Files
atomic-design-poc/docs/project/readable-codebase/RD-14-move-savestate-delete-action-state.md
T
ehoandClaude Sonnet 5 a8c7a573fc refactor: move SaveState into debounced-save.ts, delete action-state.ts (RD-14)
RD-12 and RD-13 moved both ActionState consumers into their machines. This
left ActionState with zero users, so this ticket deletes it outright.

SaveState is different. It has two four-way consumers (brief.page.ts and
org-template.page.ts) that still switch on all four cases, so it survives.
It moves into debounced-save.ts, next to createDebouncedSave, the only
function that sets it. Both store imports merge into the existing
debounced-save import line. The doc comments that named ActionState are
reworded, since the type no longer exists. No store's public saveState
signature changes, so brief/ui/ needs no edit.

This completes the phase. Two encodings survive: RemoteData for fetched
data, and each machine's own state union. SaveState stays as an explicitly
justified third encoding, for a separate concern (debounced autosave status)
that the other two do not cover.

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

5.5 KiB

RD-14 — Move SaveState beside its producer, delete action-state.ts

Status: done Source: PLAN.md 1b#2b

Why

RD-12 and RD-13 moved both ActionState consumers into their machines, so ActionState now has zero real users. Word-anchored, it survives only in its own definition and in one doc-comment mention.

SaveState is different and must survive: it has two genuine consumers that keep all four cases (brief.page.ts:150 and org-template.page.ts:102 both switch on it, and brief.page.ts:77 reads === 'Error'). The original plan called for deleting both types; that was corrected once the consumers were read.

So the file's remaining job is to hold one type whose only producer lives elsewhere. Move SaveState next to createDebouncedSave, which is what sets it, and the file has no reason to exist.

Read first

  • libs/shared/src/application/action-state.ts — 9 lines, both types
  • libs/shared/src/application/debounced-save.tsSaveState's new home; note the comment at line 16, which names ActionState
  • apps/ssp/src/app/brief/application/brief.store.ts:4,57 and org-template.store.ts:3,66 — the two importers

Decisions (pre-made, don't relitigate)

  1. Delete ActionState outright. Zero users after RD-12 and RD-13. Do not deprecate it, do not keep a re-export.

  2. Move SaveState verbatim into debounced-save.ts, keeping its doc comment. That file already owns the debounced-autosave concern and createDebouncedSave is the only thing that drives the state, so the type belongs beside it. Keep the four cases exactly as they are — Idle | Saving | Saved | Error.

  3. Delete libs/shared/src/application/action-state.ts. Nothing else lives in it.

  4. Update the two store imports to @shared/application/debounced-save. Both stores already import from that module for createDebouncedSave, so this should merge into an existing import line rather than adding one.

  5. Reword debounced-save.ts:16, which currently reads "it touches that store's SaveState/ActionState + adapter". Drop the ActionState half — the type will not exist.

  6. Change no UI file and no page. saveState's public signature on both stores stays identical, so the three consumer sites need no edit.

Files

  • libs/shared/src/application/debounced-save.ts — gains SaveState, comment reworded
  • libs/shared/src/application/action-state.tsdeleted
  • apps/ssp/src/app/brief/application/brief.store.ts — import only
  • apps/ssp/src/app/brief/application/org-template.store.ts — import only

No spec files. No UI files. No machine files.

Steps

  1. Move the SaveState declaration and its doc comment into debounced-save.ts.
  2. Reword the ActionState mention at line 16 (decision 5).
  3. Re-point both store imports (decision 4).
  4. git rm libs/shared/src/application/action-state.ts.
  5. Update this ticket's Status: to done and the README's RD-14 row to done.
  6. Commit all of it together.

Acceptance criteria

Measured baselines, dry-run before handover.

# The file is gone, and nothing imports it.
ls libs/shared/src/application/action-state.ts        # MUST be "No such file"
git grep -l "application/action-state" -- apps libs   # was 2 files -> MUST return nothing

# ActionState is gone entirely, word-anchored (a name containing it would defeat a bare grep).
git grep -nw "ActionState" -- apps libs               # MUST return nothing

# SaveState survives, in its new home, with all four cases. Anchor on the DECLARATION:
# a bare `-w SaveState` grep already returns 1 today, from the line-16 comment.
D=libs/shared/src/application/debounced-save.ts
git grep -c "export type SaveState" -- $D                       # was 0 -> MUST be 1
git grep -c "'Idle'\|'Saving'\|'Saved'\|'Error'" -- $D           # MUST be >= 4

# The render seam did not move: the three consumer sites are untouched.
git diff --name-only c599fee | grep -c "brief/ui/" || true   # MUST be 0
git grep -c "readonly saveState" -- \
  apps/ssp/src/app/brief/application/brief.store.ts \
  apps/ssp/src/app/brief/application/org-template.store.ts   # still 1 each
npm run ci   # exits 0

Verification

npm run ci. No story, no .mdx, no libs/shared/src/ui/**, so --full is not required.

dep:check matters here: debounced-save.ts is in libs/shared/src/application, the same layer action-state.ts was in, so no boundary changes. If dep:check fails, the type landed in the wrong layer.

If dotnet test fails with SQLite Error 1: 'no such table: …', that is the stale bigregister.db artifact in this README's Troubleshooting section, unrelated to your change.

Out of scope

  • Anything under brief/ui/ (decision 6).
  • The machines. RD-12 and RD-13 already moved the action lifecycles.
  • NO_SUBORGS becoming Empty — optional RD-34.
  • UploadStatus's type: discriminant — optional RD-35.

Risks

  • Do not delete SaveState along with the file. It has two four-way consumers. The original plan said to delete both types; reading the consumers corrected that, and this ticket is the corrected version.
  • Merge into the existing debounced-save import in both stores rather than adding a second import line from the same module — lint will not complain, but it reads badly.
  • This is the last ticket that touches action-state.ts. After it, the phase's claim holds: two encodings survive, RemoteData for fetched data and each machine's own state union, plus SaveState as an explicitly-justified third for a different concern.