Close the three remaining unvalidated `as <DomainType>` casts at the wire boundary (intake-policy, big-register aantekening type, brief passage scope), each replaced by a Result-returning parser with a rejection-case spec, plus the Foundations/Parse, don't validate curriculum page.
2.6 KiB
2.6 KiB
WP-05 — Parse-don't-validate closure + MDX
Status: done 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.mdsrc/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; addparseIntakePolicy(raw: unknown): Result<string, …>and a domain-side typesrc/app/registratie/infrastructure/big-register.adapter.ts(~line 25) —n.type as AantekeningType→ validated parsesrc/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, extendbig-register.adapter.spec.ts/brief.adapter.spec.ts(create if missing) - New
src/docs/parse-dont-validate.mdx— titleFoundations/Parse, don't validate
Steps
- For each hole: write the small parser (pattern:
parseAanvraagStatusinapplications.adapter.ts), wire it in, delete the cast. - Spec each parser: valid shape, missing field, unknown tag/enum value →
err. - 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 toPartial<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.