Swimlanes
These are the completable workflows the rebuilt app actually supports. Lanes are actors. Time flows left → right.
For HPD-specific multi-order examples (616+617 split, 622←617 blocker, RPO+hazard) with built-vs-not-built UI notes, see ../PROJECT_LIFECYCLE_GUIDE.md. For pass/fail of a real walk-through, see ../LIFECYCLE_ASSESSMENT.md.
1. Staff project: violation → commercially done
Canonical version of the lifecycle swimlane. ../PROJECT_LIFECYCLE_GUIDE.md §6 points here instead of redrawing it.
Phase is not a system actor. The header dropdown (setProjectPhase) can be clicked at any time; it does not evaluate conditions. Filing vs billing are independent: setting closed does not wait on HPD accepting a package, and closed does not make the project read-only.
Collaborator tenant with field_execution can sit in the Inspector lane for that project only. They never enter the Back-office money lane.
XRF is the only report generator wired in the wizard. Paint-chip / dust-wipe / abatement capture data that no UI turns into a document.
2. Agency ingest (no UI actor)
Until a cron is attached in the hosted Supabase project, this lane only runs when someone invokes the function (local script: db-tests/scripts/run-sync-orchestrator-locally.ts). Citywide map (/map) and violations explorer (/violations) read this data; they do not sync it.
3. Client portal (read-only)
No portal messaging, work-order requests, self-signup, or password-reset flow. Accounts are staff-provisioned. Portal users cannot see inspections, rate cards, licenses, or vendor payments (proven in db-tests leakage suite). Portal route /portal/violations exists alongside the staff /violations explorer.
4. Notification + email
SMS: if sms_enabled, notify writes a second notification_log row with channel='sms' and status='queued' and does not call a provider.
5. Cross-tenant collaboration
Invite roles (code catalog, domain/src/collaboration/collaboratorRoles.ts): field_execution, abatement, clearance_sampling, lab_coordination. Field-table RLS is role-scoped via has_active_collaboration_grant_for_role(): field_execution on inspections/XRF/floor plans/inspection_events; lab_coordination also on samples/CoC; abatement also on abatement_components. clearance_sampling has no RLS array yet. Project SELECT is any active grant. 28 RCNY abate-vs-clearance independence is warn-only at invite time and at visit time.
The Collaborators card on project detail uses collaboration_tenant_directory() / project_collaborator_tenants() so staff pick a tenant by name instead of pasting a UUID. There is still no HQ/firm switcher comparable to the old app.
6. Platform impersonation (schema ready, no product UI)
start_impersonation / stop_impersonation + impersonation_sessions + audit_log. Time-bounded, reason-required. The rebuilt staff app does not expose an impersonate control. REQUIREMENTS still wants the tenant to be able to read the audit of impersonation against them.