Commit Graph

7 Commits

Author SHA1 Message Date
6257d7ede3 feat(design): adopt CIBG component patterns (header, forms, wizards, dashboard)
Re-skins the app's layout on top of the CIBG Huisstijl theme (previous commit) so it
matches designsystem.cibg.nl, not just its colour tokens — magenta ("robijn") header,
horizontal nav, and the CIBG component markup for forms/wizards/dashboard.

- Header: logo block + robijn titlebar (breadcrumb + user menu) + grey horizontal nav
  (4 links) replacing the dashboard side-nav; breadcrumb restyled for the titlebar
  (no background of its own — CIBG's global `header nav` rule otherwise bleeds a grey
  fill into it, fixed by scoping an override inside BreadcrumbComponent).
- Forms: form-field/radio-group/checkbox rebuilt on CIBG's horizontal `form-group row`
  / `form-check.styled` markup (label col-md-4, control col-md-8); same input() APIs.
- Wizards: stepper rebuilt as the CIBG "stappenindicator" (numbered circles, visited
  steps clickable for back-nav, title merged in); wizard-shell adopts the CIBG
  procesnavigatie button row. Back-navigation wired into all three wizard machines
  (registratie-wizard already had it; added `GaNaarStap` to intake/herregistratie
  machines, pure + spec'd).
- New shared/ui molecules: confirmation (animated bevestiging checkmark, replaces
  plain alerts on submit), review-section (controlestap sections with "Wijzigen"),
  application-list/application-link (CIBG "aanvragen" rows, replace the dashboard's
  card grid and aanvraag-block).
- Cleanup: delete side-nav and now-unused styles.scss utilities (.app-overview,
  .app-form-panel, .app-card-grid); correct design-tokens.mdx (it referenced tokens
  that no longer exist) and document the CIBG-value token bridge.

Verified: build/lint/check:tokens green, 178 tests pass (4 new GaNaarStap cases), and
manually driven end-to-end (dashboard, a full herregistratie submission through to the
confirmation screen, mobile width, keyboard focus).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 14:33:05 +02:00
9c2a80451f Step 3 (production-readiness): PII storage, validated reads, seams
Implement-now:
- G1: keep PII out of persistent storage — never persist BSN (only `naam`);
  move both wizard drafts (address/email, work data) localStorage → sessionStorage
  so they clear on tab close.
- G2: validate storage reads before trusting the cast — shape/tag guard in every
  restore() (mirrors the parse* HTTP boundary); corrupt/foreign shape → start fresh.
- G3: already satisfied (debug-state redacts via mask.ts).

Show-the-seam (hook + doc, not fully built):
- G4: problemFieldErrors() maps a server validation envelope (ASP.NET
  ValidationProblemDetails `errors`) to the field-keyed map the wizards already
  render; returns {} until the backend sends it. +spec.
- G5: documented the retry/backoff seam at the adapter GET loader; reads may
  retry, mutating submits never do.

Out of scope (named): unsaved-changes warning (persistence prevents data loss),
real auth/tokens, axe-core in CI.

Gate green: lint, check:tokens, build, test 79/79.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 14:07:10 +02:00
474c040410 Step 2 (i18n): $localize sweep + JA_NEE dedup (M3, M4)
Wrap every user-facing Dutch string in Angular's first-party i18n — `i18n`/
`i18n-<attr>` in templates, `$localize` in TS (value-objects, machines, commands,
label constants, shared-component defaults). Source locale stays nl; a second
locale is now a translation file, not a code change.

- M3: ~145 strings localized with stable @@ ids across registratie,
  herregistratie, auth, shared/ui, shared/layout. Skipped: showcase, debug-state,
  scenario interceptor, generated client, specs/stories, raw status enum tags,
  internal parse* diagnostics.
- M4: single shared JA_NEE (localized labels) in radio-group; both wizard copies
  removed.

Gate green: lint, check:tokens, build, test 77/77.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 14:00:10 +02:00
7a582ae2fa Rijkshuisstijl restyle + wizard fixes
Chrome: two-tier Rijksoverheid header (white brand bar + lint-blue
breadcrumb bar, route-driven), dark multi-column footer, white page
surface. Session shown via a shared SESSION_PORT token (keeps shared/
free of the auth context).

Overview ("Mijn overzicht") rebuilt to the NL Design System #392 pattern:
side-nav + "Wat moet ik regelen" task list (derived) + "Mijn registratie"
cards. New shared components: card, task-list, side-nav; pure
tasksFromProfile (+spec).

Wizards: grey form panel, connected numbered stepper, form-field
"(verplicht)" markers + styled description/error, full-width inputs.
Propagated to login, detail, change-request, address-fields.

Bug fixes:
- wizard-shell: add FormsModule so NgForm intercepts submit (wizards now
  advance; no native GET leaking choices into the URL).
- wizard-shell: error-summary links focus the field instead of navigating
  (a fragment href resolved against <base href="/"> reloaded to "/" and
  bounced to login).
- wizard-shell: error-summary focus only on the rising edge, so typing
  while errors are shown no longer scrolls the page up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 13:21:54 +02:00
64385999eb Add registratie wizard, BFF dashboard-view, contracts/value-objects, and architecture docs
Checkpoint of in-progress work: the registration wizard (address prefill,
DUO diploma lookup, policy questions), decision-DTO contracts, parse-don't-
validate value objects, infrastructure adapters, plus CLAUDE.md and the
architecture/ADR docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:23:52 +02:00
6086729563 Fix login output name collision and herregistratie demo eligibility
Walking through the running app surfaced two issues:

- login-form's `submit` output collided with the native DOM `submit` event
  bubbling to <app-login-form>, so login() also fired with an Event (not the
  BSN string) — "bsn.trim is not a function". Renamed the output to `submitted`
  (matching the other forms).
- The static mock herregistratie deadline (2027-09-01) sat outside the 12-month
  eligibility window, so the wizard was correctly hidden. Moved it to 2027-03-01
  so "verloopt binnenkort" is true and the flow is demoable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 07:38:06 +02:00
2114514ad7 Restructure into DDD bounded contexts + functional state management
Reorganise from atomic-design-only folders into bounded contexts
(auth / registratie / herregistratie) over a shared kernel, each split into
domain / application / infrastructure / ui layers. Dependencies point inward;
the domain layer is framework-free. Path aliases (@shared/@auth/@registratie/
@herregistratie) make import direction explicit.

State management (Elm-style, native TS, no new deps):
- shared/application/store.ts — createStore(init, update): pure reducer + signal
- shared/application/remote-data.ts — add map/map2/map3/andThen combinators so
  several services fold into one RemoteData; <app-async> gains an [rd] input
- registratie/application/big-profile.store.ts — root singleton combining the
  BIG-register and BRP services via map2 into one state; holds the optimistic
  herregistratie flag shared with the dashboard
- herregistratie: machine gains a WizardMsg union + pure reduce; submit is a
  command that calls infra and dispatches the result, with optimistic update +
  rollback against the shared store
- auth: SessionStore + DigiD adapter + functional route guard; login establishes
  the session, protected routes use canActivate

Rich domain: registration.policy.ts (statusColor/label, herregistratie
eligibility, invariants); BigNummer/Postcode/Uren value objects with smart
constructors. status-badge is now domain-free (colour/label inputs).

Specs for the reducer, RemoteData combinators, and eligibility policy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 07:20:13 +02:00