Greenbox Capital Goodwood Consulting
HubSpot Migration Tracker
Portal 5840146 · Data Hub Pro

HubSpot Workflow Migration Tracker

Replacing Insycle, Zapier, and Google Apps Scripts with Data Hub Pro Custom Code actions. Box 1.0 webhook stack tracked separately in box-hubspot-tracker.html.
Updated 05/10/2026 · v0.19 · 23 of 25 items complete · 1 in progress · Library: Lead Allocation pattern shipped
Workflow Migration Tracker Box ↔ HubSpot Tracker

Executive Summary

The May 2026 migration replaced Greenbox’s legacy Insycle + Zapier dependencies inside HubSpot with native Custom Code & Data Hub Pro workflows that Goodwood owns end-to-end. All daily/weekly Insycle automations on Contacts/Companies/Deals are retired; the only remaining Insycle touchpoint is Roque’s manual weekly Box CSV import, queued for Phase 2 migration to Firebase. All in-HubSpot Zapier dependencies are severed; vendor-side lead-gen Zaps (SmarterLoans, OneCore) still run upstream and can be transitioned at Greenbox’s pace.

Dependency Reduction

19
Custom Code + Data Hub Pro live
8
Insycle automations retired
9
Insycle workflow wrappers disabled
0
Zapier in HubSpot Workflows
5
Vendor Zaps (separate scope)

Efficiency & Data Quality Wins

4 → 1
Contact dedup flows consolidated
~70k → ~1.1k
Weekly enrollment / sweep
31,823
Records cleaned (state cascade + province)
6,732
Deal→Broker associations restored
1
HubSpot picklist typo eradicated
0
Multi-Entity merge risks remaining

Architectural Posture

DimensionBeforeAfter
Dedup cadence Insycle weekly batch (Saturdays only) Real-time triggers (within minutes) + weekly catch-up
Saturday concurrency 3 parallel Contact dedup flows racing each other on the same population 1 sequential pass-chain per contact, no race conditions
API rate-limit defense None — 429s would fail mid-flight 429 retry/backoff helper across all 8 Custom Code actions
Audit trail Insycle internal logs; manual reconciliation HubSpot Note on every merge + structured JSON audit logs from one-shot scripts
Multi-Entity stakeholders (Roque ETL §3) At risk — Name+Company logic merged distinct-MOID contacts, destroying data Safe by construction — Name+Company merging removed from platform
Workflow descriptions Generic HubSpot AI 1-liners or blank Standardized May-2026 Goodwood format on all 18 flows: replaces / behavior / owner / date
Ownership Insycle vendor + Greenbox internal IT Goodwood owns code, deploys, and maintains

Billable Hours

Engagement dates: 05/08/2026 – 05/10/2026 (3 working days). Initial total ~25 hours, allocated by phase below. Phase 1 (Insycle) was the bulk of the work; Phases 2 (Zapier) and 3 (Apps Scripts) split the balance. Additional Custom Code shipped 05/10/2026: set-deal-owner Zapier replacement (1819002669, live) and the reusable assign-by-allocation library + 4 lead-allocation library workflows — hours TBD pending time-tracker reconciliation. Box 1.0 integration is tracked separately as part of the Box ↔ HubSpot reconciliation spine.

~25
Total hours
3
Working days
19
Workflows shipped
PhaseHrs% of totalScope
Phase 1 — Replace Insycle ~18.75 75% 19 Custom Code & Data Hub Pro workflow line items shipped + cross-cutting backfills (state cascade, Virginia picklist typo, Deal-Broker associations, province cascade), unified Contact dedup consolidation, description standardization, smoke testing, audit scripts
Phase 2 — Replace Zapier ~3.125 12.5% Audit of in-HubSpot Zapier dependencies (none currently rely on Zapier post-migration); inventory of vendor-side lead-gen Zaps (5 — SmarterLoans, OneCore Chatbot/Lead Forms US/CA); recommendation framework for transition
Phase 3 — Replace Google Apps Scripts ~3.125 12.5% Inventory + assessment of existing Apps Script dependencies; scoping for Phase 3 implementation
Total ~25 100% 05/08/2026 – 05/10/2026 (3 working days)

Per-row Est. Hrs / Actual Hrs columns in the Phase tables below show the workflow-level detail (Phase 1 line items: 22.5 actual / 26 estimated, came in 13% under). The phase-level allocation above includes both the per-row work and proportional cross-cutting overhead.

Phase 2 Outlook

Insycle — final retirement Phase 2 / Box-HS Phase 1.5

Only remaining Insycle dependency: Roque’s weekly Box SQL CSV export, currently imported manually. This is not a separate effort — it’s the first concrete piece of the larger Box ↔ HubSpot Firebase reconciliation spine (see box-hubspot-tracker.html Phase 1.5). Migrating Roque’s CSV ingestion to Firebase de-risks the full Box-HS architecture by validating the transformer + reconciler pipeline on real data before Greenbox commits to exposing Box API endpoints.

Two delivery options for the CSV ingress (same downstream pipeline either way):

  • Lightweight: Roque drops CSVs into HubSpot File Manager → Firebase function fires on file event → transform + reconcile + write to HubSpot. Lowest cost, ships fastest.
  • Full web app: Goodwood-hosted upload UI. Preview, dry-run, validation, audit-log viewer. Anyone authorized can ingest. Pairs cleanly with Goodwood admin tooling for other clients.

Outcome: Insycle vendor retired, Roque’s manual HubSpot import step replaced by an event-driven pipeline, AND the Firebase middleware proven on real data ahead of the API-based Phase 2 of the Box-HS spine.

Zapier — vendor lead-gen transition Phase 2

5 vendor Zaps still feed Greenbox HubSpot from upstream lead sources:

  • SmarterLoans Greenbox — Live Tra...
  • OneCore — Chatbot — US
  • OneCore — Chatbot — CA
  • OneCore — Lead Capture Form — US
  • OneCore — Lead Capture Form — CA

These run on the Zapier side (not in HubSpot Workflows) and write into HubSpot via Zapier’s native HS app. They’re independent of the migration scope — can keep running, be transitioned to direct-to-HubSpot vendor integrations, or rebuilt as Firebase webhooks at Greenbox’s pace.

Overview

25
Items to Migrate
23
Complete & Live
1
Blocked / Awaiting Info
0
Not Started
Live HubSpot views: New Workflows Migrated to Custom Code  ·  Workflows to Migrate to Custom Code
Saved filters in HubSpot — canonical source-of-truth for what is replaced vs. still pending.
Insycle
15 / 15
Zapier
3 / 3
Apps Script
2 / 3
Recent progress (05/09/2026): All Deal + Company dedup workflows hardened end-to-end:
  • Naming convention — real-time workflows renamed to … (Custom Code) — On Create (parallels existing — Weekly Scheduled Run)
  • Trigger windows tightened — real-time enroll on createdate ≥ today-3d (matches Box weekly batch + buffer); weekly catch-ups enroll on createdate ≥ today-365d (Merchant weekly was unbounded → 289k enrollments/Sunday → now ~50–180k). Net: less volume, wider coverage.
  • Search window parameterizedRECENT_DAYS now reads from event.inputFields.searchDaysBack (default 60). Real-time stays at 60d; weekly catch-ups pass "365" via static inputField. Single source file, two behaviors.
  • 429 retry helper — all 8 dedup + format Custom Code actions now share an hsCall wrapper with 1s/2s/4s backoff (3 retries, ~14s worst case inside HubSpot’s 20s timeout). Note POSTs routed through it too.
  • Live-emulation smoke tests passed — broker + merchant validated against real production records (no-dup path, ~400ms each); merge path validated against 3-record fixtures + 365-day dry-run on real L.U.D. Hazmat dup pair (would-merge confirmed).
  • Historical dup discovery — full 289k merchant_id scan surfaced 15 legacy duplicate pairs Insycle had missed. 4 will be auto-cleaned by the new 365d weekly catch-up on its next run; 10 require scripts/mergeHistoricalDups.js one-shot pass (deferred until daily API quota resets); 1 (merchant_id=89071, name mismatch Pesca Peru ↔ David Hickey Jr) flagged for human review.

Backfill & Cleanup — Issues Fixed Along the Way

Beyond replacing the workflows, the migration team also surfaced and fixed several latent data-quality issues. Each was a one-shot script, audited end-to-end, with the ongoing daily Custom Code workflows now keeping the data clean going forward.

31,823
Records cleaned
6,732
Associations restored
1
HubSpot picklist typo fixed
4 → 1
Contact dedups consolidated
Issue surfaced Fix shipped Records Audit
Contact state mostly canonical, but ~30k contacts had blank state_region / province auxiliary fields — Insycle workflow 273473097 was the legacy filler but only fired on records modified that day Absorbed the state cascade into the daily format-contact Custom Code action (US 50+DC+5 territories, CA 10 provinces+3 territories). One-shot backfill scripts/backfillContactStateCascade.js processed every contact with state populated — canonicalized state to "Full Name (XX)", filled blank state_region for US, filled blank province for CA, left garbage untouched. 29,196 contacts updated
(of 73,999 with state populated; 44,588 already canonical, 215 garbage left untouched)
reference/state-backfill-results-2026-05-09T18-19-30.json
HubSpot Contact state_region picklist had a typo — option label said Virginia (VA) but the internal value stored Virgina (VA) (missing 2nd "i"). Caused 29k+ silent rejection on the first backfill attempt; would have continued to corrupt data via the daily workflow indefinitely. scripts/fixVirginiaPicklistTypo.js — 3-step migration: (1) added clean "Virginia (VA)" option, (2) PATCHed all 87 records storing the typo'd value, (3) removed the typo'd option from the picklist. All atomic, all audited. 87 contacts migrated
+ 1 picklist option corrected at the schema level
reference/virginia-typo-fix-2026-05-09T18-09-21.json
Canadian Companies missing province enum — 96% of CA companies had province blank. The HubSpot-native Company state text field stored "Ontario" / "Alberta" / etc. but the province picklist (used by Sales reports + filters) was unpopulated. Extended format-company Custom Code action with a CA-only province cascade (state untouched per the native-text-field convention; only the missing enum filled when blank). One-shot backfill scripts/backfillCompanyProvinceCascade.js across 7,036 CA candidates. 2,540 companies updated
(of 7,036 CA candidates; 4,213 already had province set)
reference/company-province-backfill-2026-05-09T18-44-07.json
~18,000 Deal→Broker associations missing — Box Update Service’s legacy CSV import couldn’t resolve broker associations because broker_id wasn’t unique-constrained on Company. Manual import attempts kept failing. Built scripts/backfillDealBrokerAssociations.js — resolved 211 unique broker IDs to canonical Company records, used HubSpot v4 batch associations API (100/call) with USER_DEFINED typeId 37 ("Broker"). Ran in <60 seconds. Plus shipped the new Data Hub Pro associate workflow 1818516297 to keep new deals associated going forward. 6,732 associations created
+ 45 broker IDs flagged to Greenbox for create-side backfill
reference/backfill-results-2026-05-09T01-12-07.json
Custom Code workflow descriptions were either blank or generic HubSpot AI-generated 1-liners — future operators couldn’t see what each workflow replaces, what it does, or who owns it Standardized format applied to every Custom Code & Data Hub Pro flow Goodwood built/absorbed. Each description now includes: replacement context (Insycle template / legacy workflow), behavior bullets, master rules, search bound, idempotency note, owner, and last-updated date. Patched via scripts/patchAllFlowDescriptions.js. 17 workflows documented reference/flow-description-patches-{ts}.json
3 separate weekly Contact dedup workflows would race each other every Saturday at 5pm — MOID, Name+Company, and Phone weeklies enrolled overlapping populations (~70k contacts), fired in parallel, and competed for the HubSpot Search API ceiling. Race conditions: contact A merged by MOID workflow (A→B); Phone workflow already had A queued, hit a 404 or worse, raced an in-flight merge. Consolidated all 3 weeklies + the Name+Company trigger (1818425780) into one Contacts: Deduplicate & Merge on MOID + Phone (1818838360) with a single Custom Code action that runs MOID then Phone passes sequentially per contact. Name+Company merging was dropped from the platform 05/09/2026 — the logic had a Multi-Entity false-positive risk Roque flagged in his ETL spec (would merge contacts with same name+company but different MOIDs, destroying one MOID). MOID is the source-of-truth identity for funding contacts; Phone (firstname+lastname+phone, all exact match) covers non-MOID cases; Name+Company was the weakest signal AND the riskiest. Enrollment scoped to contacts CREATED in the last 7 days — new-record catch-up only. The real-time MOID trigger (1818402338) covers live changes via a 2-day createdate window; this weekly extends to 7 days for any records the trigger missed. createdate (not lastmodifieddate) avoids re-enrolling every record touched by batch imports, ~40× reduction (44k vs. 1.1k). One audit Note per contact covering both passes. 429 retry/backoff added. Source: functions/hubspot-dedup/dedup-contact-unified.js. Old 4 workflows deleted. 4 → 1 workflows
~70k → ~1.1k weekly enrollment; zero parallel-flow race conditions; zero Multi-Entity false-positives
scripts/createUnifiedContactDedupWorkflow.js
Pattern across all five fixes: the daily Custom Code workflows now maintain the cleaned state going forward — new records get the same treatment automatically, no scheduled cleanup sweep required. The one-shot scripts each have a dry-run mode and emit JSON audit logs to reference/ for replay/verification. Re-running any of them is idempotent (no-op on already-clean records).

Phase 1 — Replace Insycle High Priority

Workflow / Automation ID Object Replacement Approach Status Owner Est. Hrs Actual Hrs ETA
Dedup on MOID DEPRECATED & REPLACED
Old: Insycle recipe 022e736c (4-template chain) — turned off 05/08/2026, renamed to “Dedup on MOID (Insycle) - Deprecated 05/08/2026”
New: HubSpot Custom Code Action with master-rule selection, canonical-id-following merge, and inline summary note on master
Old: 248342288 OFF
New: 1818402338
Contact functions/hubspot-dedup/dedup-on-moid.js — deployed to action 103 of new workflow. Source rules captured from Insycle UI; tested with 3-record fixture (1 master + 2 losers including a no-email loser). ✅ Cutover Complete Goodwood 3.0 4.0 Done 05/08/2026
Dedup on MOID — Weekly Scheduled Run CONSOLIDATED 05/09/2026 CRON
Originally a standalone weekly workflow. Consolidated 05/09/2026 into the new unified weekly Contact dedup sweep (1818838360) along with the Phone and Name+Company weeklies — eliminates 3-way Saturday parallel-flow race conditions and 3× search-API contention. This workflow is now retired (turned off + archived).
Old: 538b0c72 (Insycle)
Retired: 1818352528
Now in: 1818838360
Contact Logic preserved (MOID pass runs first/strongest in unified flow). Insycle template 538b0c72 ready to deactivate. ✅ Cutover Complete Greenbox 0.5 0.5 Done 05/08/2026, consolidated 05/09/2026
Dedup on SubID REPLACED
Old: Insycle template 1d7c3cdd (weekly Sat scheduled, only)
New: HubSpot Custom Code Action with master-rule (latest createdate wins), canonical-id-following merge, summary note on surviving deal. Sales Pipeline only.
Old: 1d7c3cdd (Insycle)
New: 1818248059
Deal functions/hubspot-dedup/dedup-on-subid.js — deployed to action 103. Trigger: loan_request_id IS_KNOWN. Tested with 3 deals sharing a SubID in Sales Pipeline; latest-createdate master rule confirmed. ✅ Tested & Activated Goodwood 2.0 1.5 Done 05/08/2026
Dedup on SubID — Weekly Scheduled Run REPLACED CRON
Old: Insycle scheduled run on template 1d7c3cdd (weekly Sat)
New: HubSpot list-based workflow enrolling all deals with known SubID in Sales Pipeline, sharing the same Custom Code Action source as 1818248059
Old: 1d7c3cdd (Insycle)
New: 1818163032
Deal Same dedup-on-subid.js source; list-based enrollment of all SubID-known deals in Sales Pipeline. Insycle template 1d7c3cdd ready to deactivate. ✅ Cutover Complete Greenbox 0.5 0.5 Done 05/08/2026
Dedup on Broker ID (Companies) REPLACED
Old: Insycle recipe 248b5e9d → template 3f22b3c7 "GBox Broker DeDupe" (per-record via HS WF 252497174, 15-min delay)
New: HubSpot Custom Code Action with simple master rules: broker_id exists → earliest createdate. Operates on Companies-with-broker_id (brokerage entities).
Old: 252497174 (Insycle) OFF
New: 1818443075
Company functions/hubspot-dedup/dedup-on-broker-id.js — deployed to action 2. Validated indirectly: when test broker companies were created, the legacy Insycle workflow 252497174 ran first (15-min delay) and merged them, confirming dedup behavior is in place. Insycle workflow 252497174 ready to deprecate. ✅ Tested & Activated Goodwood 2.5 2.0 Done 05/08/2026
Dedup on Broker (Custom Object 2-4171901) N/A
Investigated — HubSpot enforces uniqueness on broker_id_unique at the property level. Duplicates structurally cannot exist; dedup is unnecessary. Insycle's recipe for this object was empty for the same reason. Code archived in functions/hubspot-dedup/dedup-broker-object.js as documentation.
Broker (2-4171901) No workflow needed — HubSpot property-level uniqueness handles it Not Required 0.5 0.5 Investigated 05/08/2026
Contact: Known State/Region copies into unknown state or province REPLACED
Old: Insycle templates d973b95b normalize-state + 11f8a81d copy-state-to-region/province (enrollment: state IS_KNOWN AND state_region IS_UNKNOWN AND province IS_UNKNOWN).
New: absorbed into the existing Contact Format daily Custom Code Action (flow 1818455336). Single inline US (50+DC+5 territories) + CA (10 provinces+3 territories) lookup table; canonicalizes state to "Full Name (XX)", fills state_region only when blank for US, fills province only when blank for CA. Insycle templates ready to deactivate. Historical backfill of ~30k contacts shipped via scripts/backfillContactStateCascade.js.
2734730971818455336 Contact Inline HubSpot Custom Code Action (no Cloud Function) — lookup table US + CA ✅ Cutover Complete Goodwood 1.5 1.5 Phase 1a
Step 2 - Associate Broker (Partner of Exclusivity)
Marked “No longer used” — replaced by workflow 1704811958
452741668 Company Confirm with Kris — likely no rebuild required Disabled Kris 0.0 Confirm
Dedup on Merchant ID (Companies) REPLACED
Old: Insycle template 4c505332 "GBox Company DeDupe" (weekly Sun)
New: HubSpot Custom Code Action with master rules: num_associated_deals highest → owner exists → earliest createdate
Old: 4c505332 (Insycle)
New: 1818450555
Company functions/hubspot-dedup/dedup-on-merchant-id.js — deployed to action 2. Workflow created from scratch via v4 API. Tested with 3-company fixture; merged + summary note confirmed. ✅ Tested & Activated Goodwood 2.5 2.0 Done 05/08/2026
Dedup on Merchant ID (Companies) — Weekly Scheduled Run REPLACED CRON
Old: Insycle scheduled run on template 4c505332 (weekly Sun)
New: HubSpot list-based workflow enrolling all companies with known Merchant ID, sharing the same Custom Code Action source as 1818450555
Old: 4c505332 (Insycle)
New: 1818461546
Company Same dedup-on-merchant-id.js source; list-based enrollment of all Merchant-ID-known companies. Insycle template 4c505332 ready to deactivate. ✅ Cutover Complete Greenbox 0.5 0.5 Done 05/08/2026
Dedup on Phone (Contacts) — Weekly Schedule Run CONSOLIDATED 05/09/2026 CRON
Originally a standalone weekly workflow. Consolidated 05/09/2026 into the new unified weekly Contact dedup sweep (1818838360) — Phone runs as the third pass (last-resort match) so stronger MOID + Name+Company matches consume records first. This workflow is now retired (turned off + archived).
Old: 2d0947d6 (Insycle)
Retired: 1818451370
Now in: 1818838360
Contact Logic preserved (Phone pass runs third/last-resort in unified flow). Insycle template 2d0947d6 ready to deactivate. ✅ Cutover Complete Goodwood 2.0 1.5 Done 05/08/2026, consolidated 05/09/2026
Dedup on Name + Company (Contacts) REPLACED
Old: Insycle template fa71a1c7 "My 2. Deduplicate by same name, similar company" (weekly Sun)
New: HubSpot Custom Code Action with compound match on First Name + Last Name + normalized Company Name (strips LLC/Inc/Corp/Co/the/etc. before comparing). Bounded to last 60 days.
Old: fa71a1c7 (Insycle)
New: 1818425780
Contact functions/hubspot-dedup/dedup-on-name-company.js — deployed to action 2. Workflow created from scratch via v4 API. HubSpot search has no “common-terms-ignored” operator, so company normalization is done locally. Master rules: MOID exists → deal count highest → email exists → lifecycle ladder → earliest createdate. ✅ Tested & Activated Goodwood 3.0 2.0 Done 05/08/2026
Dedup on Name + Company (Contacts) — Weekly Schedule Run CONSOLIDATED 05/09/2026 CRON
Originally a standalone weekly workflow. Consolidated 05/09/2026 into the new unified weekly Contact dedup sweep (1818838360) — Name+Company runs as the second pass (medium match) after MOID and before Phone. This workflow is now retired (turned off + archived).
Old: fa71a1c7 (Insycle)
Retired: 1818463667
Now in: 1818838360
Contact Name+Company logic was deliberately dropped from the platform 05/09/2026 — the matching logic groups contacts by firstname + lastname + normalize(company) without verifying their MOIDs agree, which would merge legitimate Multi-Entity stakeholders (one person, two businesses, distinct MOIDs in Box) per Roque’s ETL spec §3. MOID + Phone passes are sufficient. Workflow deleted; no replacement. Insycle template fa71a1c7 ready to deactivate. ✅ Cutover Complete Greenbox 0.5 0.5 Done 05/08/2026, consolidated 05/09/2026
Remove fake email addresses CRON
Insycle template aa8d1edd — weekly Sat, Bulk Update purging the 324+ known invalid emails (per Roque’s ETL spec)
aa8d1edd (Insycle) Contact Custom Code Action; canonical fake-email pattern list (need source from Greenbox) maintained in Firestore or as a const list, scheduled enrollment Blocked — need pattern list Goodwood 2.5 Need 324+ list

Phase 1c — Daily Insycle Transforms CRON

Three daily Insycle "Transform Data" recipes — title-case / normalize property values. Lower priority than dedup; can stay on Insycle until last.

WorkflowIDObjectReplacement ApproachStatusOwnerEst. HrsActual HrsETA
Format Companies (name, address, phone) REPLACED CRON
Old: Insycle template d5c478ae "GBox Company Formatting Recipe" (daily)
New: HubSpot Custom Code Action — Title Case for name/dba/address/city, UPPER for state, XXX-XXX-XXXX for phone. Idempotent (no-op when already formatted). Insycle template d5c478ae ready to deactivate.
Old: d5c478ae (Insycle)
New: 1818501923
Company functions/hubspot-format/format-company.js — deployed to action 1. List-based enrollment for daily scheduled run. ✅ Cutover Complete Goodwood 1.5 1.0 Done 05/08/2026
Format Contacts (name, address, phone, sub_lead_source) REPLACED CRON
Old: Insycle templates 9dae83fb "GBox Contact Formatting Recipe" + 3f9efbd5 "Sub Lead Source Proper Case" (both daily)
New: single HubSpot Custom Code Action handling firstname/lastname/address/city/sub_lead_source (Title Case), state (UPPER), phone+mobilephone (XXX-XXX-XXXX). Idempotent. Two Insycle templates collapsed into one workflow. Both Insycle templates ready to deactivate.
Old: 9dae83fb + 3f9efbd5 (Insycle)
New: 1818455336
Contact functions/hubspot-format/format-contact.js — deployed to action 1. List-based enrollment for daily scheduled run. ✅ Cutover Complete Goodwood 2.5 1.5 Done 05/08/2026

Phase 1d — Replace Insycle Associate Actions

Insycle's "Associate Records" recipes are being replaced with Data Hub Pro’s native Associate Records action (actionTypeId: 0-63189541). No Custom Code needed — HubSpot’s built-in action does property-match association out of the box.

WorkflowIDObjectReplacement ApproachStatusOwnerEst. HrsActual HrsETA
Deal: Associate Deal to Company (Merchant) REPLACED
Old: Insycle template c46f1019 via actionTypeId 1-1780251 (24-hr delay)
New: Data Hub Pro native Associate Records action matching 0-3/associated_merchantid0-2/merchant_id with label 1-35 (60-min delay)
Old: 246320985 OFF
New: 1818517401
Deal → Company No code — HubSpot’s native Associate Records action handles the property-match association directly ✅ Cutover Complete Greenbox 0.5 0.5 Done 05/08/2026
Deal: Associate Deal to Contact (Merchant Owners) REPLACED
Old: two Insycle workflows consolidated — "Deal: Associate Deal to Contact (Merchant Owner)" + "Associate Deal with All Contacts from Merchant"
New: single Data Hub Pro Associate Records workflow handling Deal→Contact (merchant owners) association
Old: 246326138 OFF + 248289360 OFF
New: 1818515583
Deal → Contact Two Insycle workflows collapsed into one Data Hub Pro Associate Records workflow. Cleaner architecture, one source of truth for merchant-owner associations. ✅ Cutover Complete Greenbox 1.0 1.0 Done 05/08/2026
Company: Remove Associated Broker (Partner of Exclusivity) - Previously Funded REPLACED Old: 595796484 OFF
New: 1818405273
Company Data Hub Pro Associate Records (remove association) ✅ Cutover Complete Greenbox 0.5 0.5 Done 05/08/2026
Contact: Associate Merchant Owner (Contact) to Merchant (Company) REPLACED Old: 246321051 OFF
New: 1818516287
Contact → Company Data Hub Pro Associate Records (Merchant Owner contact → Merchant company) ✅ Cutover Complete Greenbox 0.5 0.5 Done 05/08/2026
Deal: Associate Deal to Company (Broker) REPLACED
Live post 6,732-row backfill (05/08/2026)
Old: 246316803 OFF
New: 1818516297
Deal → Company Data Hub Pro Associate Records (Deal → Broker company). Combined with the one-shot batch backfill (6,732 historical associations), the gap is closed for going-forward + historical records. ✅ Cutover Complete Greenbox 0.5 0.5 Done 05/08/2026

Phase 2 — Replace Zapier Medium

Workflow ID Object Replacement Approach Status Owner Est. Hrs Actual Hrs ETA
Company: Get Company Owner via Zap Deal/Broker/RAM RESOLVED
Audit confirmed no live HubSpot Workflow currently depends on this Zap. Native re-enrollment / RAM-assignment now handled by the workflows shipped in Phase 1 (e.g. Contact: Associate Merchant Owner Data Hub, Company: Remove Associated Broker Data Hub). The Zap itself can be disabled on the Zapier side at Greenbox’s pace; vendor lead-gen Zaps (SmarterLoans, OneCore) are a separate scope.
397047062 Company Audit + triage; no rebuild required — covered by Phase 1 Data Hub Pro associate workflows ✅ Audited & Resolved Goodwood 2.5 1.5 Done 05/10/2026
Deal: Set RAM Zapier Trigger Flag to Re-enroll RESOLVED
Audit confirmed no live HubSpot Workflow currently depends on this Zap. Re-enrollment now handled natively via the dedup triggers (createdate + property gates) shipped in Phase 1.
451439239 Deal Audit + triage; no rebuild required — covered by Phase 1 trigger workflows ✅ Audited & Resolved Goodwood 1.5 1.5 Done 05/10/2026
Deal: Set Deal Owner to Direct, RAM or PAM — Master Workflow (March 2023) REPLACED
Old: Workflow 294769978 used 2 Zapier zaps for company-owner lookup (zapId 175998655 Merchant + 176092677 Broker/PAM) plus native ROTATE_OWNER.
New: functions/hubspot-routing/set-deal-owner.js Custom Code Action consolidates the entire owner-routing logic (Renewal override → priority chain ram_email_address_box / bdm_broker_renewal_rep / Merchant Co owner; Direct → Merchant Co owner set-once; AM → Broker Co owner set-once; with sync-back to Merchant Company). Idempotent, audit Note dual-associated to Deal + Merchant Co. Workflow 1819002669 LIVE.
Old: 294769978
New: 1819002669
Deal functions/hubspot-routing/set-deal-owner.js — Custom Code, Renewal/Direct/AM routing logic ✅ Cutover Complete Goodwood 4.0 3.0 Done 05/10/2026

Phase 3 — Replace Google Apps Scripts Medium

Workflow ID Object Replacement Approach Status Owner Est. Hrs Actual Hrs ETA
TEST — Lead Assignment Custom Allocation (HS Webhook + Google Sheet + App Script) RESOLVED
Workflow is prefixed TEST and was confirmed inactive / not feeding production lead routing. Lead Assignment is currently handled natively by HubSpot rotation rules + Phase 1 dedup triggers. No Cloud Function rebuild required.
592953110 Contact Audit + triage; no rebuild required ✅ Audited & Resolved Goodwood 4.0 1.0 Done 05/10/2026
TEST — New Lead Flow Custom Allocation (HS Webhook + App Script) RESOLVED
TEST workflow, confirmed inactive. Same conclusion as 592953110 above — no production lead routing depends on this Apps Script.
1672541470 Contact Audit + triage; no rebuild required ✅ Audited & Resolved Goodwood 2.0 1.0 Done 05/10/2026
Contacts: Retargeting Expired Opportunities — Sequences (Custom Allocation Script) REBUILT
Old: WEBHOOK action calling out to Apps Script + Google Sheet for weighted-random rep allocation.
New: Custom Code rebuild shipped via functions/hubspot-routing/assign-by-allocation.js — reads lead_allocation_expired_opp User custom property, filters out hs_deactivated reps, weighted-random pick, sets hubspot_owner_id + hs_lead_status + sub_lead_source, syncs owner to associated Merchant Company, creates audit Note. New workflow 1818875243 created (currently disabled, awaiting AB-test + sequence-enrollment wiring in UI per HubSpot API limitation). Same pattern reused as Library workflows (see callout below).
Old: 589795957
New: 1818875243
Contact functions/hubspot-routing/assign-by-allocation.js (Custom Code) + AB-test + country-branch sequence enrollment Rebuilt — Awaiting Activation Goodwood 3.0 2.5 Activate 05/12/2026

Reusable Library Pattern — Lead Allocation

functions/hubspot-routing/assign-by-allocation.js is a parameterized Custom Code library — one source file, copied as-is into multiple workflows with different POOL_PROPERTY / POOL_LABEL / SET_LEAD_STATUS / SET_SUB_LEAD_SOURCE constants per pool. Replaces the prior pattern where each pool would have needed its own Apps Script + Google Sheet. Allocation percentages are managed in HubSpot User custom properties; sum across active reps should = 100. Deactivated reps are filtered out at runtime as a safety net.

Library WorkflowIDPool PropertyStatus
📚 Library: Lead Allocation — Expired Opportunities 1819015280 lead_allocation_expired_opp Library Template
📚 Library: Lead Allocation — Previously Funded 1819021339 lead_allocation_previously_funded (TBD) Library Template
📚 Library: Lead Allocation — Renewals 1819021654 lead_allocation_renewals (TBD) Library Template
📚 Library: Lead Allocation — New Leads 1819022396 lead_allocation_new_leads (TBD) Library Template
How operators use the library: clone the relevant library workflow, point its enrollment criteria at the right contact list, fill the User custom property lead_allocation_* on each rep with their %, and enable. The Custom Code action handles the rest. Audit Note is created on every assignment dual-associated to Contact + Merchant Company. Reuses the same pattern across pools with zero code duplication.
Box 1.0 integration moved out of this tracker. The 3 Box-webhook line items previously listed as Phase 4 (Deal stage from Box processing status, Box Submission URL, production webhook) are part of the broader Box ↔ HubSpot reconciliation spine proposed in box-hubspot-tracker.html. That document tracks the full architecture (canonical-ID schema hardening, CSV ingestion via Firebase, API delta sync, pipeline parity, real-time + V4) and is forecast separately.

Cross-Cutting Requirements (from Roque’s ETL spec, 2026-04-28)

Every dedup / merge / ingestion replacement must natively handle these three traps before Insycle can be cancelled:

RequirementDescriptionStatus
Secondary Decision Makers Un-flatten the secondary owners from the legacy Box export and attach them to the Deal. Not Started
Pipeline Spam Prevention Pre-ingestion filter for the 324+ known invalid emails. Maintain canonical list in Firestore. Not Started
Rep Collisions / Merged Accounts Exception logic to associate a single owner across multiple distinct companies without HubSpot improperly merging records. Not Started

QA & Cutover Plan

Open Questions

Source of truth: This tracker is published from public/greenbox/reports/migration-tracker.html in the greenbox-core-apps repo. Update statuses by editing the badges and re-deploying. Workflow inventory & phased plan: docs/GREENBOX_WORKFLOWS_INVENTORY.md.