Files
atomic-design-poc/docs/project/readable-codebase/RD-09-docs-effect-idiom.md
T
ehoandClaude Sonnet 5 d15943bb36 docs: teach the effect map, not the deleted submit method (RD-09)
RD-05 through RD-08 replaced the hand-called submit method with
createStore's effect map. Two teaching documents still showed the old
method in a code block, as the answer to "how does a submit happen?".
Both blocks also called a function that no longer exists.

Rewrite the code block in ARCHITECTURE.md section 2d and its
fp-tea-atomic-design.md counterpart. Both now show the effect map, keyed
on the Submitting tag, using the same herregistratie worked example with
its optimistic begin/confirm/rollback calls. Both use draftSync.submit,
the call the two herregistratie wizards make today.

State the two properties the old idiom lacked, since they are the reason
for the change: entering a state runs its effect, so a dispatch cannot
skip it; and double-submit protection is structural, because the effect
fires only on a tag transition. Add one sentence on the Seed exemption: a
mount or restore message must not trigger a submit.

Fix the one runIfSubmitting() hop in the write walkthrough at
ARCHITECTURE.md's line 574. The rest of section 6a stays stale on
purpose — RD-31 owns it, including its line citations and dead paths.
fp-tea-atomic-design.md's broken pre-monorepo paths stay stale too —
RD-32 owns those.

Set RD-09's Status to done and its README row to done in the same
commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 17:26:52 +02:00

5.8 KiB

RD-09 — Update the two documents that teach the deleted submit idiom

Status: done Source: PLAN.md 1c (A5, as corrected)

Why

RD-05 through RD-08 replaced the hand-called runIfSubmitting with createStore's effect map, and grep now finds the method nowhere in apps/ or libs/. Two teaching documents still present it as the house idiom, in a code block, as the answer to "how does a submit happen?".

Both blocks are doubly stale: they teach a deleted idiom and call submitHerregistratie(s.data), a function that no longer exists either.

A document that teaches a deleted idiom is worse than no document — a reader who follows it reintroduces the silent-failure bug RD-06 fixed.

Read first

  • libs/shared/src/application/store.ts — the effect map, the trigger rule, the Seed exemption, and the "must never throw" contract. This is the new idiom to document.
  • Any migrated call site, as a worked example — besluit-form.component.ts is the smallest.
  • docs/reference/architecture/ARCHITECTURE.md §2d (the block at 306-322) and the write walkthrough mention at :574.
  • docs/reference/fp-tea-atomic-design.md (the block at 336-350).

Decisions (pre-made, don't relitigate)

  1. Scope is exactly two documents. An earlier version of this plan claimed plop-templates/form-machine.hbs generates runIfSubmitting and that .claude/skills/form-machine/SKILL.md teaches it. Both are false, verified by grep: the plop template is machine-only (74 lines, no @Component), and the skill never mentions it. Do not "fix" either file. If you find yourself editing a .hbs or a SKILL.md, stop.

  2. Rewrite the code block, do not delete the section. §2d ("Side effects (HTTP) without polluting the reducer") and its fp-tea counterpart answer a real question and answer it well. The answer changed; the question did not.

  3. The new block shows the effect map. Same worked example (a herregistratie submit with its optimistic begin/confirm/rollback), expressed as a registration:

    private store = createStore<WizardState, WizardMsg>(initial, reduce, {
      Submitting: async (s, store) => {  },
    });
    

    Keep the numbered inline comments — they are what makes the block teachable.

  4. State the two properties the old idiom lacked, because they are the reason for the change and a reader should see them:

    • Entering the state runs the effect. A dispatch cannot silently skip it.
    • Double-submit protection is structural: the effect fires only on a tag transition, so a second Submit while already submitting is a reducer no-op and fires nothing.
  5. Document the Seed exemption where the idiom is taught, in one sentence: a mount or restore message must not trigger a submit. That is the non-obvious part of the rule, and store.ts explains it in full for anyone who needs more.

  6. Fix ARCHITECTURE.md:574's write walkthrough too — it opens with runIfSubmitting() (§2d) → createSubmitChangeRequest. Replace the first hop with the effect map. Leave the rest of §6a alone: RD-31 rewrites that section, including its stale L<n> citations and two dead file paths. Touch only the runIfSubmitting hop here.

  7. Drop the submitHerregistratie(...) call from both blocks. That module no longer exists (submit-herregistratie.ts was deleted). Use draftSync.submit(...), which is what the two herregistratie wizards actually call today.

Files

  • docs/reference/architecture/ARCHITECTURE.md (§2d block, and the one hop at :574)
  • docs/reference/fp-tea-atomic-design.md (the block at 336-350)

No code files. No .hbs. No SKILL.md.

Steps

  1. Rewrite ARCHITECTURE.md §2d's code block per decisions 3-5.
  2. Fix the first hop of the write walkthrough at :574 per decision 6.
  3. Rewrite the equivalent block in fp-tea-atomic-design.md per decisions 3-5 and 7.
  4. Update this ticket's Status: to done and the README's RD-09 row to done.
  5. Commit all of it together.

Acceptance criteria

The deleted idiom is no longer taught anywhere:

grep -rn "runIfSubmitting\|runIfIndienen" docs/ apps/ libs/ .claude/   # MUST return nothing
grep -rn "submitHerregistratie" docs/                                  # MUST return nothing

Every code identifier the new blocks name must exist:

grep -n "StoreEffects\|effects?" libs/shared/src/application/store.ts   # the API is real
grep -rn "draftSync.submit" apps/ssp | head -3                          # the call is real
npm run ci   # exits 0

Verification

npm run ci. This ticket touches only two Markdown files under docs/reference/, so --full is not required — neither is globbed by Storybook.

Read both rewritten blocks end to end and check a reader could follow them without opening store.ts. That is the actual acceptance test for a teaching document, and no command checks it.

Out of scope

  • The rest of ARCHITECTURE.md §6a — its stale L<n> line citations, its two non-existent file paths, and its post-RD-16 parseDashboardView claim. RD-31.
  • fp-tea-atomic-design.md's 11 broken pre-monorepo src/app/… paths and its broken anchor. RD-32.
  • plop-templates/form-machine.hbs and .claude/skills/form-machine/SKILL.md (decision 1).
  • CLAUDE.md. RD-33.

Risks

  • Do not chase the other staleness in these two files. Both are also targets of RD-31 and RD-32. Editing their line citations or paths here creates a conflict with those tickets for no gain. Change only what teaches the submit idiom.
  • fp-tea-atomic-design.md's surrounding paths are already broken (they use the pre-monorepo src/app/… prefix). Leaving them broken in this commit is correct — RD-32 owns them. Do not half-fix the file.
  • Prettier formats Markdown. Run npx prettier --write on both files, or format:check fails.