Renewals across all properties

A design and clickable prototype for one Renewals screen that works for one building, a few, or the whole portfolio. For Fede's review before any build.

2026-10-02 · Leasing > Renewals · Proposed — pending review. Nothing built.

Gera's organization-and-property model, applied to Renewals. You see only your own company's buildings; the screen shows whichever buildings are ticked in the selector, one, a few or all. Counts add up; rates are weighted. The model.

1. Problem

With "All Properties" selected, Renewals shows no renewals, only "Pick a property" and a pill per building (about 90 at Western Slope). This blocks Western Slope renewals.

Today: Renewals with All Properties selected shows an empty state and one pill per building
Today, from production (a two-building test login).

2. The design

Try it: pick buildings in the selector, click a row, click a purple button. It copies the real app; all tenants are made up.

Company:
Quick pick:
Columns:
What changes on screen
  • The selector takes one, a few, or all buildings. It is the real selector, unchanged; the Renewals page just stops refusing more than one.
  • Rows from every ticked building appear in the same three tabs. The month cards show the summed counts, nothing added. "% renewed" is summed renewed over summed decided, never an average of percentages.
  • A Property column shows only when two or more buildings are ticked, the same column Prospects has. Order is Unit, Property, Tenant (the toggle above also tries Unit, Tenant, Property).
  • A Property filter sits next to the Month filter the table already has.

Everything else is today's screen. With one building ticked it is identical.

How it works at one building, a few, and all
Selector showsWhat you seeWhy
One building (JP&Co with only Camellia)Today's season view, untouched: month cards, three tabs, no Property column.The set is one building, so every number is already that building's. Nothing to add.
A few (Camellia and Yale 25 Station)Same screen plus a Property column and a Property filter. Cards show summed counts and a weighted rate.The set is two buildings. Counts add, rates are weighted, and each row names its building.
All Properties at a big company (Western Slope, 89)Same screen as "a few". Most buildings have no renewals this season and simply add nothing.Same rule, bigger set. A failing building is noted, not fatal.
Where Renewals differs from Gera's model

Renewals needs no rules of its own. Three places where today's code breaks the model:

  • The one-building guard. Renewals is the one Leasing page that refuses a set. Prospects reads the whole company from one index; Tours reads each ticked building. The design makes Renewals behave like Tours. The guard's stated reason ("no honest cross-property math") does not hold: counts add and the rate is a weighted ratio.
  • Reading is building by building. There is no company-wide index of renewals, and the data is deliberately keyed by building, never by company. So the list reads each ticked building and combines them. For Western Slope that is roughly 1,000 small reads. It is not measured yet, so PR 3 must be timed on the real 89 before we pick a cache.
  • Per-building rules ride on the row. Rent policy, month-to-month premium, auto-start window and the "renewals off at this building" switch are per building. The list resolves them per row. A row at a building with renewals off shows that state instead of an Offer button.
What stays the same
  • Clicking a row opens the same renewal page for that lease. It is keyed by lease, so it needs no change.
  • The Review drawer and its two choices (Offer renewal, Move to month-to-month). Approve already works from the tenant alone.
  • One building selected: today's view, same numbers, same wording.
  • Stages, tab names and wording: Settled, Upcoming renewals, Requires action.
  • Renewal policy and auto-start settings stay per building, in their own settings screen.
  • Nobody sees a building outside their company. The list only reads buildings the selector already allows.
  • No switch. This fixes a live page, so it goes live everywhere when merged.
The build: four small pull requests
  1. PR 1, carry the building on each renewal. About 80 lines. Each row learns which building it belongs to. Nothing changes on screen.
  2. PR 2, read several buildings at once. About 280 lines. One loader that takes the ticked set, reads each building with limited parallelism, and records any building that failed instead of failing the page.
  3. PR 3, let the page accept a set. About 150 lines. The "pick a property" refusal goes away when two or more are ticked. A usable list exists after PR 3. It would still lack the Property column, so it is for us, not for Fede.
  4. PR 4, the screen. About 250 lines. Property column, Property filter, per-row drawer rules. A building that fails to load is skipped quietly, not drawn. This is the version to show Fede.
  5. Only if PR 3 is slow on the real 89: cap parallelism or store a company-wide list. Decide after a timing.

For Gera: the model says never blend report-only buildings into live numbers. I found no report-only marker on renewals data; where would it come from?

Proof wanted before each merge: a replay on real Western Slope data, a timing for 89 buildings, and the existing guard test staying green.

Decisions for Fede

1. Column order when several buildings are ticked

Compare both with the Columns toggle above the prototype. Unit and building read together as an address; Property last keeps the tenant name beside the unit as today.

2. Percent renewed on the month cards with several buildings

Weighted means summed renewed over summed decided, which matches a hand count. Keeping it means several buildings look exactly like one.

How this was made

Real screens captured from production, headless, with the smoke account: Renewals with All Properties (the picker), Renewals for Camellia (season cards, all three tabs, the renewal page), the building selector open, Prospects and Tours with All Properties. The smoke account sees only two buildings (Camellia, Yale 25 Station). It cannot see Western Slope or the Willows test building, and I did not open the Review drawer, so the drawer and the 89-building case are my best reading of the code, not screenshots. Only the picker screenshot is embedded here; the others show real tenant names, so the prototype redraws them with made-up people. Colors come from the app's own design tokens; the app's Suisse font is licensed, so the prototype uses Inter.

Renewal document setting (prototype)

Update Sat 10/3 — not building this. A look at every Western Slope renewal offer from July 3 to October 3 showed staff already send one document on every building: “AF Renewal Function: Renew (Simple)” (24 of 26 offers, every renewal since mid-July, Pomona Park included), with no extra addenda. The building defaults in AppFolio are leftover setup. Plan: ask Western Slope to confirm, then make that amendment the default on every building in AppFolio (we offered to do it for them). The robot already sends each building’s default, so no PropFlow setting is needed. Per-tenant cases (adding or removing a tenant) go to a person.

Proposed — pending review. Fede asked on 10/3 to see this with real data. A person picks the renewal document by name from the client’s AppFolio documents. We store its number behind the scenes and send it to the robot with every renewal offer. It is set per client, so each client can differ. Blank keeps today’s behavior: each building’s own AppFolio default.

Below is Western Slope with its real 49 AppFolio documents. Staff used the “Renew (Simple)” amendment on 26 of their last 30 offers. Click the field, search, pick another, or use the buttons to flip between open and closed.

Show:

1. A building has its own AppFolio default. Does the company choice still win?

Yes matches what staff actually send today. 10 Western Slope buildings default to one amendment, 10 have none, and staff pick another anyway.

2. Refresh the document list daily?

New templates then show up without anyone remembering to refresh.

A per-building view of which document each building would send could help later. Not built, not asked for.

PropFlow Docs