Skip to content

feat: unify first-run activation, welcome, and onboarding flow#26

Merged
m0r6aN merged 1 commit intomainfrom
first-run_activation_and_onboarding
Apr 3, 2026
Merged

feat: unify first-run activation, welcome, and onboarding flow#26
m0r6aN merged 1 commit intomainfrom
first-run_activation_and_onboarding

Conversation

@m0r6aN
Copy link
Copy Markdown
Collaborator

@m0r6aN m0r6aN commented Apr 3, 2026

Summary

Unifies Keon Control’s first-run experience behind a single deterministic flow:

magic link -> /activate -> /welcome -> /setup -> app

This removes the previous parallel entry paths and establishes one source of truth for provisioning, onboarding completion, readiness, and next-route resolution.

What changed

  • Added a canonical first-run state owner in src/lib/first-run/state.tsx
  • Unified routing decisions around:
    • provisioningComplete
    • onboardingComplete
    • readyState
    • stage
    • nextRoute
  • Wired activation completion to hand off into the shared first-run state before redirecting to /welcome
  • Enforced stage gates:
    • provisioning incomplete -> /activate
    • provisioning complete but still at welcome -> /welcome
    • onboarding incomplete -> /setup
    • ready -> app shell
  • Gated shell-backed product routes behind AppReadyGate
  • Removed legacy bypass behavior from /, /get-started, and /onboarding
  • Removed duplicate activation-ready flag ownership in favor of the unified first-run state

User-facing outcome

A first-time user can no longer bypass onboarding or land directly in advanced product surfaces.

The enforced path is now:

  1. Arrive from magic link at /activate
  2. Complete provisioning
  3. Land on /welcome
  4. Start guided setup at /setup
  5. Reach ready state
  6. Enter the app shell

Why this matters

Before this change, activation, welcome, setup, and app entry existed as partially parallel surfaces. That allowed drift, conflicting readiness logic, and route shortcuts that could expose the app shell before the user was actually ready.

This change makes first-run entry deterministic and gives the product one clear authority for setup state.

Key files

  • src/lib/first-run/state.tsx
  • src/components/providers.tsx
  • src/components/onboarding/route-gates.tsx
  • src/components/activation/ActivationFlow.tsx
  • src/components/layout/shell.tsx
  • src/app/activate/page.tsx
  • src/app/welcome/page.tsx
  • src/app/setup/page.tsx
  • src/app/get-started/page.tsx
  • src/app/onboarding/page.tsx
  • tests/unit/first-run/state.test.ts

Testing

Attempted:

  • node .\node_modules\.pnpm\vitest@4.0.18_@types+node@20.19.33_jiti@1.21.7_jsdom@28.1.0\node_modules\vitest\vitest.mjs run tests/unit/first-run/state.test.ts tests/unit/onboarding/entry-routing.test.ts

Environment issue:

  • local Node runtime crashes in this environment with:
    • Assertion failed: ncrypto::CSPRNG(nullptr, 0)

So this PR includes test additions/updates, but I could not complete local execution from this shell.

Follow-up

Recommended hardening after this lands:

  • persist first-run truth in a more durable source for refresh/SSR consistency
  • add one golden-path e2e for /activate -> /welcome -> /setup -> app
  • validate back-button and refresh behavior across first-run stages

@m0r6aN m0r6aN merged commit 2130457 into main Apr 3, 2026
@m0r6aN m0r6aN deleted the first-run_activation_and_onboarding branch April 3, 2026 15:24
m0r6aN pushed a commit that referenced this pull request Apr 3, 2026
Implements the raw localStorage module tested in
tests/unit/activation/activation-flag.test.ts (present since PR #26).

Exports: ACTIVATION_COMPLETE_KEY, markActivationComplete,
isActivationComplete, clearActivationFlag.

Use useFirstRunState() in component code — this is the
storage layer beneath the first-run routing system.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant