Files
atomic-design-poc/docs/backlog/WP-05-parse-boundaries.md
Edwin van den Houdt 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

2.6 KiB

WP-05 — Parse-don't-validate closure + MDX

Status: todo Phase: 1 — FP/DDD core

Why

Three adapters trust the wire, contradicting the repo's flagship "parse, don't validate" principle (every response through a hand-written parse* returning Result).

Read first

  • CLAUDE.md §3 + §4; docs/architecture/0001-bff-lite-decision-dtos.md
  • src/app/registratie/infrastructure/applications.adapter.ts (+ its spec — the pattern to copy)
  • The three offenders below

Decisions (pre-made, don't relitigate)

  • Unknown enum-ish values from the wire map to an explicit Failure (never a silent fallback); specs pin that behavior.
  • The MDX curriculum page ships in this WP (the WP that establishes an invariant teaches it).

Files

  • src/app/herregistratie/infrastructure/intake-policy.adapter.ts — returns the raw DTO resource with no parse; add parseIntakePolicy(raw: unknown): Result<string, …> and a domain-side type
  • src/app/registratie/infrastructure/big-register.adapter.ts (~line 25) — n.type as AantekeningType → validated parse
  • src/app/brief/infrastructure/brief.adapter.ts (~line 189) — dto.scope as PassageScope → validated parse (the file is otherwise parse-heavy; this one field skips)
  • New co-located specs: intake-policy.adapter.spec.ts, extend big-register.adapter.spec.ts / brief.adapter.spec.ts (create if missing)
  • New src/docs/parse-dont-validate.mdx — title Foundations/Parse, don't validate

Steps

  1. For each hole: write the small parser (pattern: parseAanvraagStatus in applications.adapter.ts), wire it in, delete the cast.
  2. Spec each parser: valid shape, missing field, unknown tag/enum value → err.
  3. MDX page: the principle, value objects (registratie/domain/value-objects/), boundary parsers, linking the three real call sites just fixed (before/after snippet).

Acceptance criteria

  • No unvalidated as <DomainType> casts in **/infrastructure/** (the sanctioned "narrow unknown to Partial<Dto> then parse" entry-cast is fine).
  • Each new parser has a spec including a rejection case.
  • MDX renders under Foundations in Storybook.

Verification

GREEN + npm run test-storybook:ci. Smoke: intake wizard still loads its policy (npm start → /intake).

Out of scope

Runtime validation on every endpoint (explicitly out of scope for the POC per CLAUDE.md); digid.adapter.ts (faked auth, sanctioned).

Risks

Seeded backend data containing values the new parsers reject → surfaces as Failure in the UI; check the backend seed while writing the parsers and align the accepted set.