Matching a lead or caller to a property and a home: what exists

Handoff for Fede's session 003 (lay-of-the-land page, local harness, prototypes). Answers bridge question q-home-matching-handoff-2026-10-29. Code citations are origin/main as fetched 2026-10-29; prod reads are propflow-prod.

2026-10-29 · written by Agent Smith from the code, git history and prod reads · nothing here is a new decision

There are three matchers, not one. (1) a building matcher that reads the company's alias store, (2) a home matcher over listing rows whose only "alias" is the public listing's title and description, and (3) the newer ADR-0147 address index, wired into phone maintenance and a few leasing paths but not email filing. The alias store is almost empty in prod, and nothing reads a property's internal description.

The current design page for this exact problem already exists and is newer than most of this: lead-to-home-matching-design-2026-10 (2026-10-28, Fede's Pick A). Read it alongside this map. ADR: 0147 one address index for every channel.

1. What exists

The alias store (building and unit "other names")

The home matcher (which listing / unit)

The ADR-0147 address index

Portfolio / company line ("umbrella")

Where names and addresses come from

2. The flow, per channel

ChannelBuilding stepHome stepNotes
Voice (leasing)Dialled line → property at call start (phone-registry.json). search_properties is NOT bound to the voice agent (src/lib/tools/leasing.ts:1252-1257, agents: []; note in leasing.config.json:2). On an umbrella line the home is picked by resolveOrgHomeForLine (tools-leasing.ts:8214) and mapped to the child building by resolveCompanyLineHome (front-door-unit-home.ts:233).schedule_tour (handleScheduleTourImpl, :7788) → resolveListingTarget (:8434) with listingCandidates for the "which one?" list (:8448). Umbrella line: pickOrgHome.A home the caller names wins on a many-homes line (#17157, #17727). Post-call guest card uses resolveAddress (postcall-prospect-capture.ts).
Voice (maintenance)Dialled line.spoken-home-resolver.ts → ADR-0147 resolveAddress.Emergencies never wait on a match.
TextDialled number → property, then resolvePropertyContext (tools-leasing.ts:1971) → resolveNamedBuilding (:3067) → searchPropertyByName (alias store). search_properties → handleSearchPropertiesImpl (:12463); a no-match writes a learned suggested name (:12606).home-match.ts over the message, then listingCandidates.Company-line texts on the address index since #21406.
Email / guest card (ILS lead)match-property.ts → matchPropertyByNamedHome (:308) → resolvePropertyByName(…, { strict: true }) (:274) with the alias store; find-property-in-text.ts:88 scans prose.home-match.ts → listingCandidates.Order: recipient address (match-property.ts:155) → named home in body (process-inbound-email.ts:1721; a tie stops routing) → subject-line scorer match-property-by-name.ts:261, which reads no aliases. Guest card: parse-lead-source.ts:657 → apply-parsed-lead-facts.ts:297 → resolveGuestCardHome (guest-card-home.ts:280) → pickOrgHome → resolveListingTarget. Not on the address index. Fede's 10-28 page: 9 of the 10 still-failing known misses are on email filing. #23382 (merged 10-29) ignores a generic tail word in the named building.
Staff toolsfind-prospect-for-staff.ts:192, handle-forward-to-property-manager.ts:877 → resolvePropertyByName (no aliases passed).—Staff-typed address matching #15978.

Voice tool route: src/app/api/voice/tools/[tool]/route.ts:199 → handleLeasingToolCall (tools-leasing.ts:891). Property names: AppFolio wins (property-directory-refresh.ts:93), refreshed on the 15-min listings tick; company listings live separately in ORG#/LISTING# rows.

3. What is populated in prod (read 2026-10-29)

[propflow-prod] ORG#org_c42d9150-…/PROPALIAS#* → 2 rows     (Western Slope; org id from config/elevenlabs-phone-numbers.json)
  "2858 C 1/2 Rd"    source=learned  status=suggested  targets=[]  seenCount=2
  "585 Redcliff Cir" source=learned  status=suggested  targets=[]  seenCount=1
[propflow-prod] ORG#org_a3376147-…/PROPALIAS#* → no row     (Situs; org id from situs-front-door's organizationId)

Not checked for this page: which current Western Slope listing rows carry "Ember" in their listing text after the renames. That is the next read for the harness.

4. Known gaps

Already written down by Gera and Fede

Observed while writing this (my reading, not Gera's)

5. In flight

Merged history (main PRs)

#13966 alias records · #14044 name kinds · #14661 strict mode · #14667/#15020 spreadsheet loader · #14685 map-lookup streets · #14193/#15497/#15499 names editor · #14676/#15343/#15370/#14677 one matcher for guest card, staff desk, search_properties · #15411/#15498/#15551 learned names · #15461 master tenants · #15346 legal entities · #15978 staff-typed addresses · #16012/#16073 "Also known as" · #16204/#16264 geo streets · #17157/#17727 named home wins on a many-homes line · #18146 nicknames · #18346 no owner-roster prefill · #18495 home by name without a number · #19739 umbrellas out of the availability heartbeat · #20363 homeKey to a neutral module · #21201/#21406/#21418 ADR-0147 address index · #23382 email lead files on the named building. Earlier: #8610, #8621, #9418, #9420, #9554, #11801.

PropFlow Docs