How guided onboarding works
The onboarding state machine — how each wizard step derives from real app state, how skips auto-upgrade, and what Super Admin can see.
How guided onboarding works
The guided setup wizard is not a checklist that trusts you — it is a state resolver. Every step is recalculated from real system state, so "done" can only mean "the thing actually exists". That design choice explains almost every behaviour you will observe, including why some steps you thought you finished can flip back, and why skipped steps complete themselves later.
The idea in plain language
- The wizard walks a workspace through the 12 frozen client steps (Client onboarding from zero).
- Behind the scenes, a resolver asks the database one question per step: "is the real condition for this step true right now?"
- The answer becomes a status:
NOT_STARTED,IN_PROGRESS,COMPLETED,SKIPPED(you chose to skip) orBLOCKED(Meta needs attention). - Completion is one-way: once the resolver sees real state, the step stays completed.
- Zodiac Tech sees the whole picture on the client onboarding dashboard — including skips and stuck steps — and the workspace is notified when you finish.
stateDiagram-v2
[*] --> NOT_STARTED
NOT_STARTED --> IN_PROGRESS: you open/provide the step
IN_PROGRESS --> COMPLETED: real condition true
IN_PROGRESS --> BLOCKED: Meta needs attention
BLOCKED --> IN_PROGRESS: connection fixed
IN_PROGRESS --> SKIPPED: you skip (skippable steps only)
SKIPPED --> COMPLETED: condition met later (auto-upgrade)
COMPLETED --> [*]: wizard completes when all required steps settle
The 12 client steps and their real conditions
| # | Step key | Completes when… | Required / Skippable |
|---|---|---|---|
| 1 | business |
Business name and business type are set | Required · not skippable |
| 2 | industry |
Industry is set and a pipeline exists | Required · not skippable |
| 3 | meta_connect |
A Meta connection exists (BLOCKED if error/needs-reauth) | Required · not skippable |
| 4 | meta_assets |
A Page and an ad account are stored on the connection | Required · not skippable |
| 5 | lead_forms |
Form ids are selected and the mapping is confirmed | Required · skippable |
| 6 | sales_process |
The largest pipeline has ≥ 2 stages | Required · not skippable |
| 7 | lead_routing |
Assignment mode is off/specific/round-robin | Required · not skippable |
| 8 | followups |
An enabled lead_created automation exists |
Required · not skippable |
| 9 | team |
The workspace has more than one user | Optional · skippable |
| 10 | whatsapp |
A WhatsApp connection is in state connected | Optional · skippable |
| 11 | mobile |
A device registered or manual confirmation stored | Optional · skippable |
| 12 | test_lead |
test_lead_verified_at is set by the test run |
Required · skippable |
Why step 5 is skippable A Page with no lead forms yet must not lock a client out of the CRM forever. Skip settles the step as SKIPPED; the resolver auto-upgrades it to COMPLETED as soon as forms are actually selected.
The technical trace
- Definitions are frozen.
App\Support\OnboardingSteps::CLIENT_STEPS(plusINTERNAL_STEPSfor the Zodiac Tech checklist) is the single map of keys, labels, and required/skippable flags. Every consumer — resolver, wizard UI, SA dashboard, drawer, backfill, tests — reads this map; no step key is hard-coded elsewhere. - Seeding.
App\Services\GuidedOnboarding\OnboardingService::ensure()creates the header row (business_onboarding) and all step rows (business_onboarding_steps) for a workspace. - Resolution.
OnboardingStateResolver::clientStepStatus()computes each step's status + client-safe detail from real state (table above). Meta steps can return BLOCKED when the connection is in an error/needs-reauth state or the token expired. - Sync.
OnboardingService::sync()re-derives all client steps inside a transaction, persists statuses, and audits changes (guided_onboarding.step_status,guided_onboarding.completed). It sends the one-time setup complete notification to the internal team. - Progress + UI.
progress()is the floor of completed/total — the top-bar chip (App\Livewire\GuidedSetupChip, "Setup NN%") and the drawer render from it. The drawer shows a per-step icon: ✓ completed, ↷ skipped, ⚠ blocked, ● in progress, ○ not started. - Gating.
App\Http\Middleware\RedirectToOnboardingsends workspace owner/admins to/admin/guided-setupuntil the header row is COMPLETED (billing pages, profile, and the wizard itself are exempt). Members are never redirected. - Completion. When required steps are settled (completed or skipped), the header flips to COMPLETED; the wizard shows the completion screen and the chip disappears.
- Recovery nets.
- Backfill:
php artisan leadhub:guided-onboarding-syncseeds/repairs step rows for existing workspaces (e.g. after migrations or for workspaces created before the feature). - Stuck sweep:
DetectStuckOnboardingruns daily at 08:15 and flags steps that have been settled too long, so the SA team can reach out.
- Backfill:
- Super Admin visibility.
/super-admin/meta-ads/client-onboardinglists every workspace with progress, current step, payment state, Meta connection health, and a ⚠ stuck flag (24h+). Request Action sends the client an in-app + email prompt — and clients can be given signed 72-hour onboarding links (/guided-onboarding/{tenant}) that resume the wizard without a password.
Troubleshooting notes
| Symptom | Likely cause | Explanation |
|---|---|---|
| A completed step shows as unfinished again | The real condition stopped being true (e.g. Meta token expired → BLOCKED) | The resolver reflects reality; fix the underlying state |
| Skipped step never auto-completes | The real action never happened | Do it for real; sync picks it up |
| Progress % seems behind your click-through | Steps count only when their condition is verified, not when you click | Expected behaviour |
| Workspace owner stuck at the wizard with everything done | One required step is technically unsettled | Open the drawer; the unfinished step is marked |
| Steps missing entirely | Onboarding rows were never seeded (old workspace) | Run php artisan leadhub:guided-onboarding-sync |
Related guides
- Client onboarding from zero · Finish & go live
- Client onboarding dashboard · Client delivery playbook
- Queues, jobs & scheduler — the stuck-sweep and other scheduled jobs
Was this page helpful?
Thanks — noted. ✦