Properties — the grid paints from the roster, counts stream in

The building cards paint without waiting for the units, leases and work-order reads; their counts say "—" until they land and "Couldn't load" if they fail.

28 Sept 2026 · branch p11-properties-roster-first-paint · captured against json · at 1a0e36e7c2+local

Data note. Every name and balance below comes from json, which is anonymized by construction (ADR-0097/0110 — phones in the impossible +1000 NPA, emails @example.test). The identical capture against prod would carry real tenants' names and balances and is not safe to attach anywhere, which is why the generator refuses to run against one.

1 · While the counts are on their way

The counts are withheld (a local-only patch, never committed, drops the streamed promise) and the client's own refresh is blocked, so what is on screen is exactly the first paint: every building's name, address and unit count, and a — in every count that has not arrived. No 0, no 0%, no $0: a count the server has not sent is shown as absent, never as zero.

Asserted in the captured DOM — Properties · UNITS · OCCUPANCY · OPEN WOS · MONTHLY RENT · — · contract rent, occupied units. The card labels render uppercase, so the DOM text is uppercase. The pending counts read "—", and the rent caption (a label, not a number) is already in place, so the card does not grow when the counts land.

While the counts are on their way
The filled and failed states, and how these were produced

2 · When the counts land

The same page with nothing held: the counts arrive about three seconds after first paint (a local-only delay stands in for the slow reads) and fill the same cards in place — occupancy with its occupied count, open and total work orders, monthly rent.

Asserted in the captured DOM — occupied · total · contract rent, occupied units. "N occupied", "N total" and the rent caption appear only on a row whose counts arrived.

When the counts land

3 · When the counts fail

The streamed counts are forced to fail and the client's refresh is blocked. The cells stop saying "—" and say Couldn't load, and one line above the grid says so with a Retry. The page's 5-second refresh keeps trying on its own; the moment one answers, the counts replace these.

Asserted in the captured DOM — Couldn't load occupancy, rent and work-order counts · Retry · Couldn't load. The failure is named, not left as "—" forever.

When the counts fail

How these were produced

Local dev server on the JSON dev backend (data/*.json, dev staff user), not stage or prod. The hold, the forced rejection and the three-second delay are a local patch that is not in this PR. Whether first paint actually moves prod LCP (p75 3,392 ms) is a post-deploy real-visitor check, not something these pictures show.

PropFlow Docs