# WP-07 — Brief on the shared idioms + RemoteData MDX Status: todo Phase: 1 — FP/DDD core Depends on: WP-06 (typed ``) ## Why The brief context drifted from the repo's own reflexes: `brief.store.ts` (~lines 22-25) holds `busy: signal` + `lastError: signal` + a separate `saveState` union side by side — representable illegal combos, the exact "second boolean" smell CLAUDE.md §3 bans. And `brief.page.ts` hand-renders its load lifecycle with `@switch` + spinner/alert instead of `RemoteData` + `` — the only async flow in the app bypassing the shared molecule. ## Read first - `CLAUDE.md` §3; `src/app/shared/application/remote-data.ts` - `src/app/brief/application/brief.store.ts`, `src/app/brief/ui/brief.page.ts`, `src/app/brief/domain/brief.machine.ts` (+ spec) - `src/app/registratie/application/applications.store.ts` (a store doing it right) ## Decisions (pre-made, don't relitigate) - Transient submit/save state becomes **one** tagged union (`Idle | Busy | Failed{error}`), replacing `busy`+`lastError`. `saveState` keeps its union shape (align tag style). - Load lifecycle → `RemoteData` + ``; the machine keeps owning the letter's _domain_ lifecycle (loading tags move out of the machine only if they purely mirror the fetch — keep the seam: RemoteData = fetch, machine = letter). - Keep the debounced-save sequencing identical; only re-type the state. ## Files - `src/app/brief/application/brief.store.ts` - `src/app/brief/ui/brief.page.ts` - `src/app/brief/domain/brief.machine.ts` + `brief.machine.spec.ts` - New `src/docs/remote-data.mdx` — title `Foundations/RemoteData & Async` ## Steps 1. Replace the signal trio with one union signal; update consumers (letter-composer bar, autosave status line). 2. Route the page's load through `RemoteData` + `` (typed via WP-06); wire the existing loading/empty/failure templates. 3. Update machine/store specs for the union transitions. 4. MDX page: the four states, `map2`/`andThen`, the delay-gated spinner, and the `?scenario=` dev toggle — linking `brief.page.ts` and `dashboard.page.ts` as live examples. ## Acceptance criteria - [ ] No boolean-plus-error signal pairs in `brief/`. - [ ] `/brief` renders all four async states (check with `?scenario=slow|empty|error`). - [ ] Specs cover the transition union (Busy→Failed, Busy→Idle). - [ ] MDX renders under Foundations. ## Verification GREEN + `npm run test-storybook:ci`. Manual: `npm start` → `/brief` with `?scenario=slow`, `?scenario=error`; exercise autosave + submit + rejection flow. ## Out of scope Brief component stories (WP-15); machine renaming conventions (WP-08). ## Risks Autosave (debounced) interplay with the new transition union — flush ordering must stay as-is; the machine spec pins it.