Proves the Phase-6a wizard engine against a real 2-step modal: the Transaction
Rule wizard (edit step + read-only test/preview step) now runs on wizard2 /
wizard-state, fully de-cursored.
What changed
- Wizard machinery removed: deleted the EditModal / TestModal /
TransactionRuleWizard defrecords (mm/ModalWizardStep + LinearModalWizard),
MultiStepFormState, the EDN snapshot, and the step-params[...] prefix. Replaced
with a data-driven `transaction-rule-wizard-config` (two steps + init-fn +
done-fn) driven by the engine.
- De-cursored the whole edit form (82 fc/ refs -> 0): every field reads explicit
data + path->name2; errors via a bound *errors* / ferr. The account row's Alpine
cross-field dispatch wiring (clientId -> accountId -> location) is preserved
verbatim — only the data plumbing moved off the cursor.
- The test step's :render reads :all-data (the engine's get-all), so the
formtools "combine at the end" mechanism feeds the preview table.
- Routes 4 -> 2: open-rule-wizard (new + edit), save-step (every transition via the
engine's `direction` field). The dedicated `navigate` route is deleted.
- decode-rule-form select-keys to the schema's known keys so the engine's nav
fields (wizard-id/current-step/direction) don't leak into the upserted entity.
Scorecard (admin/transaction_rules.clj): fc/ 82->0, mm/ 20->0, defrecords 3->0,
LOC 1000->964, routes 4->2.
Scope note: the de-cursored edit step keeps com/* Hiccup leaf components (not yet
sc/* Selmer); the value here was removing fc/ + mm/ and proving the engine, not
re-templating the conditional/Alpine-cross-field layout. Hiccup-in-render is a
documented partial; the com/ -> sc/ swap is a mechanical follow-up.
Verification: rule spec 4/4 (new + edit dialogs, advance-to-test preview, save);
full Playwright suite 55/55; cljfmt clean. Skill fed: scorecard row + narrative
(engine's first real modal; generalizes for a one-data-step wizard); gotchas
(strip engine nav fields in decode, new-row temp-id, direction-button nav).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Behavior-parity safety net before migrating the Transaction Rule modal onto the
session-backed wizard engine. The modal had no e2e coverage; the test server seeded
no rules.
- test_server.clj: seed a transaction rule (under client TEST2, in a SEPARATE
transaction so the first transaction's tempid->entity-id allocation — and thus the
TEST transaction grid order the other specs depend on — is byte-identical); surface
its id via /test-info (ruleId).
- e2e/transaction-rule.spec.ts (4 tests): the new-rule edit step renders (description,
account grid, approval radios, Test control), the edit dialog pre-populates the
seeded rule, advancing to the test step renders the matching-transactions preview,
and saving from the test step creates the rule + closes the modal. Covers both entry
points (new/edit), both steps (edit + test), and save.
Note: deliberately NOT seeding a recent matching transaction — a date-NOW txn perturbs
an unrelated transaction-edit save spec (pre-existing fragility), and the test-table
query/render is reused unchanged by the migration, so characterizing that the preview
renders is sufficient parity.
Full Playwright suite 55/55 (51 prior + 4 new).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>