The plan to finish Google Calendar for a company's shared calendar and a leasing agent's own calendar, and to straighten the onboarding steps around it. For Gera, in six pieces you can test one at a time.
2026-09-16 · Google integration scope v2 · S1 in progress
Google works for a building's calendar and nowhere else. New customers are set up as "one shared calendar for the company" by default, so the default customer path never reaches Google today.
| Rung | Where you see it | Today |
|---|---|---|
| Building | Property Settings · onboarding Channels step (per-building companies) | Google live |
| Company | Organization Settings · onboarding "company-microsoft" step (centralized companies) | Microsoft only |
| Person | /welcome/calendar · Profile → My calendar | Microsoft only |
The company and person calendars are stored in one shared token vault that already has a provider field with google as a legal value. What keeps them Microsoft-only is small: one refresh function that only knows how to call Microsoft, three gates that refuse a Google row, and two "coming shortly" buttons. There is no second storage system to build.
Each is its own pull request off main, each works on its own, and each ends with something you can see.
~250 lines · no visible change · unblocks S2 and S3
The one refresh function branches on the row's provider: Google rows refresh through Google, keep their long-lived refresh token, and a revoked Google grant marks the row "reconnect needed" with plain-English copy. The three gates that refuse a Google company or person row start admitting it, and the tour code reports "google" for those rungs instead of assuming Outlook. Tests: the existing "a Google company row never reaches Microsoft" pin flips to "reaches Google"; a new pin for the person rung, which has none today.
You see: nothing yet. This is the plumbing every later slice stands on.
~300 lines · onboarding + Organization Settings
The company connect route sends a Google-domain mailbox to Google's consent for the shared calendar, and the shared callback stores a company row. The onboarding step's Google button stops saying "coming shortly". Organization Settings shows the Google calendar as connected, and the collapsed row in Property Settings names it.
You see: in the centralized test company, "Continue with Google" opens Google's consent for calendar access; afterwards Organization Settings shows the calendar connected, and Clara books tours against it from the bench.
~250 lines · /welcome/calendar + Profile
The Google button on the first-run calendar screen and a Google option on "My calendar" go through the same shared callback and store a person row. Clara's "which agent is free" logic reads it like a Microsoft one.
You see: a new teammate's first sign-in offers Google for real; Profile → My calendar shows it connected.
~150 lines, mechanical · old address redirects
/onboarding/company-microsoft becomes /onboarding/company-channels. Every reference moves (about twenty, plus a generated route manifest and one browser test); the old address keeps working by redirect so no bookmark or email link breaks.
You see: the address bar says company-channels.
~300 lines · sequence, back button, Skip vs Finish
One Channels step that shows the company shape or the per-building shape instead of skipping to a separate page. The personal calendar becomes a wizard step after Channels rather than a surprise after "Finish". Every step has Back. Teammates ends with one primary action: "Skip for now" when nothing is typed, "Send invites" when something is, never both.
You see: AppFolio → Sync → Review → Channels → Your calendar → Teammates → Dashboard, with Back on every screen.
~120 lines · teammates step only
The role picker moves to the arsenal select. The name field becomes optional: a suggestion is derived from the email ("jane.doe" becomes "Jane Doe") and stays editable, since guesses from addresses are wrong often enough that people need to fix them.
You see: invite a teammate with just an email.
| After | Who | Do | Expect |
|---|---|---|---|
| S2 | propflow.test in the centralized test company | Onboarding company step → Continue with Google → pick test.client@ → allow calendar | Back in PropFlow with the calendar connected; Organization Settings shows it; a bench tour lands on that Google calendar |
| S3 | a new teammate invite | First sign-in → /welcome/calendar → Continue with Google | Profile → My calendar shows the Google calendar |
| S4 | anyone | Open the old company-microsoft address | Lands on company-channels |
| S5 | a fresh test company | Walk the whole wizard | Straight line, Back everywhere, one clear ending |
| S6 | same walk | Invite by email only | Name suggested, editable |
company-channels matches the API and the settings card; another name is a one-line change.