Commit Graph

5 Commits

Author SHA1 Message Date
0f5650b73e refactor(ssr): collapse 5 manual-coding operation routes into edit-form-changed (heuristic 6)
The 5 manual-coding operations (vendor change, simple/advanced toggle, add row, remove
row, $/% toggle) each had their own route + handler, all doing "mutate form state ->
render-full-form". Fold them into the single edit-form-changed endpoint, which now
dispatches on an `op` form-param to the relevant pure apply-* mutation fn (apply-vendor-
changed / apply-toggle-mode / apply-new-account / apply-remove-account /
apply-toggle-amount-mode) then re-renders. A missing/unknown op (a plain dependent-field
change, e.g. account->location or amount->totals) just re-renders, as before.

- edit.clj: 6 handlers -> 1 dispatcher + 5 pure apply-* fns; markup posts to
  edit-form-changed with :hx-vals {:op "..."}.
- routes/transactions.cljc: remove the 5 now-unused route keys.
- e2e specs: retarget the vendor selector by op (div[hx-vals*="vendor-changed"]) and
  point the toggle-amount-mode / vendor response waits at edit-form-changed, since the
  old per-op route names are gone. (Behavioral assertions unchanged.)

Scorecard: manual-coding routes ~10 -> ~5 (operations now one dispatcher). Parity held:
swap spec 6/6, full suite 32 pass (Shared Location green; no new regression).
2026-06-03 07:07:52 -07:00
07159dc221 refactor(ssr): drop dead account-total / account-balance routes (heuristic 6)
The hx-select reference moved running totals into an inline #account-totals tbody that
refreshes via edit-form-changed, so nothing posts to ::route/account-total or
::route/account-balance anymore -- their route handlers were referenced only by their own
registrations. Remove the two handler fns, their route registrations, and the now-unused
route keys from routes/transactions.cljc. The pure account-total* / account-balance* fns
(used inline to render the totals) are untouched.

Scorecard: modal routes ~12 -> ~10. Full suite 31 pass / no regression.
2026-06-03 06:33:52 -07:00
57f3b63b6a refactor(ssr): de-fake simple-mode account cursor via explicit render (heuristic 1)
simple-mode-fields* rendered its single account row by rebinding the form cursor to a
synthetic MapCursor rooted at accounts[0] (faking a deep starting position). Replace that
with explicit-data rendering: account-field-name builds the exact field names the cursor
would produce at [:step-params :transaction/accounts 0 field] (via path->name2), and
account-field-errors reads errors from the same path -- no re-rooted cursor.

This is the render-fn rewrite the earlier with-field-default shortcut couldn't be (that
mutated the cursor and broke the simple-mode swap). Scorecard: faked cursor roots 2 -> 0
(both heuristic-1 items now clear for this modal). Parity held: swap spec 6/6 (its vendor
tests run in simple mode), Shared Location save green, full suite 31 pass / no regression.
2026-06-03 06:29:25 -07:00
a7ccdb12f3 docs(skill): record faked-cursor de-fake learning + Phase 2 scorecard progress
- gotchas.md: de-faking a cursor is not a drop-in -- with-field-default mutates the
  cursor (transact!) as a render side effect and broke the simple-mode swap; the de-fake
  belongs with the render-fn rewrite, verified against the swap spec.
- scorecard.md: append the Phase 2 (in-progress) Transaction Edit row -- no-cursor 1->0,
  LOC 1608->1555, parity held (swap 6/6 + Shared Location). Faked roots / snapshot /
  Selmer / route-collapse remain as the wholesale-rendering continuation of Phase 2.
2026-06-03 06:20:04 -07:00
3ecd115f76 docs(skill): distil ssr-form-migration skill from transaction-edit reference (Phase 1)
Capture the proven whole-form hx-select swap method as a reusable skill so every
later modal migration is cheaper and consistent. No app code changes.

- SKILL.md: the per-migration playbook (classify → baseline → characterize →
  consolidate render fns → templatize → wire HTMX → collapse routes → verify →
  commit → feed skill) + Growth contract + non-negotiables.
- reference/swap-doctrine.md: the four swap rules, focus invariant, Alpine-survives-
  swap hardening, target-selector strategy — worked from the real edit.clj swaps
  (memo no-request, account→location targeted cell, amount→totals sibling-tbody,
  vendor/mode/row whole-form). 0 OOB.
- reference/render-functions.md: explicit-data or top-rooted cursor; the MapCursor
  fake + transaction-account-row-no-cursor* twin as the smell to remove.
- reference/form-vs-wizard.md: classification + the data-driven session-backed
  (formtools SessionStorage) engine that replaces the snapshot round-trip + protocol.
- reference/selmer-conventions.md: STUB, validated in Phase 2.
- component-cookbook.md / gotchas.md / test-recipes.md / scorecard.md: seeded from
  what transaction-edit proves (7 cookbook entries, caret-survival + typeahead test
  recipes, scorecard baseline LOC 1608 / ~12 routes / 1 no-cursor twin / 2 faked
  roots / 0 OOB).

Scorecard (Transaction Edit baseline, before Phase 2): LOC 1608, routes ~12,
no-cursor twins 1, faked-cursor roots 2, snapshot merges ~75, OOB 0, mixed hx- 8.
2026-06-03 00:05:11 -07:00