Files
atomic-design-poc/docs/backlog/WP-05-parse-boundaries.md
Edwin van den Houdt f769242f76 docs: replace SHOWCASE-ROADMAP.md with docs/backlog/ (17 WPs)
Turns the prior roadmap sketch into ordered, gated work packages (enforcement
gates, FP/DDD consistency, CIBG fidelity, Storybook curriculum, a11y) from the
2026-07-02 showcase-hardening audit.
2026-07-02 17:07:59 +02:00

67 lines
2.6 KiB
Markdown

# 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.