WIZ-1 Onboarding state table + /onboarding/should-redirect trigger #672

Closed
opened 2026-05-01 19:26:17 +00:00 by claude-desktop · 1 comment
Collaborator

User story

As a platform engineer, I want the setup table, /onboarding/state endpoints, and the dashboard-level redirect logic, so that a fresh deploy lands the operator on the wizard automatically after their first OAuth login.

Acceptance criteria

Schema

  • New migration adds setup table:
    CREATE TABLE setup (
      id                INTEGER PRIMARY KEY CHECK (id = 1),
      wizard_started_at INTEGER,
      wizard_completed_at INTEGER,
      current_step      TEXT,
      selected_repos    TEXT,                 -- JSON array
      agent_type_renames TEXT,                -- JSON map
      detected_stacks   TEXT,                 -- JSON map
      starter_pack_choices TEXT               -- JSON shape mirroring catalog
    );
    

Endpoints

  • GET /onboarding/state returns the row (or default-shaped object on first access).
  • PATCH /onboarding/state body { ...partial } upserts fields. Operator-auth-gated.
  • POST /onboarding/skip sets claude-hooks/wizard-skipped cookie (90 d), returns 204.
  • POST /onboarding/reset (admin-only) clears the row + cookie + wizard_completed_at. Hidden under admin route.
  • GET /onboarding/should-redirect returns { redirect: bool } based on the trigger logic in the spec.

Trigger

  • The SPA bootstrap (apps/web/src/main.tsx or app-shell init) fetches /onboarding/should-redirect once on first dashboard load. When redirect: true, navigate to /onboarding.
  • Logic: session present AND agents_count === 0 AND secrets_count === 0 AND wizard_completed_at === null AND skip-cookie absent → redirect.
  • /onboarding is NOT session-gate-exempt — runs after OAuth.

Tests

  • Unit: /onboarding/should-redirect returns the right decision across boundary states (authed empty vs authed populated vs unauth).
  • Integration: empty DB + missing skip cookie + active session → bootstrap redirects.
  • Integration: post-Apply (wizard_completed_at set) → redirect off.

Out of scope

  • Wizard screens (WIZ-2..WIZ-7).

References

  • specs/first-login-wizard.md §Story WIZ-1
  • apps/server/src/infrastructure/database/migrations/
  • apps/web/src/main.tsx
## User story As a platform engineer, I want the `setup` table, `/onboarding/state` endpoints, and the dashboard-level redirect logic, so that a fresh deploy lands the operator on the wizard automatically after their first OAuth login. ## Acceptance criteria ### Schema - [ ] New migration adds `setup` table: ```sql CREATE TABLE setup ( id INTEGER PRIMARY KEY CHECK (id = 1), wizard_started_at INTEGER, wizard_completed_at INTEGER, current_step TEXT, selected_repos TEXT, -- JSON array agent_type_renames TEXT, -- JSON map detected_stacks TEXT, -- JSON map starter_pack_choices TEXT -- JSON shape mirroring catalog ); ``` ### Endpoints - [ ] `GET /onboarding/state` returns the row (or default-shaped object on first access). - [ ] `PATCH /onboarding/state` body `{ ...partial }` upserts fields. Operator-auth-gated. - [ ] `POST /onboarding/skip` sets `claude-hooks/wizard-skipped` cookie (90 d), returns 204. - [ ] `POST /onboarding/reset` (admin-only) clears the row + cookie + `wizard_completed_at`. Hidden under admin route. - [ ] `GET /onboarding/should-redirect` returns `{ redirect: bool }` based on the trigger logic in the spec. ### Trigger - [ ] The SPA bootstrap (`apps/web/src/main.tsx` or app-shell init) fetches `/onboarding/should-redirect` once on first dashboard load. When `redirect: true`, navigate to `/onboarding`. - [ ] Logic: `session present` AND `agents_count === 0` AND `secrets_count === 0` AND `wizard_completed_at === null` AND skip-cookie absent → redirect. - [ ] `/onboarding` is **NOT** session-gate-exempt — runs after OAuth. ### Tests - [ ] Unit: `/onboarding/should-redirect` returns the right decision across boundary states (authed empty vs authed populated vs unauth). - [ ] Integration: empty DB + missing skip cookie + active session → bootstrap redirects. - [ ] Integration: post-Apply (`wizard_completed_at` set) → redirect off. ## Out of scope - Wizard screens (WIZ-2..WIZ-7). ## References - `specs/first-login-wizard.md` §Story WIZ-1 - `apps/server/src/infrastructure/database/migrations/` - `apps/web/src/main.tsx`
Collaborator

🤖 Auto-assigned to boss (heuristic: area:agents → boss (architecture-touching)). Reply /unassign to reroute.

🤖 Auto-assigned to **boss** (heuristic: area:agents → boss (architecture-touching)). Reply `/unassign` to reroute.
Sign in to join this conversation.
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
charles/claude-hooks#672
No description provided.