Consolidate four hand-rolled nl-NL date formatters (tasks.ts, aanvraag- block, letter-preview, aanvraag-view -- one more than the WP found) into one shared/kernel/datum.ts::formatDatumNl, spec-pinned and empty-safe. Add the two missing command specs CLAUDE.md's testing rule calls for: draft-sync.spec.ts (debounce coalescing + trailing-call + submit Result shape, via fake timers) and submit-change-request.spec.ts. Remove the unused RemoteData.map3 (updating the three docs that mentioned it); the variant input on confirmation.component.ts was already gone. Documents both stale-WP-text corrections in the backlog file. This closes out backlog Phase 1 (FP/DDD core, WP-05..09).
4.1 KiB
WP-09 — Pure-logic closure: dates + missing command specs
Status: done Phase: 1 — FP/DDD core
Why
Three hand-rolled copies of the same nl-NL {day: numeric, month: long, year: numeric}
formatter exist with divergent signatures, while other components use the Angular date
pipe — two mechanisms plus drift risk. And two application commands with real logic have
no spec despite "domain and pure logic must have a spec" (CLAUDE.md §5).
Read first
src/app/registratie/domain/tasks.ts(~line 15,formatNL(d: Date))src/app/registratie/ui/aanvraag-block/aanvraag-block.component.ts(~line 96,formatNL(iso?: string))src/app/brief/ui/letter-preview/letter-preview.component.ts(~line 96, inline copy)src/app/registratie/application/draft-sync.ts(debounce logic)src/app/registratie/application/submit-change-request.tssrc/app/app.config.ts(LOCALE_IDnlis already set)
Decisions (pre-made, don't relitigate)
- Templates use
DatePipe; pure TS uses oneformatDatumNlinsrc/app/shared/kernel/datum.ts(Intl.DateTimeFormat, accepts ISO string | Date, empty-safe). Rule goes into CLAUDE.md conventions. - Kernel naming is Dutch (
datum.ts) — it formats for the Dutch UI; if that clashes with the "shared = English" rule during implementation,format-date-nl.tsis the alternative — pick one and note it here.
Files
- New
src/app/shared/kernel/datum.ts+datum.spec.ts - The three formatter copies (delete, redirect to pipe or kernel fn)
- New
src/app/registratie/application/draft-sync.spec.ts - New
src/app/registratie/application/submit-change-request.spec.ts CLAUDE.mdconventions (one line: DatePipe in templates,formatDatumNlin pure TS)
Steps
- Write
formatDatumNl+ spec (pin exact expected strings, e.g.2 juli 2026; undefined/empty →''). - Replace the three copies; templates that can use the pipe use the pipe.
draft-sync.spec.tswith vitest fake timers: coalescing (n rapid changes → 1 sync), trailing call, flush-on-submit if applicable.submit-change-request.spec.ts: ok path, error path (stubbed client), Result shape.- Also sweep the tiny dead exports flagged in the audit: remove unused
map3fromshared/kernel/fp.ts(verify unused first) and the never-setvariantinput onconfirmation.component.ts.
Acceptance criteria
- Exactly one hand-written date formatter in the repo.
formatDatumNlusesIntl.DateTimeFormat(...).format()rather than.toLocaleDateString(), sogrep -rn "toLocaleDateString" src/appnow hits nothing (stronger than the literal criterion, same intent — no file anywhere hand-rolls date formatting). - Both command specs exist; debounce coalescing + error path covered
(
draft-sync.spec.ts,submit-change-request.spec.ts). map3removed (found inshared/application/remote-data.ts, notshared/kernel/fp.tsas the WP text guessed — updated the three docs that mentioned it: CLAUDE.md,docs/ARCHITECTURE.md,remote-data.mdx). Thevariantinput onconfirmation.component.tsno longer exists — already cleaned up before this WP ran; nothing to do.- CLAUDE.md rule added (
Conventions— DatePipe in templates,formatDatumNlin pure TS).
Verification
GREEN + npm run test-storybook:ci (208 unit tests, up from WP-08's 201 by the 7 new
specs; 137 Storybook/a11y unchanged). Manual smoke via a running docker compose stack +
Playwright: dashboard's herregistratie-deadline task text ("Verleng uw registratie vóór 1
maart 2027"), the Concept aanvraag-block's complete-before text ("Rond de aanvraag af
vóór 2 augustus 2026"), and formatDatumNl unit specs for the letter-preview's today —
all render the expected long-form Dutch date, no console errors.
Out of scope
Result combinators (map/andThen/fold) — nice-to-have from the old roadmap, not in this
backlog.
Risks
Node ICU vs browser locale output differences — the spec pins strings; if CI's Node lacks
full ICU (it shouldn't on Node 24), pin via Intl.DateTimeFormat('nl-NL', …) explicitly.