Verdan · new-tenant experience

Verdan Onboarding Fix Plan

A new GC admin should reach a live jobsite in one sitting of about ten minutes and never be asked the same thing twice. Today five separate setup surfaces fire on the same person, read different "done" signals, and leave dead ends. The fix is one setup state, three screens, one follow-up list.

Findings behind this plan are filed as VER-8526 with 13 sub-issues, each cited to file and line on main.

Who onboards, and what "done" means to them

Three people arrive in the first week. Only one of them should ever see a setup wizard.

PersonHow they arriveWants in the first sessionMust never happen
Sarah
GC owner or safety director (admin)
Activation email after HQ provisioning, or Stripe checkout when self-serve is onA jobsite that is live: project, super assigned, QR poster printedBeing asked for her company name, first project or team invite twice
Mike
Superintendent
Invite email from Sarah during setupLog in on his phone, see his project, approve the first foremanLanding in Sarah's wizard, or on a page telling him to create a project
A sub's foremanProject invite, or the QR poster on day oneSign in his crewAny setup screen at all
The payoff moment

The first worker sign-in on the QR poster. Everything before it is setup cost; everything after it is the product. The jobsite story canon puts this at pre-day-1: the GC sets the project up, the super approves the foreman, the crew self-signs on the QR. Onboarding is done when that chain can start, not when a checklist reads 9 of 9.

That gives one definition of done for the whole tenant: company profile filled, one project created with a super on it, and the QR poster generated. Subs, insurance requirements, templates and orientation are follow-up work the product should nudge, never gate.

What Sarah hits today

Sarah's first session, as main ships it, asks her to set up the company four times and never tells her when she is finished.

flowchart TD
  A[Activation email] --> B["/activate then /login"]
  B --> C["/projects: Getting Started card
4 steps, 'Your account is set up'"] C --> D["Top-bar pill unlocks
'0 of 4'"] C --> E["Guard redirects to
9-step wizard"] E --> F["Wizard inside dashboard shell
pill still visible"] F --> G["Playbook step links out
to /admin/users"] G --> E F --> H["Complete: redirect to
8-step project setup checklist"] H --> I["/admin/getting-started
6-step guide"]

The card and the wizard fire on the same landing. Leaving the wizard by its own links can bounce her back in. Finishing it drops her into a second checklist, with a third guide page one click away.

Screen by screen

  1. Payment or activation. Self-serve checkout ends on a page whose only link is the homepage. HQ-provisioned tenants get an activation link that ends at login. Either way Sarah finds her own way in. VER-8543
  2. First landing on /projects. A Getting Started card says "Your account is set up" and lists four tasks. Seeing it unlocks a "0 of 4" pill in the top bar. In the same second the auth guard reads the tenant's onboarding row, sees "in progress", and redirects her to the wizard. VER-8535 VER-8534
  3. The wizard. Nine steps: account, company profile, playbook, first project, team, billing, compliance, mobile, review. It renders inside the dashboard shell, so the sidebar and the pill surround it. The billing step asks a self-serve tenant to pay again. The playbook step's "Do it now" links go to admin pages; following one can send her back to step one on the next page load. VER-8536 VER-8537
  4. After Review and Launch. She is redirected into an 8-step project setup checklist for the project she just created. Two of its required steps, subcontractors and compliance requirements, repeat what the wizard asked. VER-8537
  5. Back on the dashboard. The card still says "Create your first project" because it never renders ticks. The pill counts from a different endpoint whose invite check looks at the users table, so people she invited do not count until they accept. The guide page's Mark as Complete forgets on reload. VER-8538 VER-8539 VER-5473
  6. Her super, Mike. His invite email links to /invite/{id}, a page that does not exist. If he signs out mid-wizard he is sent to /signup, not /login. VER-8540 VER-8541

None of these is a hard bug on its own. Together they are why the experience reads as broken.

The target flow

One setup state, computed on the server from what the tenant actually has, drives everything: the one redirect, the wizard's starting step, and the follow-up list. No stored "completed" flags to drift.

flowchart LR
  P["Payment or activation
lands on /activate"] --> W1["1. Your company
name, address, timezone"] W1 --> W2["2. Your first jobsite
name, address, start, super"] W2 --> W3["3. Print the QR poster
invite subs (optional)"] W3 --> D["Jobsite dashboard
one Setup list, 3 of 5"] D --> S["First sign-in on the QR"]

Three full-screen steps, no dashboard shell, no pill. The follow-up list on the dashboard is the same five-item state, read from the same endpoint, and it disappears at the first sign-in.

The five-item setup state

ItemDerived fromGates the wizard?Replaces
Company profiletenant name, address, timezone presentYeswizard account + company steps, guide step 1
First jobsiteone project rowYeswizard project step, card step 1, guide step 2, checklist basics
Super assigneda project lead row with role super, invite pending countsYeswizard team step, card invite-team, playbook
Subs invitedat least one subcontractor besides the GC self-subNo, nudge onlycard import-subs, guide step 3, checklist subcontractors
First sign-inone sign_ins rowNo, ends the listthe reason the list exists

Billing leaves the wizard entirely. A self-serve tenant already paid at checkout; an HQ-provisioned pilot carries a pilot billing profile set at provisioning (see VER-8547). Compliance requirements, templates, orientation and notifications come from tenant defaults the seeding lane is adding now (VER-8548 to VER-8551), so the wizard stops asking a first-day admin to configure them.

Walkthrough of the target flow

Sarah's first ten minutes

Mike's first login

Sarah abandons at step 2 and comes back on Thursday

Rules the build keeps

Redirect rule

Redirect an admin into the wizard only while company profile or first jobsite is missing. Never redirect any other role, ever. Never redirect on a page inside the wizard. The rule lives in one place and reads the setup endpoint, so the two disagreeing signals (tenant_onboarding_state and tenants.onboarding_completed) stop being read by anything.

Derived, not stored

Every tick is computed from rows that exist for another reason: a project, a lead, a subcontractor, a sign-in. "Mark as complete" buttons go away. Dismissal of the follow-up list is the one stored value, and it is stored on the tenant, not in localStorage.

Ask once

If the wizard asks it, the project setup checklist does not. The 8-step project checklist becomes the per-project detail view of items the tenant list nudges, and its required flags drop to basics and QR only. Billing is never a wizard step.

Same words everywhere

Step ids and labels come from one shared list in packages/shared. The card, the wizard and the API return the same five ids, so a tick earned in one place shows in every place.

Build plan

Five phases. Phase 0 and 1 need no product ruling and can start now. Phases 2 to 4 wait on the decisions in the last section.

Phase 0 · Stop the bleeding

can start now
VER-8540VER-8541VER-8543VER-8542
Fix the invite link target, the sign-out redirect to /signup, the payment-success dead end, and remove the bare /onboarding public route.
Verify: a Playwright live check that follows a real invite link to activation; contract test that no email template links to a route the app does not serve.

Phase 1 · One setup state

can start now
VER-8534VER-8538VER-8539
Extend GET /api/tenants/onboarding-status into the five-item state above, with the invite check counting pending invitations and the sub check excluding the GC self-sub. Point the redirect guard and the card at it. Card renders real ticks.
Verify: API unit tests for each item's predicate against fixtures (fresh tenant, tenant with invites only, tenant with self-sub only); a red-then-green contract test that the guard reads only this endpoint.

Phase 2 · Three-screen wizard

after decisions
VER-8535VER-8536VER-8537VER-8544
Cut the wizard to company, jobsite, poster. Full-screen layout without the dashboard shell. Prefill from the lead or HQ record. Drop billing, playbook, mobile, compliance and review steps. Starting step comes from the setup state.
Verify: dev-build screenshots of all three steps at phone and desktop width, approved before merge; e2e that abandons at step 2 and resumes at step 2.

Phase 3 · One follow-up list

after decisions
VER-8539VER-5473
Replace the card, the pill and the guide page with one Setup card driven by the same state. Dismissal stored on the tenant. The guide's explanatory copy moves into each item's expandable help. Project setup checklist drops the duplicated required steps.
Verify: contract test that exactly one component renders setup progress in the dashboard tree; the pill component and guide route are deleted, not hidden.

Phase 4 · Canon, SPECs, tests

with phase 2
VER-8545VER-8546
Amend the canon's onboarding ruling to the three-screen flow and the five-item state. Rewrite tools/onboarding-wizard-steps/SPEC.md and tools/get-started-topbar-pill/SPEC.md (the latter retires). Un-quarantine the two expired onboarding contracts and make them pass.
Verify: canon-lint green; quarantine.json has no onboarding entries.

Decisions needed from Daylan

Answer these and phases 2 to 4 dispatch as lanes the same day. Phases 0 and 1 are ready to dispatch now.