refactor(ssr): Phase 5 — full Selmer migration of Invoice Bulk Edit; remove the wizard; implement live totals
Migrates the Invoice Bulk Edit modal off the wizard to a plain Selmer form, building on the parity gate. Structurally Phase 3's bulk-code applied to invoices (selected entities -> expense-account rows), so near-pure reuse of bulk-code's flat-state plumbing + edit's account-totals-tbody. What changed - Wizard removed: deleted BulkEditWizard/AccountsStep records, MultiStepFormState, the step-params[...] prefix, the EDN snapshot, and all mm/* for this modal. Replaced with a plain handler + flat wrap-bulk-state (decode straight into bulk-edit-schema, no snapshot). - Selection-as-ids round-trip: the non-editable invoice selection is resolved to a concrete not-locked id vector at open and ridden back in hidden ids[] fields (the bulk analog of edit's single db/id) -- no filter re-query. - De-cursored bulk-edit-account-row* to Selmer (sc/*), explicit-id location swap (#account-location-<index>, replacing the old find * swap), reusing tx-edit/location-select*. - 100% Selmer modal render path; the surgical edit was done with the text-based Edit tool (the clojure-mcp structural tools reformat the whole 1812-line file), so the diff is contained to the requires + the bulk-edit region. - Routes 5 -> 3: GET bulk-edit, PUT bulk-edit-submit, POST bulk-edit-form-changed (one whole-form op dispatcher folding the old new-account route). Implemented the dead totals - The wizard's TOTAL/BALANCE percentage rows were commented out (#_(...)) with a duplicate id="total". Implemented as a #expense-totals sibling-<tbody> refreshed by a Rule-4 percentage-keyup swap (the new-account + total + balance routes all fold into form-changed / the sibling-tbody). Scorecard delta (bulk-edit modal): wizard records 2->0, bulk-edit routes 5->3, step-params/fc-cursor (modal) ->0, location swap find *-> explicit-id, totals dead->implemented. Verification: invoice-bulk-edit spec 5/5 (incl. add-row, save, validation, the implemented totals); full Playwright suite 50/50; cljfmt clean; diff confined to the modal region. Skill fed: scorecard row + settled repeated-row target-selector convention; gotcha (structural tools reformat large files -> use text Edit). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -133,3 +133,31 @@ Each migration appends one row (after-numbers), referencing the before in the di
|
||||
> proper `#summary-totals` block shows running Total + Balanced/Unbalanced (a Rule-4 targeted swap
|
||||
> on manual amount edits). The spec was updated to assert the fixed behavior. New cookbook entries:
|
||||
> the **inline click-to-edit cell** and the **db/id-keyed item merge** for partially-posted rows.
|
||||
|
||||
> **Phase 5 — Invoice Bulk Edit (cold apply in a 1812-line shared file).** Structurally
|
||||
> Phase 3's bulk-code applied to invoices (selected entities → expense-account rows:
|
||||
> account/location/percentage), so it was near-pure reuse: bulk-code's flat-state plumbing
|
||||
> (ids round-trip, `wrap-bulk-state`, schema/decode) + edit's `account-totals-tbody` for the
|
||||
> live totals. `BulkEditWizard`/`AccountsStep` + `MultiStepFormState` deleted, `step-params`
|
||||
> dropped, the rows de-cursored to Selmer with the explicit-id location swap, bulk-edit
|
||||
> routes 5→**3** (the `new-account` + `total` + `balance` routes folded into one
|
||||
> `form-changed` op dispatcher + the sibling-`<tbody>` totals swap). **Implemented the dead
|
||||
> TOTAL/BALANCE display** (the wizard had them commented out with a duplicate `id="total"`)
|
||||
> as a `#expense-totals` sibling-`<tbody>` refreshed by a Rule-4 percentage-keyup swap.
|
||||
> Parity held: invoice-bulk-edit spec 5/5, full suite 50/50.
|
||||
>
|
||||
> **Editing a wizard buried in a large shared file:** the clojure-mcp structural tools
|
||||
> (`clojure_edit` / `replace_sexp`) **reformat the whole file** — here that was a spurious
|
||||
> 650-line whitespace diff that would bury the real change. For a surgical migration inside a
|
||||
> big multi-modal file, use the **text-based Edit tool** instead (the AGENTS.md "absolutely
|
||||
> necessary" carve-out), then `load-file` + `cljfmt` to verify. The resulting diff was fully
|
||||
> contained to the requires + the bulk-edit region.
|
||||
>
|
||||
> **Repeated-row target-selector convention — settled (the Phase 5 exit criterion).** Across
|
||||
> edit / bulk-code / sales-summary / invoice-bulk-edit the convention converged on: **explicit
|
||||
> per-row ids** (`#account-location-<index>`, `#account-row-<index>`) for a cell-local swap
|
||||
> (Rule 2), and a **single stable-id sibling-`<tbody>`** (`#account-totals` / `#expense-totals`)
|
||||
> for running totals (Rule 4) — *not* data-attribute selectors or a `form-path→selector`
|
||||
> helper. Per-row ids are generated from the row index the form already uses for field names
|
||||
> (`path->name2`), so server and markup agree by construction. Whole-form swap (Rule 3) covers
|
||||
> structural changes (add/remove row). This is now the cookbook default; see `swap-doctrine.md`.
|
||||
|
||||
Reference in New Issue
Block a user