Reporting for scattered-home portfolios

The weekly owner report was built for one big building. Western Slope is dozens of single-family homes, each its own property, so it sends dozens of one-house emails. Here is the shape that replaces it.

Proposed — pending review  ·  2026-09-14 · design only, nothing built

A · What happens today

One email per building every Monday, whether or not the building is a house.

The job runs Mondays 15:30 UTC (vercel.json:153). It loops every property, skips test ones, and mails the configured owner recipients plus the property's own inbox, which is always added, never replaced (run-digest.ts:511, 525, 574-583). On 2026-09-14 it built 72 reports across 82 non-test properties (Fede's figure; not re-run here). Most are Western Slope's 69 buildings, one per home (provision-western-slope-front-door.ts:92).

Two facts shape the fix. Nothing groups properties except the company — no portfolio or owner record exists, and Property.ownerId is a PMS-credential login, not a landlord (types.ts:3868). And occupancy is occupied ÷ units (build-report.ts:325), which on a one-unit home only ever prints 0% or 100%.

Correction to the brief: no open change gates the report to properties that have recipients configured.

B · What we report on

OptionWhat it givesWhy not / why
Per home (today)Nothing new72 emails saying "100% occupied, no activity".
Per managerA work queueA dashboard, not a report.
Per ownerWhat each landlord ownsRight eventually; no ownership record exists yet.
Per company, homes as rows  recommendTotals on top, a row per homeBuildable today; the view the manager needs.

Recommendation: roll up to the company; keep per-building reports for real buildings. Under five units becomes a row, five or more keeps its own report — Camellia untouched. Per-owner reports wait for ownership rows.

A one-house percentage means nothing: occupancy is a state, not a rate. Percentages live in the portfolio total; the home row reads "vacant, 3 leads, 1 tour".

C · Where it attaches and who gets it

Gera's model settles most of this: the company is the wall, a mailbox hooks to exactly one node, and an owner-facing report is pushed into the owner's own room when a live ownership row grants reports.

D · What the roll-up says

E · Cadence and delivery

Weekly Monday, unchanged, one email per company. AppFolio already sends landlords a monthly statement of money in and out; we never restate it. Ours is leasing: who is empty, for how long, what came in. Owner push, when it comes, is monthly and leasing-only.

F · Change sketch and proof

No new tables. One field on the company record, one grouping step, one alternate layout. Four changes, one concern each, all dark:

#ConcernDeletes / folds
1Reporting mode on the company record, unused
2Group by company; small homes become rowsRetires the per-home send under five units
3Roll-up email layout, with the quiet-week lineFolds the empty-report drop
4Recipients come from the company, not the propertyRetires the per-property recipient list

Delete before you add: 70-odd single-home emails become one. Proof: run it at the bench off Western Slope's real imported buildings, read-only, showing before and after — 72 emails to 1, vacant list and days vacant matching AppFolio. Two clean runs, then Fede's call to turn it on.

G · Decisions for Fede

QuestionOptions
Reporting unitA. One email per company, homes as rows ✔ · B. Per owner · C. As is
Home vs. building lineA. Under five units rolls up ✔ · B. Under ten · C. Per-property choice
Owner reportsA. Later, after ownership rows exist ✔ · B. Now, hand-entered
Quiet weeksA. One-line "all quiet" ✔ · B. Send nothing
Recipient at Western SlopeA. Shared leasing mailbox ✔ · B. Named people · C. Both

Sources: the report code (src/lib/domain/leasing/reporting-digest/), src/lib/data/types.ts, the Western Slope provisioning script, and Gera's portfolio architecture. The 72-of-82 figure is Fede's, from the 2026-09-14 run; every other citation was re-read at the tip of main that day.

PropFlow Docs