Migrates the POS Sales Summary edit modal off the wizard to a plain Selmer form,
building on the parity gate committed earlier. Largest migration so far and the
first with no prior test coverage.
What changed
- Wizard removed: deleted MainStep/EditWizard records, MultiStepFormState, the
step-params[...] prefix, the EDN snapshot round-trip, and all mm/* middleware.
Replaced with a plain handler + flat wrap-decode/wrap-derive-state. The 51 fc/
cursor refs are de-cursored into explicit data + Selmer templates.
- db/id-keyed item merge: wrap-derive-state overlays posted items onto the
persisted items by :db/id, so read-only fields the form doesn't post
(ledger-side, amount) survive a re-render and the debit/credit split + totals
stay correct. New manual rows (temp db/id) ride through as-is.
- Inline click-to-edit account cell preserved as three small targeted
.account-cell-swap routes (edit/save/cancel-item-account), ported to Selmer
with the new field-name scheme.
- 100% Selmer modal render path (the remaining Hiccup / hx-swap-oob / "hx-"
strings are all grid-page code — grid render lambdas, the filters form, and the
submit response-header map — not the modal).
- Routes: dropped edit-wizard-navigate + new-summary-item; added form-changed.
Fixes (two pre-existing bugs, per request)
- "New Summary Item" add button (was throwing `newRowIndex is not defined` and
targeting a non-existent `.new-row`) is now a whole-form-swap op=new-item that
adds an editable manual row (category + account typeahead + debit/credit money
inputs + remove).
- The dead totals/balance display (malformed Hiccup that discarded its labels) is
replaced by a proper #summary-totals block showing running Total +
Balanced/Unbalanced, refreshed via a Rule-4 targeted swap on manual amount edits.
Scorecard delta (pos/sales_summaries.clj): LOC 790->732, mm coupling 20->0,
wizard records 4->0, fc/ cursor 51->0, step-params 27->0 (2 comments), modal
routes 8->6. (hx-swap-oob 1 and mixed-hx live in the grid page, not the modal.)
Verification: sales-summary spec 7/7 (incl. the two fixes); full Playwright suite
46/46; cljfmt clean. Skill fed: scorecard row + narrative; gotchas (parity-gate-
first, characterize-then-fix, keyup-trigger tests); cookbook (inline click-to-edit
cell, db/id-keyed item merge).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Establishes the behavior-parity safety net required before migrating the POS
Sales Summary edit modal off the wizard (the modal had zero test coverage and the
test server seeded no POS data).
- test_server.clj: seed a balanced sales summary ($500 credit = $500 debit) with
two auto items referencing the existing test client + accounts; surface its id
via /test-info (`salesSummaryId`).
- e2e/sales-summary-edit.spec.ts: characterization spec (6 tests) capturing current
behavior — open modal (debit/credit columns, categories, resolved account names,
amounts), balanced state, inline account editor (pencil -> typeahead editor ->
cancel restores / save re-renders the cell), and Save (PUT round-trip closes the
modal + keeps the grid row). Exercises the edit-wizard, edit/save/cancel-item-account,
and edit-wizard-submit routes.
Notable finding: the "New Summary Item" button is currently BROKEN (its Alpine
handler throws "newRowIndex is not defined" and hx-target="closest .new-row"
matches no ancestor, so the new-summary-item route never fires). The spec documents
this as inert rather than asserting it works; the migration will decide fix-vs-preserve.
Full Playwright suite 45/45 (39 prior + 6 new).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>