First-run setup wizard: UI #81

Closed
opened 2026-07-04 14:52:43 +02:00 by fable-5 · 1 comment
Collaborator

Context

The friendly face of self-hosting: a guided, localized first-run experience.

Scope

Wizard flow at /setup: welcome + language choice, admin account, instance basics, SMTP (with test button and skip option), registration mode, summary + finish → redirect to login; progress indication, back navigation, validation per step; the rest of the SPA shows a 'setup pending' screen while unconfigured.

Acceptance criteria

  • complete wizard run on a fresh dev stack ends logged-in-ready (e2e)
  • every step validates before advancing; back preserves entries
  • works fully in de and en, chosen on the first screen

Technical notes

  • ADR 0012.

Dependencies

Depends on #80.

Size: ~1 day


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context The friendly face of self-hosting: a guided, localized first-run experience. ## Scope Wizard flow at `/setup`: welcome + language choice, admin account, instance basics, SMTP (with test button and skip option), registration mode, summary + finish → redirect to login; progress indication, back navigation, validation per step; the rest of the SPA shows a 'setup pending' screen while unconfigured. ## Acceptance criteria - [ ] complete wizard run on a fresh dev stack ends logged-in-ready (e2e) - [ ] every step validates before advancing; back preserves entries - [ ] works fully in de and en, chosen on the first screen ## Technical notes - ADR 0012. ## Dependencies Depends on #80. **Size**: ~1 day --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M8 — Self-hosting & operations milestone 2026-07-04 14:52:43 +02:00
fable-5 added the
frontend
label 2026-07-04 14:52:43 +02:00
Author
Collaborator

Implemented in 28aa04d — pipeline fully green (8 contexts), wizard verified end-to-end in a real browser against a fresh stack.

Setup gate: the SPA probes GET /setup on boot. While setup is pending it renders only the wizard at /setup, the login page (to resume a wizard someone already started, via a sign-in hand-off with ?next=/setup), and a localized “setup pending” screen on every other route — without the regular chrome, whose pond/search queries would all answer 503. If the probe itself fails (offline reload, #38) the app falls through to the normal routes; once completed, /setup permanently redirects home.

Wizard flow (6 steps, progress indicator + back navigation): welcome with language choice (switches i18n immediately and pre-fills the admin/instance locales) → Site Admin account (step‑1 session cookie signs the admin in) → instance name/default locale → SMTP with the live test-before-save from #80 plus an explicit skip (the transport error shows verbatim under the translated banner) → registration mode → summary + finish. Every step validates through the shared Zod schemas before advancing; entered values are held in the parent component, so Back preserves them, and re-submitting a step is a safe overwrite. New setup i18n namespace in de and en (i18n:check green).

e2e (AC): apps/web/e2e/setup.spec.ts needs an instance where setup is still pending, so the auth-e2e CI job now provisions a second api + static web against a virgin database on ports 3005/5175 (SMTP env forced empty so it boots unconfigured) and runs the full journey there: pending screen → German first, then English (both languages carry the wizard) → validation blocks empty admin submit → Back preserves the instance name → dead relay blocks the SMTP step, Mailpit lets it pass → finish lands on / signed in as the created admin → /setup afterwards just goes home.

Two #80 touch-ups found while verifying: GET /setup’s smtpConfigured used ??, so the empty strings compose passes for unset vars never fell through to the secret store — now || (the loadApiEnv convention); and the SMTP port’s NaN case now maps to the translated required-field message.

Implemented in 28aa04d — pipeline fully green (8 contexts), wizard verified end-to-end in a real browser against a fresh stack. **Setup gate:** the SPA probes `GET /setup` on boot. While setup is pending it renders only the wizard at `/setup`, the login page (to resume a wizard someone already started, via a sign-in hand-off with `?next=/setup`), and a localized “setup pending” screen on every other route — without the regular chrome, whose pond/search queries would all answer 503. If the probe itself fails (offline reload, #38) the app falls through to the normal routes; once completed, `/setup` permanently redirects home. **Wizard flow** (6 steps, progress indicator + back navigation): welcome with language choice (switches i18n immediately and pre-fills the admin/instance locales) → Site Admin account (step‑1 session cookie signs the admin in) → instance name/default locale → SMTP with the live test-before-save from #80 plus an explicit skip (the transport error shows verbatim under the translated banner) → registration mode → summary + finish. Every step validates through the shared Zod schemas before advancing; entered values are held in the parent component, so Back preserves them, and re-submitting a step is a safe overwrite. New `setup` i18n namespace in de **and** en (`i18n:check` green). **e2e (AC):** `apps/web/e2e/setup.spec.ts` needs an instance where setup is still pending, so the auth-e2e CI job now provisions a second api + static web against a virgin database on ports 3005/5175 (SMTP env forced empty so it boots unconfigured) and runs the full journey there: pending screen → German first, then English (both languages carry the wizard) → validation blocks empty admin submit → Back preserves the instance name → dead relay blocks the SMTP step, Mailpit lets it pass → finish lands on `/` signed in as the created admin → `/setup` afterwards just goes home. **Two #80 touch-ups** found while verifying: `GET /setup`’s `smtpConfigured` used `??`, so the empty strings compose passes for unset vars never fell through to the secret store — now `||` (the loadApiEnv convention); and the SMTP port’s NaN case now maps to the translated required-field message.
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#81
No description provided.