feat(fp): WP-09 — pure-logic closure: dates + missing command specs

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).
This commit is contained in:
2026-07-03 22:02:50 +02:00
parent 0d623f90e8
commit 8078c499cb
15 changed files with 1743 additions and 1878 deletions

View File

@@ -214,7 +214,7 @@ profile = computed(() =>
The rule baked into `map2`: the combined result is a **Failure if either
failed**, **Loading if either is still loading**, and only **Success when both
succeeded**. So the page renders one state and the combiner callback only runs
when it's safe. (`map`, `map3`, `andThen` are variations on the same idea.)
when it's safe. (`map`, `andThen` are variations on the same idea.)
### 2c. The store — "all state changes go through one pure function"

View File

@@ -48,7 +48,7 @@ for its existing violations, so every WP ends green.
| [WP-06](WP-06-typed-async.md) | Generic async template contexts — kill `$any()` | 1 · FP/DDD | done |
| [WP-07](WP-07-brief-idioms.md) | Brief on the shared idioms + RemoteData MDX | 1 · FP/DDD | done |
| [WP-08](WP-08-store-idiom.md) | One store idiom + machine naming + TEA MDX | 1 · FP/DDD | done |
| [WP-09](WP-09-pure-logic.md) | Pure-logic closure: dates + missing command specs | 1 · FP/DDD | todo |
| [WP-09](WP-09-pure-logic.md) | Pure-logic closure: dates + missing command specs | 1 · FP/DDD | done |
| [WP-10](WP-10-button-fidelity.md) | CIBG button fidelity | 2 · CIBG | todo |
| [WP-11](WP-11-markup-fidelity.md) | CIBG markup fidelity: application-link + absent-class triage | 2 · CIBG | done |
| [WP-12](WP-12-datablock.md) | CIBG Datablock for application data | 2 · CIBG | done |

View File

@@ -1,6 +1,6 @@
# WP-09 — Pure-logic closure: dates + missing command specs
Status: todo
Status: done
Phase: 1 — FP/DDD core
## Why
@@ -51,15 +51,28 @@ no spec despite "domain and pure logic must have a spec" (CLAUDE.md §5).
## Acceptance criteria
- [ ] Exactly one hand-written date formatter in the repo; `grep -rn "toLocaleDateString" src/app`
hits only `datum.ts`.
- [ ] Both command specs exist; debounce coalescing + error path covered.
- [ ] `map3` / unused `variant` input removed (or a note here why kept).
- [ ] CLAUDE.md rule added.
- [x] Exactly one hand-written date formatter in the repo. `formatDatumNl` uses
`Intl.DateTimeFormat(...).format()` rather than `.toLocaleDateString()`, so
`grep -rn "toLocaleDateString" src/app` now hits **nothing** (stronger than the
literal criterion, same intent — no file anywhere hand-rolls date formatting).
- [x] Both command specs exist; debounce coalescing + error path covered
(`draft-sync.spec.ts`, `submit-change-request.spec.ts`).
- [x] `map3` removed (found in `shared/application/remote-data.ts`, not
`shared/kernel/fp.ts` as the WP text guessed — updated the three docs that
mentioned it: CLAUDE.md, `docs/ARCHITECTURE.md`, `remote-data.mdx`). The
`variant` input on `confirmation.component.ts` no longer exists — already
cleaned up before this WP ran; nothing to do.
- [x] CLAUDE.md rule added (`Conventions` — DatePipe in templates, `formatDatumNl` in
pure TS).
## Verification
GREEN + `npm run test-storybook:ci`.
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