One Renter, One Record

No matter how many ways a renter reaches us, or how many homes they ask about, they show up once on the list, and what we show matches what the client sees in their own system.

Proposed 2026-09-20 · plain-language companion to the engineering design at /a/leasing-engine-designs#zero-duplicates-2026-09-20

Contents

  1. The picture
  2. Three rules that keep it simple
  3. Two ways a client can run
  4. What it looks like: a renter who found us on Zillow
  5. Progress tracker

The picture

Where renters come from
The client's system (AppFolio, Yardi)
A phone call or text
An email to the leasing inbox
The website contact form
Listing sites (Zillow, Apartments.com…)
Other sites (Facebook Marketplace…)
→
Clara's desk (same for every client)
1. One front doorEvery message, call or form comes in the same way: who, which home, how they found us, when.
2. “Do we already know this person?”Clara checks the phone number, then the email, then name and home. Same person, same file. Roommates and co-signers are grouped as one household.
3. One line on the listOne person, all their homes and showings under it. Their stage (inquiry, application, lease signed) and where they came from are read from the client's system, not made up by us.
→
Where the record lives (client's choice)
AppFoliothe client's system is the record
Yardinext
PropFlowwe are the record (Camellia today), same plug as the others
Later: RentCafe, Knock, Salesforce…same plug, different system
Write-back

If the client's system owns the record and something happens that it can't see (a call, a direct email), Clara adds it there. Already have this person? Add a note to their card. Never seen them? Create the card. Nothing lives only on our side. When PropFlow is the record, the same step writes to our own list. Same rule, same plug. For AppFolio and Yardi, we keep our copy of the card (the mirror): we pull it every sync and never edit that copy ourselves — changes go through write-back and come back on the next sync. For PropFlow CRM, there's no copy — the connector reads and writes our own table, so the record and the store are the same thing.

Three rules that keep it simple

Never two lines for one person

Two showings, three homes, a second email address: still one person, still one line. Anything else is a bug we fix in Clara, not with a “merge?” button.

The client's system is the truth

Stage and lead source come from their system. “AppFolio” is never a source; the source is Zillow, the website, a phone call. We don't invent a lead from a listing-site email when their system already has the card.

One plug per system

Connecting a new system means one plug that does four things: read their records, create a card, add a note, translate their words for stage and source into ours. Clara doesn't change.

Two ways a client can run

“Keep everything in my system”

AppFolio and Yardi clients, like Western Slope
  • Clara reads their leads from their system.
  • Optional add-on, per source: we also listen to calls, direct emails, Facebook Marketplace, affordable-housing sites, and write each one back into their system.
  • Result: more of their leads end up in the one place they already work.

“PropFlow is my CRM”

Clients without a leasing CRM, like Camellia
  • We are the record. Every signal, including listing-site emails, is kept on our side.
  • Same write-back step, it just lands in our own list.
  • Same Clara, same list, same rules.

What it looks like: a renter who found us on Zillow

Before

Ethan S. · 566 Placer StAppFolio
Ethan S. · 566 Placer StZillow email

Zillow's relay email reached our inbox and AppFolio created a card 30 minutes later. We made two people out of one.

After

Ethan S. · 566 Placer StZillow · Inquiry

One line. Source says Zillow, stage says whatever AppFolio says. The relay email attached to his card instead of becoming a second person.

Progress tracker

Updated 2026-09-20, 10:20 AM MT

Built = the phase's code is all merged. Proven = the phase's own check passes against real production data with zero defects. Live = a customer's record-owner setting is actually set and its page has been checked. This tracker updates as work lands — it does not change how the picture above reads.

89%
Built
8 of 9 phases (0–8) fully merged
78%
Proven on real data
7 of 9 phases pass their check on real production cards, zero defects
50%
Live for customers
Camellia is on it today; Western Slope is the pending flip (Situs Group has no production org yet, so it isn’t counted)
PhaseWhat it meansStatusProofLast change
0. CorpusPull every real guest card with everything the new model needs (property, status, inquiries, linked application, linked tenant).Done2,858 real cards pulled (Western Slope 1,116 · Situs 1,572 · Camellia 170); all 90 Western Slope multi-home cards now carry their full inquiry list2026-09-20
1. Copy (mirror)Every pulled card becomes exactly one record in our own copy; pulling it again changes nothing.Proven3,625 person-links checked across repeat pulls, 0 changed, 0 lost; production copy is live and fresh (Western Slope 1,040 cards, Camellia 60)2026-09-20
2. StatusEvery AppFolio status word maps through one explicit table, never guessed.Proven0 unmapped statuses, including the “Cold” status that was missing one lane2026-09-20
3. PersonOne human gets one person id, forever; a re-pull never loses it.Proven22 checks pass, 0 fail, on the real-data corpus across all three clients2026-09-20
4. HouseholdCo-applicants get grouped from our copy, matching how the old system grouped them.ProvenAll household/deal checks pass for JP&Co, Situs and Western Slope (2 Western Slope checks can’t run — every group in this window has just one member, a data gap, not a bug)2026-09-20
5. The page (one row per person)The prospects list is built straight from our copy, one row per person, their homes listed underneath.In reviewCard-based view: 1,040 AppFolio cards fold to 973 people, 104 groups (the old page showed 157 rows with 39 duplicate groups); grouping same-person cards into one row is the last piece before the flip2026-09-20
6. PropFlow CRM (Camellia)Camellia, which has no leasing PMS, runs as its own record owner through the same engine and the same checks.In reviewAdapter and setting merged and live; Camellia’s copy is syncing; a full before/after proof that Camellia’s page is unchanged is still queued2026-09-20
7. Write-back replayEvery historical write-back replays under the new model with the same result as before.ProvenA year of Western Slope write-backs replayed, 0 grouping changes; Situs and JP&Co had no write-back history yet to replay2026-09-20
8. Concurrency (real database)The same checks run against a real, shared database, not just an in-memory test.Proven1,279 rows written through the real production path and cleaned up (0 left); repeating a pull of the same card made zero writes2026-09-20
Go-live: Western Slope flip + live checkTurn Western Slope’s prospects page onto the new, one-row-per-person list, and confirm it live.QueuedWaiting on phase 5’s grouping piece; Fede’s call once that and the checker below are clean2026-09-20
Go-live: one-time cleanup of invented rowsAfter the flip, remove or fold the rows the old model invented, with a backup first.QueuedDry run at Western Slope: delete 117 invented/copied rows, fold 18, keep 15 real PropFlow-only leads, leave 23 for a human call; real run waits for the flip, under Fede’s go2026-09-20
Go-live: false green-check repairFix the proof checker itself where it was reporting a pass that wasn’t real.DoneA pass that could never fail (the database-lane seeder dropped the fields it needed) fixed with a real grading test; three separate checker mistakes found and corrected during the run2026-09-20

What’s left

  1. Flip Western Slope’s page to the card-based list, then verify it live.
  2. Run the one-time cleanup of invented rows (backup first).
  3. Re-run the real-data checker after cleanup to confirm it’s still clean.
  4. Prove Camellia’s page is byte-identical before and after.
  5. Inspect the result in production once live.
  6. Ship the follow-up PR for the record-owner setting’s default (a smaller cleanup item, not a new feature).

Situs Group has no production organization yet, so it has no live page to flip — its numbers above come from the harvested test pull, not production.

PropFlow Docs