10 Commits

Author SHA1 Message Date
556f2f47bf feat(fp): WP-22 — durable persistence (SQLite/EF Core)
Applications, documents (+ audit log) and the brief move off static in-memory
Dictionaries onto a real SQLite file via EF Core, so demo data survives a
process restart or `docker compose restart api` for the first time. The three
stores (ApplicationStore/DocumentStore/BriefStore) keep their exact public
signatures and static-class shape — no DI, no async ripple into Program.cs's
minimal-API handlers — each method just opens a short-lived AppDbContext via
Db.Create() under the same lock it already had. Opaque nested shapes (a
wizard's draft snapshot, a brief's sections/placeholders/status) are stored as
JSON text columns rather than redesigned into relational tables, matching the
existing "don't interpret it" posture.

Found two things the WP's own text got wrong, corrected in
docs/backlog/WP-22-durable-persistence.md's Deviations section: SeedData never
seeded these three stores (only the read-only BRP/DUO-mimicking GETs, which
stay in-memory) so there's no seed step; and no new docker-compose volume is
needed since the existing bind mount already covers the SQLite file — verified
against this environment's real podman-backed compose stack, not just by
reading the file.

Also: pinned SQLitePCLRaw.bundle_e_sqlite3 to 3.0.3 (EF Core Sqlite's own
transitive default bundles a pre-3.50.2 SQLite with a known high-severity
memory-corruption advisory); found and fixed a real xUnit test race where
concurrent test-class hosts stomped a shared static connection-string field,
fixed by disabling cross-class test parallelization rather than adding DI the
stores don't otherwise need.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-05 10:19:23 +02:00
e276629107 feat(fp): WP-20 — second locale proof (nl/en build seam)
angular.json gains an i18n block (sourceLocale nl, en translation file) and
an `en` build/serve configuration with i18nMissingTranslation: "error" so a
new $localize string without an English unit fails the build, not silently
falls back. CI now runs `ng build --localize` to build both locales every
run. Verified end-to-end, not just "the build succeeded": the nl bundle
ships "Inloggen met DigiD", the en bundle ships "Log in with DigiD".

Incidental: prettier/compodoc regen noise in docs/wcag-checklist.md,
src/docs/a11y.mdx, documentation.json from the same working session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 18:16:11 +02:00
26c2c5acd0 feat(fp): WP-19 — Playwright e2e smoke against the real FE+backend
Adds a happy-path spec (login → dashboard → registratie wizard, including
a real identity-document upload → real submit) and a degraded-path spec
(?scenario=error → <app-async> error slot → retry), both driving the real
app against the real .NET backend, plus a CI job that boots both.

Writing the retry spec surfaced a real bug: AsyncComponent's retry() only
reloads a [resource]-fed instance, so every real page (all [data]-fed via
a store's RemoteData) had a silently no-op retry button. Added a
retryClicked output and wired it on the dashboard's two async blocks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 10:13:40 +02:00
e82309786d style: format frontend, docs and skills with prettier; add .prettierignore
One-time prettier --write so the new format:check CI gate starts green.
.prettierignore excludes generated (api-client.ts, documentation.json),
vendored (public/cibg-huisstijl), and backend (dotnet format owns it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:39:31 +02:00
922f9ec8cf docs: README + Storybook mdx describe the CIBG Huisstijl setup
Replace stale @rijkshuisstijl-community package/theming claims with the
vendored CIBG Huisstijl + token-bridge reality (ADR-0003); system-font
stack instead of Fira Sans; embed the now-existing document-upload story
in atomic-design.mdx.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 10:44:00 +02:00
d08f3877f7 Architect-review remediation: enforce conventions, prod-safe tooling, one form idiom, resilience seams
Acts on the showcase review. Four workstreams; all tests green
(npm run lint, 70 FE tests, ng build, 33 backend tests).

Enforcement + CI:
- eslint.config.mjs bans `any` and enforces layer/context boundaries
  (domain ≠ Angular; herregistratie → registratie → shared, auth → shared);
  `npm run lint` added; ajv 6 scoped to ESLint via nested override.
- .github/workflows/ci.yml: FE lint+check:tokens+test+build, backend dotnet test,
  and an API-client drift check.

One form idiom (the headline finding):
- change-request-form converged onto the wizard pattern — change-request.machine.ts
  (Model/Msg/reduce + value objects) + submit-change-request.ts (Result) + a real
  POST /api/v1/change-requests (server re-validates). Spec + story added; the detail
  page no longer holds an ad-hoc success signal.

Resilience/observability seam:
- api-client.provider.ts: request timeout, X-Correlation-Id, Idempotency-Key for
  writes; comments naming the retry/auth seams.
- Backend logs correlation id + a no-PII submit-audit line; /api/v1 prefix +
  backward-compat note; client regenerated.

Quick wins:
- Dev tooling excluded from prod: scenario.interceptor wired only under isDevMode()
  (?scenario= inert in prod); debug panel @if(isDev) (tree-shaken out).
- src/environments + apiBaseUrl into provideApiClient (angular.json fileReplacements).
- Backend /health + /health/ready.
- Debug view PII-minimised (redactProfile: name/address/DOB redacted, BIG masked).
- IntakePolicyAdapter (removes inline resource in the intake wizard).
- README de-staled; CLAUDE.md gains EN/NL + forms-one-idiom + lint/CI notes.
- Stories: text-input, link, data-row, site-header, site-footer, change-request-form.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 08:25:51 +02:00
7463efdc2d Add branching intake wizard (derived steps + radio-group atom)
A second wizard demonstrating a BRANCHING flow: the visible steps are derived
from the answers by a pure `visibleSteps` function rather than stored, so
answering "buiten Nederland gewerkt? -> ja" or reporting few hours adds steps
and the progress denominator changes live. Same Elm-style store + RemoteData
patterns as the fixed wizard; answers persist to localStorage.

- intake.machine.ts: IntakeState union + Answers + visibleSteps + pure reduce (+spec)
- intake-wizard organism, intake.page, submit-intake command
- new radio-group atom (ControlValueAccessor) in shared/ui
- /intake route + dashboard link + concepts showcase section
- tighten Aantekening.type to a 'Specialisme' | 'Aantekening' union
- README + ARCHITECTURE updated

Verified live end-to-end (branches add steps 4->5->6, review, submit) with no
console errors; build, unit tests, and Storybook all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 09:38:26 +02:00
Claude
4e14152758 Content-only page transitions + dependency security overrides
- Persistent ShellComponent hosts the router-outlet so header/footer mount once
  (no re-mount flash); pages nest under a shell route. page-shell is now
  content-only; page-layout removed.
- Native withViewTransitions() cross-fades only the routed content (chrome gets
  stable view-transition-names); respects prefers-reduced-motion.
- package.json overrides pin patched transitive dev/build deps: npm audit 16
  (3 high/9 mod/4 low) -> 5 low; shipped app stays at 0 (npm audit --omit=dev).
  No Angular downgrade, no breaking Babel 8 bump. jsdom 28 -> 29.
- README: page-transitions section + honest dependency-security note.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 15:46:42 +02:00
Claude
f1f4f982a6 Full-width layout, page-shell template, httpResource async states, README
- Fix full-bleed header/footer (align-items:stretch + block hosts; centered
  content column via shared --app-content-max).
- New templates/page-shell (back-link + heading + intro + content, narrow mode);
  all pages refactored to compose it.
- Async state management with native httpResource + <app-async> wrapper that
  renders exactly one of loading/empty/error/loaded (impossible states
  unrepresentable); delayed spinner + skeleton atoms for slow/fast connections.
- Scenario interceptor (?scenario=slow|loading|empty|error) to demo every state.
- Storybook: spinner/skeleton/page-shell/async-states stories.
- README rewritten as a guide (atomic design, reuse benefits, state handling).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 14:53:28 +02:00
Claude
033d6f0317 Atomic-design POC: BIG-register self-service portal (Angular + Rijkshuisstijl)
Atoms/molecules/organisms/templates/pages composing the NL Design System
(Utrecht) CSS themed Rijkshuisstijl via @rijkshuisstijl-community tokens.
Login -> dashboard -> registration detail, mock JSON over HttpClient, Storybook
organized by atomic layer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 14:23:11 +02:00