One to-do list on Settings › Onboarding & go-live: what the customer must finish, what Propflow is doing for them, and what blocks the "Turn Clara on" switch.
2026-10-02 · for Gera · research lanes A–D merged · spec, not shipped
Customer items
23
19 required · 4 optional · hidden per module
Propflow's side
23
18 before the flip · 5 in the first week
Today
11 rows
staff see 10, customers see 3, same for every company
… 14 more customer items below; after launch this page just says "You're live".
Today's checklist is 11 rows derived by one resolver (go-live-checklist-resolver.ts). Staff see 10, customers see 3 (inbox, calendar, billing). It is the same for every company, it gates nothing, and it is honest about what it can't read (unknown, never missing). That engine stays. This spec widens it.
Also fixed on the way: the Company | Property switch on this page goes (a deliberate exception to the 2026-10-01 "every settings page gets it" ruling: it was added in #15219 and carries no per-building checklist); the staff card's "six things" header comment is stale against ten rows; and the stale dto header note that nothing reads claraLive.
Columns. R = required to go live, O = optional helper. Who: Customer, Propflow, or Both. Shows when: all = every company; leasing, maintenance, renewals = the module is on; phone = maintenance on or a property line recorded. Done when says how the row turns green: an existing resolver row or questionnaire answer, a new automatic check (with the data it reads), or a manual checkbox. Sources cite the research files: A code, B Slack, C calls, D docs.
| # | Item and why | R/O | Who | Shows when | Done when | Sources |
|---|---|---|---|---|---|---|
| Your account | ||||||
| 1 | Your admin account is set up. Terms accepted and two-step sign-in on; everyone you invite inherits the terms. | R | Customer | all | Existing: terms record (/api/admin/companies/[id]/terms) and an MFA factor on the admin. Auto-ticked by the time they see the page. | B #5, #24 · C A01, A16 · D G-04 |
| 2 | Invite your team and check everyone can see their buildings. Clara hands tours, escalations and messages to people. A login that shows nothing produces duplicates. | R | Customer | all | New auto: at least one teammate accepted, and every accepted teammate has signed in once. Reads the per-teammate progress the admin page already has (/api/admin/companies/[id]/onboarding-progress). | B #35, #112, P11 · C A15 (#17), A16 · D G-04, I-03 |
| 3 | Set up billing. Your subscription starts the day you go live. | R | Customer | all | Existing billing row (Stripe subscription active or trialing). | A §1b · B #3-4 · D G-41 |
| Connect | ||||||
| 4 | Connect AppFolio, with a user for Clara. Clara reads units, prices, guest cards and leases from AppFolio; her own login (no banking permissions) is how she writes back. Yardi customers see "Send us your daily rent roll report" instead. | R | Customer | all | Existing pms row (credential present, last rent-roll or vacancy sync succeeded). Clara's user id is already required at connect. | A §3a · B #25-27 · C A21 (#1), A22 · D G-05, G-06, C-1 |
| 5 | Choose which buildings Clara works in. Everything starts off; you switch on the ones Clara covers. Banks, LLCs and "do not use" rows stay off. | R | Customer | all | New auto: at least one building In Propflow. Warn when a selected building's name matches bank/LLC/"do not use" or is typed commercial. Today this line has no done state. | A §1d · B #28-29, P6 · C A18 (#12), C30 · D G-07 |
| 6 | Connect your shared leasing inbox (not a personal one). The mailbox Clara replies from. If Microsoft or Google needs your IT admin to approve, this row says so. | R | Customer | leasing | Existing inbox row; pending_admin_approval shows as "Waiting for your IT admin". | A §1b · B #31-33, P2, P5 · C A27 (#6), A28 (#7) · D G-21 |
| 7 | Make sure lead emails reach Clara. Listing-site and AppFolio guest-card emails must land where Clara reads. Done only when a real lead has arrived. | R | Both | leasing | New auto: every In-Propflow building has an inbound address (Property.inboundEmailAddresses) and a lead was received in the last 14 days. The "last lead received" record is written by the inbound processor when it creates a lead; the resolver only reads it (no inferred timestamp). | A §5a, §5g #1 · B #66-67, P14 · C A48 (#14), C11 · D G-30 |
| 8 | Connect a calendar for everyone who gives tours. Clara books into the calendar of the person who shows the unit, not the admin's. | R | Customer | leasing | Existing calendar row, tightened: count only people whose role gives tours (CALENDAR_ASK roles), never org_admin alone. | A §1b, §5g #9 · B #36-37 · C A34 (#8), C14 · D G-24, C-8 |
| 9 | Set up your phones: how your system works, who answers, after-hours and emergencies. Which carrier or VoIP, who rings first, what happens after hours, who takes a real emergency. You tell us; Propflow wires it. | R | Both | phone | Existing questionnaire answers ring_list.leasing, ring_list.maintenance, catch_all, plus new questionnaire fields: phone system, and emergency contacts (customer writes names and numbers; staff set the route). The customer's row is done when answered; Propflow's row shows it wired. | A §4, §5f · B #82-88 · C A37 (#2), A39 (#4), A40 (#3), A42 (#25) · D G-13 to G-16, C-5, C-7 |
| Configure Clara | ||||||
| 10 | Office hours and tour hours. Separate: when the office answers, and when tours can be booked, with notice and travel time. | R | Customer | leasing or phone | Existing office_hours row, plus tour.durationMinutes and tour.travelBufferDefaultMinutes answered. | A §4 · B #54, #59-60 · C A46 (#9), C8 · D G-10, I-05 |
| 11 | Confirm fees and deposits for each building. One quotable number for application fee, deposit, pet rent. Confirmed values lock so a sync can't change them. | R | Customer | leasing | Existing questionnaire: pricingVerified on every In-Propflow building. | A §4 · B #46-47, P17 · C A55 (#11), C13 · D G-34, G-35 |
| 12 | Answer the leasing questions. Applying, policies, tours and move-in. Clara declines what you haven't answered. | R | Customer | leasing | Existing: Leasing pending count = 0 (25 questions today). | A §4 · B #44-45 · C A54 (#10) · D G-32 |
| 13 | Answer the maintenance questions and pick preferred vendors. Ring list, office line, and the vendors Clara may dispatch. | R | Customer | maintenance | Existing: Maintenance pending = 0, plus new auto: preferredVendors non-empty at company level or on every In-Propflow building. | A §4, §5b · B #98 · C A69 · D I-15 to I-20 |
| 14 | Answer the renewal questions. How new rent is set, lease lengths, who is held for a person. Your money, so no defaults. | R | Customer | renewals | Existing: Renewals pending = 0 (renewal.offerTerms, renewal.eligibility). | A §4, §5c · B #102-103 · C A70 · D I-24 to I-26 |
| 15 | Who gets escalations and messages. A named person on your domain, by text or email. Not a shared inbox full of invoices. | R | Customer | all | Existing escalation_owner row, plus new check: the resolved address is not @propflowai.co and not the leasing inbox itself. | A §1b · B #76-77, P20 · C A61, C9 · D G-12, C-9 |
| 16 | Turn off AppFolio's own auto-replies and reminders. So Clara is the first and only reply a prospect gets. | R | Customer | leasing | Manual: customer ticks it. | B #68 · C A31 · D G-09 |
| 17 | Flag special buildings. Lockbox self-show, not for rent, coming soon, income-restricted. Clara needs the exception before day one. | O | Customer | leasing | Manual: customer ticks it (the per-building tours-type answer is the real home; this is the reminder). | B #29, #48, P16 · C A47, C7 · D I-11 |
| 18 | Name a backup showing agent. If the one agent is out, tours still book. | O | Customer | leasing | New auto: two or more tour-giver calendars connected. | B #38 · C A35 |
| 19 | Clean up availability dates in AppFolio. "Ready for showing" dates and published listings are what Clara offers. | O | Customer | leasing | Manual: customer ticks it. | B #64-65 · C A52, C12 · D I-09 |
| Test and go live | ||||||
| 20 | Brief your team on what changes. Who owns a lead, how to hand one to a person, and the 15 to 30 minute review delay in week one. | R | Both | all | Manual, two ticks: Propflow ticks "one-pager sent", customer ticks "team briefed". | B #116-117, P12 · C A79 (#19), C3 · D G-44 |
| 21 | Try Clara yourself: call, text and email her. Your sign-off before anything is forwarded. | R | Both | all | Manual: customer ticks the sign-off. Propflow's own end-to-end test is a Propflow-side row. | B #109-110 · C A74 (#20) · D G-37 to G-39 |
| 22 | Forward your main phone line to Clara. This is the moment Clara answers your phones. Done when we see a forwarded call. | R | Customer | phone | New auto: an inbound call on the company's line whose ForwardedFrom is the customer's main number, within the last 7 days. The main number is read from the customer-forwarded registry row (forwardsInto) or, when none exists, the phone-system answer in item 9. Unlocked once Propflow's side says ready. | A §5f · B #84-85, #113, P8 · C A37 (#2), C15 · D G-18, G-43 |
| 23 | Let residents know Clara is AI. Signage or a notice; outreach from an unknown number reads as a scam. | O | Customer | maintenance or phone | Manual: customer ticks it. | B #119, P23 · C C41 |
A leasing-only company with no phone line sees 18 of these (15 required, 3 optional). A maintenance-only company with a phone line sees 13. The list is deduplicated across 126 Slack items, 85 call items, 45 playbook gates and the 11 code rows; the long tail (lease-wording FAQ, weekly lead summary recipients, uploaded house rules, Spanish per building) stays in the questionnaire's optional questions, not on this list.
The customer's page shows these as "Propflow is setting up your phone line" lines, never as checkboxes. Staff see them as rows with ticks and history. Manual rows record who ticked, when, and keep every change.
| # | Item | Shows when | Done when | Sources |
|---|---|---|---|---|
| Before the invite | ||||
| P1 | Company created from the AppFolio pull; operating model and modules set; one company per PMS database | all | New auto: operatingModel non-null, enabledModules non-empty, no second org on the same PMS subdomain | D G-01, G-02 · B #10-11, #14 · C A03, A05, A08 |
| P2 | Isolation checked by signing in as the new admin | all | Manual staff tick | D G-03 · B #20 · C A12 |
| P3 | Every building and the company has a time zone | all | New auto: buildings missing a time zone = 0; org.timezone set | D G-08 · B #55, P26 · C A09 |
| P4 | Import capped at 30 days; reminders and notifications off | all | New auto: pm_action_reminders.enabled false; import record window ≤ 30 days | D G-09 · B #12, P1 · C A29 (#5), C1 |
| P5 | Email identity chosen (whose address Clara writes from) | leasing | Existing email_setup | D G-20 · B #15 · C A30 |
| P6 | Lead source, prospect record owner and AppFolio trusted senders set | leasing | New auto: leadSource, prospectRecordOwner, appfolioTrustedSenders non-empty | D G-27 to G-29 · A §5a |
| P7 | Application link mode set; building URLs exist when the mode is a fixed link | leasing | New auto: leasing.applicationLinkMode set; if fixed_url, every In-Propflow building has an applicationLink | D G-31 · A §5g #4 · C A51 |
| Connect and configure | ||||
| P8 | Phone line bound to the buildings and the voice agent; no empty dynamic field; sender registration approved | phone | Existing phone_line, plus new: the number is in config/elevenlabs-phone-numbers.json; Twilio A2P or toll-free status reads approved; the empty-variable test is green | D G-17, G-19 · A §5f · B #19 |
| P9 | Call routing wired: office hours, catch-all, emergency route | phone (emergency: maintenance or phone) | Existing office_hours, catch_all_line, emergency_route, now module-scoped | D G-14, G-15, C-7 · A §1b |
| P10 | Every transfer target test-called | phone | Manual staff tick with the call ids | D G-18 · B #87 · C A39 |
| P11 | Knowledge loaded and read back; confirmed fees locked | leasing | New auto: last knowledge:verify-live result for the org reports 0 missing (store the result); pricingVerified true on every building | D G-33, G-34, G-36 · B #43 |
| P12 | Compliance review of the answers (fair housing, source of income, assistance animals) | leasing | Manual staff tick | B #49 · C A57 |
| P13 | Replay on the customer's own guest cards; one fresh lead proven end to end | leasing | Manual staff tick with the counts | D G-37 to G-40 · B #107 · C A75 |
| P14 | End-to-end test on every channel with the real calendar and mailbox | all | Manual staff tick | B #109 · C A74 |
| P15 | Activity Slack channel registered; support channel open | all | New auto: the org's Slack channel id is set | D G-25 · B #121 · C A66 |
| P16 | Modules that are off are really off; renewal per-building arms set on purpose; maintenance intake route set | all | New auto: building module rows agree with enabledModules; autonomousRenewalEnabled reviewed when renewals is on; maintenance.intake_route set when maintenance is on | B #11, P18 · C A67 (#22) · A §5b, §5c · D G-45, I-29 |
| P17 | Staff one-pager sent | all | Manual staff tick (pairs with customer item 20) | B #116 · C A79 |
| P18 | Turn Clara on, supervised: live switch on, review hold on | all | Existing claraLive and reviewOutboundEmails | D G-42 · A §2a |
| First week (taking the review hold off) | ||||
| P19 | Mailbox reading confirmed and the subscription renewing | leasing | Existing mailbox_reading, plus new freshness: subscription expiry in the future, renewer logged recently. Moved here because the Gmail reader skips until live, so it can't be green before the flip. | A §5a · D G-22 |
| P20 | Replay of the week's guest cards: 0 "do not send", at least 90% send as is | leasing | Manual staff tick with the counts | D X-01 |
| P21 | No open correctness bug on this customer's shape | all | Manual staff tick | D X-02 |
| P22 | A fresh-lead proof after the latest deploy | leasing | Manual staff tick; the timestamp must be later than the last production deploy | D X-03 |
| P23 | The onboarding lead's explicit go, in one line; then the review hold comes off | all | Manual, recorded with who and when | D X-04 · B #104 |
clara+<company>@propflowai.co as a user with no banking or financial permissions, its user number saved on the company connection. The shared clara@ address in the older intake draft is superseded: a flagged or rate-limited login must take down one customer, not all. Per-PMS rule: AppFolio = API credentials plus Clara's user (checklist item 4); Yardi = no connection, a daily rent-roll report plus outcome emails forwarded to Clara (item 4 swaps its wording).maintenance.intake_route leaves the customer count entirely (it is already Propflow-only).gmail.readonly, which needs a CASA audit nothing in code uses yet. For Google Workspace customers the IT admin allowlists Propflow's app (no CASA), the shared mailbox is connected for sending, and leads reach Clara through forwarded listing emails and AppFolio guest cards (item 7 proves it). The Gmail reader also skips everything until the company is live, so "mailbox reading confirmed" moves to the first-week list (P19) instead of sitting red before launch.Today nothing blocks it; billing adds a sentence to the confirm dialog. Recommendation: block on five auto-detected facts, warn on everything else. Blocks never depend on a manual tick (a tick is a claim), and a platform administrator can override a block with a typed reason that is recorded in the manual-check history and shown on the staff card. A guard with no must-pass control is just a wall.
| Block (switch refuses) | Why |
|---|---|
| AppFolio connected and a sync has succeeded (or the PMS is not AppFolio) | Clara would be live on no data. |
| At least one building In Propflow | Live on nothing is a lie on the staff page. |
| At least one module on | Same. |
| Email identity chosen; and if the identity is the customer's own mailbox, the inbox row is ready | The flip means Clara starts emailing prospects. With a Propflow-hosted address the inbox is only a warning, so onboarding is never blocked on IT (the 9/16 ruling). |
| Escalation owner resolves to a person on the customer's domain | Every held or escalated item needs a human who is not us. |
Warn (listed in the dialog, switch still works): billing, calendars, a lead received, office hours, every phone row, time zones, knowledge verified, team invited and signed in, replay result, and every manual tick (team briefed, customer tested, compliance, isolation).
Today claraLive holds customer-facing email and proactive prospect texts only. Voice is not gated at all, and inbound texts get replies. A number wired for testing means Clara is live on the phone before anyone flipped anything. Recommendation: claraLive also gates voice and inbound SMS, with a tester allow-list (registry numbers of kind human or tester, plus the customer's own staff numbers). While dark, an unlisted caller hears that the line is not in service yet and is forwarded to the customer's existing line or office line; an unlisted text gets no reply and is logged. Test calls still work. This is the one change in the live voice path, so it is the last PR and needs a yes before it starts.
Each part works on its own and branches off origin/main. Target 300 lines, hard ceiling 1,000. Files are under propflowai/src; dto = lib/domain/onboarding/go-live-checklist-dto.ts, resolver = …/go-live-checklist-resolver.ts.
appliesTo to every row and an applicability input (modules on, phone derived from maintenance or a property line in config/phone-registry.json); selectCustomerRows and selectStaffRows filter by it. The resolver reads enabledModules (it never has). Visible result: a maintenance-only company stops seeing "Connect your inbox". Files: dto, resolver, app/api/settings/go-live-checklist/route.ts, app/api/admin/companies/[id]/go-live-checklist/route.ts, tests.account_ready (terms + MFA), team_ready (reads the onboarding-progress data), buildings_chosen; tighten calendar to tour-giver roles; add the domain check to escalation_owner. Files: dto, resolver, lib/domain/onboarding/onboarding-progress-dto.ts, tests.handler.ts path that already consults the live gate) it stamps leadIntake.lastReceivedAt and the source on the Organization. Write only, no reader yet.lead_intake row: inbound address on every In-Propflow building and a stamp within 14 days. Customer item 7 appears.company_shape, timezones, import_window, lead_source_owner, application_link, slack_channel, modules_inert, vendors. Files: dto, resolver, tests.phone_bound (ElevenLabs numbers file, Twilio registration status) and mailbox_fresh (subscription expiry, renewer log). Each read fails to unknown, never missing.lib/domain/onboarding/go-live-manual-checks.ts on setting attachments with history, same pattern as lib/domain/organizations/customer-building-control.ts (listSettingAttachments(…, {history:true})). Routes: PUT /api/settings/go-live-checklist/[key] (org admin of that company; customer-tickable keys only) and PUT /api/admin/companies/[id]/go-live-checklist/[key] (staff). The resolver turns a ticked row into ready with "ticked by role, date"; unticking is allowed; history is readable.app/(workspace)/settings/_components/PreLaunchChecklistCard.tsx becomes the phased checklist: checkboxes (manual rows clickable), Required/Optional pills, a progress bar over required items, "Propflow is doing" lines. settings/go-live/client-page.tsx drops the Company | Property switch and building-go-live-card.tsx is deleted. onboarding-hub-hero.tsx derives its steps from the checklist; GoLiveBanner.tsx counts required items left. Live: "You're live", with one supervised-week line.app/(workspace)/admin/companies/[id]/_components/GoLiveChecklistCard.tsx: customer's items as progress, Propflow's items with ticks and history, a first-week section; fix the "six things" comment.lib/domain/onboarding/go-live-gate.ts, a pure function rows → {blocks, warns}. app/api/admin/companies/[id]/clara-live/route.ts answers 409 with the blocks unless the body carries an overrideReason from a platform administrator (recorded via the store). The confirm dialog in …/_components/CustomerDetailClient.tsx lists blocks and warns, replacing claraLiveBillingWarning.lib/domain/onboarding/onboarding-menu.ts, settings keys, the Hours & contact and Emergencies sections); maintenance.intake_route leaves the customer count.claraLive. In the live voice path: needs a yes before starting, not in the ordinary auto-merge lane.SYSTEMS.md entry for the checklist resolver with liveness signals; the two 8-row lists are removed.Parts 1, 2, 7 and 8 can open in parallel (three at a time per builder). Part 4 needs 3 merged; part 10 needs 7. Everything else is independent.
Four research files, read in full, then deduplicated into one list. Where two sources disagreed, the later and more specific one won, and the disagreement is listed under conflicts.
origin/main at 741357c7ee2, 2026-10-02): the 11-row resolver and its two selections, the wizard steps, the 29-question questionnaire, the per-module integration gaps ranked 1 to 10.People appear by role only. Company names appear only in this section. Quotes were not re-checked against raw recordings for this page; the research files carry the timestamps.