Files
atomic-design-poc/docs/project/archive/backlog/WP-08-store-idiom.md
T
ehoandClaude Opus 5 12f17d9d73 docs: archive the finished backlogs (RD-30)
Two backlog trees are complete: `docs/project/backlog/` (75 files, every
WP done) and `docs/project/refactor-backlog-setup/` (the arc before it).
Move both under `docs/project/archive/` with `git mv`, so history stays
intact through `git log --follow`. `SHOWCASE-ROADMAP.md` moves with them,
because it points at the now-archived backlog README.

Add `docs/project/archive/README.md`. It states that these trees are
historical and names the two directories that are still live.

Repoint every inbound reference named in RD-30's Files table: CLAUDE.md,
the root README, both backend READMEs, `LetterHtml.cs`, `a11y.mdx`, the
`document-feature` and `new-ssp` skills, and the readable-codebase PLAN,
README, and RD-19 ticket. Fix two upward-relative links inside the moved
WP files (WP-68, WP-69) that gained a directory level and would otherwise
break. Repoint `.prettierignore`'s two agent-prompt exclusions to their
new path, so prettier keeps leaving those files' exact wording alone.

Mark RD-30 done and check off its acceptance criteria; flip its README
row to done.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 23:00:38 +02:00

4.1 KiB
Raw Blame History

WP-08 — One store idiom + machine naming + TEA MDX

Status: done Phase: 1 — FP/DDD core

Why

Docs (docs/reference/fp-tea-atomic-design.md, ARCHITECTURE §2c) teach createStore as THE wiring, but the wizard pages hand-wire signal(model) + local dispatch() — juniors see two idioms and copy the wrong one. Machine naming also drifts: change-request.machine.ts exports bare State/Msg; upload.machine.ts exports reduceUpload/initialUpload.

Read first

  • src/app/shared/application/store.ts (createStore) + its spec
  • docs/reference/fp-tea-atomic-design.md Part on TEA-in-Angular
  • All *.machine.ts files (6) and their UI wiring sites (wizard components/pages)

Decisions (pre-made, don't relitigate)

  • createStore is THE idiom — migrate the hand-wired pages to it. One shape everywhere is the teachability win; the migration is ~5 lines per page.
  • Naming convention (goes into CLAUDE.md §3):
    • State/Msg types are context-prefixed: ChangeRequestState, ChangeRequestMsg (rename the bare ones; other machines already comply).
    • A top-level machine exports initial + reduce.
    • A composable sub-machine (embedded in a parent model) keeps prefixed value exports: initialUpload/reduceUpload stay — prefixing avoids alias noise at the composition site.

Files

  • src/app/registratie/domain/change-request.machine.ts (+ spec + consumers) — rename
  • Wizard UI wiring: registratie-wizard.component.ts, intake-wizard.component.ts, herregistratie-wizard.component.ts (whichever hand-wire signal+dispatch) → createStore
  • CLAUDE.md §3 — the naming + wiring convention
  • New src/docs/machines.mdx — title Foundations/State Machines (TEA)

Steps

  1. Rename State/Msg in change-request (mechanical; lint/build finds consumers).
  2. Swap hand-wired model signals for createStore(initial, reduce) in the wizard components; templates keep dispatching messages — no template changes expected.
  3. Write the convention into CLAUDE.md §3 (including the sub-machine rule).
  4. MDX page: Model/Msg/reduce, commands-outside-reducers, createStore wiring, the naming rules — linking herregistratie.machine.ts as the worked example.

Acceptance criteria

  • grep -rn "export type State\b\|export type Msg\b" src/app → empty.
  • Every machine consumer wires via createStore; no local signal(model) + hand-rolled dispatch remains.
  • Convention documented in CLAUDE.md; MDX renders.
  • All machine specs pass unchanged (reducers untouched).

Verification

GREEN + npm run test-storybook:ci (197 unit / 137 Storybook, unchanged from WP-07 — this WP touched no reducer logic). Manual smoke via a running docker compose stack + Playwright: the change-request form (the renamed machine) submitted end-to-end with a referentie shown; the intake wizard stepped forward and back; the herregistratie wizard loaded its first step — no console errors across all three.

Deviation from the original plan

Step 2 (migrate wizard pages off hand-wired signal(model)+dispatch() onto createStore) turned out to already be done. registratie-wizard.component.ts, intake-wizard.component.ts, herregistratie-wizard.component.ts, and change-request-form.component.ts all already wire createStore<XState, XMsg>(initial, reduce) — confirmed both by reading each file and by git log -p on registratie-wizard.component.ts, which shows createStore present since the file's introduction. grep -rn "= signal<.*State>\|= signal(init" src/app (excluding specs) turns up nothing outside store.ts itself and brief.store.ts's two unrelated transient-state signals (WP-07). The WP's "Why" section was accurate for an earlier snapshot of the codebase but stale by the time this WP ran — only the change-request.machine.ts naming fix (Step 1) and the CLAUDE.md/MDX documentation (Steps 34) had real work left.

Out of scope

Changing reducer logic or messages; store specs for root stores (they're covered where logic exists).

Risks

Rename ripple — purely mechanical; reducer specs are the net.