Files
atomic-design-poc/docs/backlog/WP-04-ui-not-infrastructure.md
Edwin van den Houdt 035e785c95 feat(boundaries): WP-04 — ui ↛ infrastructure + showcase sanction
Move the two wizard lookups behind application-layer facades so ui/ no longer
injects infrastructure adapters directly:
- RegistratieLookupStore (BRP address + DUO diplomas): owns the resources,
  runs the trust-boundary parse, exposes adresStatus/prefillAdres/duoLookup.
- IntakePolicyStore (scholing threshold): owns the policy resource, exposes
  the derived threshold.

Add the lint rule ui/ + layout/ ↛ **/infrastructure/** (@typescript-eslint
variant so it composes with the base direction rules; stories/specs exempted
as test scaffolding). Add the documented showcase sanction (may read every
context). Fix the docs' inventory: 6 contexts / 5 layers, +brief, +contracts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 21:01:42 +02:00

3.5 KiB

WP-04 — Boundaries II: ui ↛ infrastructure + showcase sanction

Status: done (pending commit) Phase: 0 — enforcement & gates

Why

The documented rule ui → application → domain (CLAUDE.md §1) is not lint-enforced, and three components inject infrastructure adapters directly. This is the biggest refactor of Phase 0 — a pure move of wiring, no behavior change.

Read first

  • CLAUDE.md §1, docs/ARCHITECTURE.md
  • eslint.config.mjs
  • src/app/registratie/ui/registratie-wizard/registratie-wizard.component.ts (lines ~18-19: BrpAdapter/parseBrpAddress, DuoAdapter/parseDuoLookup)
  • src/app/herregistratie/ui/intake-wizard/intake-wizard.component.ts (~line 28: IntakePolicyAdapter)
  • src/app/registratie/application/big-profile.store.ts (the facade pattern to copy)
  • src/app/showcase/ui/concepts.page.ts

Decisions (pre-made, don't relitigate)

  • Showcase is sanctioned, not fixed: showcase/ is a teaching page whose point is showing multiple contexts side by side. Add an explicit eslint override allowing @registratie/* / @herregistratie/* from src/app/showcase/**, with a message comment — same precedent as the existing debug-state exemption. Document in ARCHITECTURE.md: "showcase may read every context; nothing imports showcase."
  • Move wiring only — do not redesign adapter signatures. Existing machine specs are the safety net.

Files

  • eslint.config.mjs — forbid **/ui/** and **/layout/****/infrastructure/**; add the showcase sanction
  • src/app/registratie/ui/registratie-wizard/registratie-wizard.component.ts — BRP/DUO lookups move behind a registratie application/ facade (command or store methods)
  • src/app/herregistratie/ui/intake-wizard/intake-wizard.component.ts — policy resource moves behind new src/app/herregistratie/application/ (folder doesn't exist yet)
  • docs/ARCHITECTURE.md — fix "three contexts, four layers" → six contexts (shared, auth, registratie, herregistratie, brief, showcase), five layers (+ contracts); add the showcase sanction
  • CLAUDE.md §1 — add brief to the context list; note the showcase sanction

Steps

  1. Create the application-layer facades (pattern: big-profile.store.ts / submit-*.ts commands); components inject those instead of adapters.
  2. Add the eslint restriction; add the showcase override with rationale message.
  3. Fix any further hits lint finds (letter-composer's infra import is handled in WP-03; if it slipped, fix here).
  4. Update both docs' context/layer inventory.

Acceptance criteria

  • Rule active; lint green; no disables beyond the documented showcase + debug-state exemptions. (Probed: a ui→infra import errors.)
  • No **/ui/** file imports from **/infrastructure/** (production; stories/specs exempted — test scaffolding wires the real client).
  • Both wizards behave unchanged (178 specs pass; storybook a11y suite mounts both wizards green — behaviour is a pure wiring move behind root facades).
  • CLAUDE.md and ARCHITECTURE.md list 6 contexts / 5 layers.

Verification

GREEN + npm run test-storybook:ci. Manual smoke: npm start → run the registratie wizard (BRP prefill + DUO lookup steps) and the intake wizard end-to-end.

Out of scope

Redesigning the adapters or resource loading; parse boundaries (WP-05).

Risks

Resource wiring moving layers can subtly change injection timing — keep facades providedIn: 'root' like existing stores and hand the resource through unchanged.