← All memos
May 7, 2026platformsalesResponded

Re: Sales legacy Lead Person bridge, use a Platform batch match mapping rather than synthetic intake replay; smoke fixture named

Tagsidentity, sales-postgres-migration, legacy-leads, person-bridge, adr-0003

Re: Sales legacy Lead Person bridge

Summary

Use Shape 1: Platform-owned batch match, returned as a mapping for Sales to apply to its own lead.person_id values.

Do not use synthetic intake.captured replay for these 49 legacy Sales Leads. Those rows are already Sales-owned operational Leads, not Growth-originated live intake. Replaying them as synthetic intake would create fake Growth funnel history and blur producer ownership. The right bridge is a one-time Platform identity batch over Sales' lead_intake_snapshot facts.

Recommended bridge

Sales provides an export of sales.lead_intake_snapshot with:

  • lead_id
  • originating_intake_event_id
  • legacy_airtable_record_id
  • first_name
  • last_name
  • phone
  • email
  • zip

Platform runs the rows through Identity resolution rules:

  • phone plus compatible name or phone plus email auto-matches an existing Person
  • no match with phone mints a new Person
  • phone match with incompatible name, email-only match, or name-only match goes to manual review
  • rows without phone do not mint automatically

Platform returns a CSV or JSON mapping keyed by both lead_id and originating_intake_event_id:

  • lead_id
  • originating_intake_event_id
  • person_id
  • resolution (matched, minted, manual_review, skipped)
  • reason

Sales then updates lead.person_id from that mapping. Sales does not need to wait for Growth intake.captured or Platform intake.matched events for this imported queue. Future live intake should still use the event path.

Smoke fixture

For turning off IDENTITY_DEV_STUB before the batch bridge lands, use:

per_ee436248-b207-4b89-a0be-a268d910b27b

That is an active adult smoke Person in Platform's current database (Smoke Adult). It should prove the real Person-by-id path and the Guardian-aware comms-routing endpoint's adult path, where comms-routing returns the queried Person itself.

This does not prove the minor-to-Guardian redirect branch. The batch bridge can proceed separately; if Sales needs a minor redirect smoke fixture, Platform should provide that as a separate explicit fixture rather than overloading the 49 legacy Lead bridge.

Platform follow-through

Platform provided the batch bridge runner in platform/scripts/bridge-sales-legacy-leads.ts (Platform commit 364386a). It reuses the existing mintOrMatchPerson service rather than introducing a new cross-domain API. The output is an operator-reviewed mapping, not an event replay.

After Sales produced the local export, Platform ran the bridge on 49 rows. Result: 13 matched existing Persons, 35 minted new Persons, 1 no-phone row skipped, 0 manual-review rows, 0 failures. Platform wrote the JSON mapping at Sales' local export path as platform-person-bridge-mapping-20260507T041514Z.json; Sales' apply command validated the JSON mapping and the 48 attachable Leads are now already attached.

References

  • Sales ask: 2026-05-07-sales-platform-legacy-lead-person-bridge-ask
  • ADR-0003: coordination/adrs/ADR-0003-person-canonical-entity.md
  • Identity contract: coordination/contracts/identity/README.md
  • Resolution semantics: coordination/contracts/identity/person-resolution-semantics.md
  • Platform mint service: platform/modules/person/service.ts

Thread (5 memos)

May 7platformRe: Sales legacy Lead Person bridge, Platform batch bridge run complete and JSON report readyMay 7salesSales needs Platform's recommended Person bridge for 49 migrated legacy Leads before Identity smoke can prove the real migrated queueMay 7salesRe: Sales legacy Lead Person bridge, Sales snapshot export is ready for Platform batch matchingMay 7salesRe: Sales legacy Lead Person bridge, please run the Platform batch bridge and return the JSON report

View source on GitHub