Invoice Pay is the first GENUINE multi-data-step wizard, and migrating it exercises
the engine's central abstraction for the first time: choose-method collects
{:bank-account :method}, payment-details collects {:invoices :check-number
:handwritten-date :mode}, and the engine's get-all MERGES the two independent step
payloads for the per-method pay (handwrite-check transacts a pending check; the
others go through print-checks-internal). This is exactly the mechanism the Phase-6
adversarial review flagged as unproven.
What changed
- Deleted the 3 wizard records (PayWizard / ChoosePaymentMethodModal /
PaymentDetailsStep), MultiStepFormState, the EDN snapshot, and the step-params[...]
prefix. Replaced with pay-wizard-config (init-fn builds read-only :context;
two steps; done-fn = pay!) driven by wizard2.
- De-cursored the payment-details amounts grid (fc/cursor-map -> explicit
(map-indexed) over :context :invoices with path->name2 names).
- The bank-account cards' method controls now post {bank-account, method,
direction:next} straight to the engine submit-route (was a bespoke navigate route).
- Routes 3 -> 2: open-pay-wizard (GET), pay-step (every transition); the
pay-wizard-navigate route is deleted.
- Used the post-review engine primitives: :open-response (modal wrap), nav-footer
(with new :save-label "Pay"), auto nav-field stripping (flat decode, no allowlist),
Enter guard.
invoices.clj falls fully off the framework: Invoice Pay was the last mm/fc user
(bulk-edit went in Phase 5), so fc/ 0, mm/ 0, defrecord 0, step-params 0 — and the
multi-modal / form-cursor / malli.util requires are removed.
Gotcha discovered + documented: wizard session data must be EDN-safe (the cookie
session store has no clj-time readers), so the date default is computed in render,
not stored in context.
Verification: invoice-pay spec 3/3 (the merge end-to-end); full suite 58/58; load-file
clean; cljfmt clean. Skill fed: scorecard row (merge proven; whole-file zeroing) +
the EDN-session-safety gotcha.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Invoice Pay wizard is the first GENUINE multi-data-step wizard: choose-method
(collects bank-account + method) -> payment-details (collects check-number /
handwritten-date / amounts), merged only at submit. This gate characterizes that
flow before migrating it onto the session-backed engine, so the merge can be proven
behavior-preserving.
- Seed: make the TEST client's check bank account visible (+ name "Test Checking")
so the choose-method step renders a usable method card. The pay flow had no e2e
coverage, so the bank account was never visible in tests before.
- Spec drives the real 2-step flow against the unmodified wizard: choose-method
renders the bank account + its methods (print-check/debit/handwrite-check, in the
card tooltip); picking handwrite-check advances to payment-details (check-number +
date + Pay); filling the check number and submitting shows the completion modal.
The handwrite-check path is used because it transacts a pending check payment
directly (no PDF/S3), making the success assertion stable.
Notes for the migration: the method controls live in a <template x-ref="tooltip">
revealed by the card button; the footer Pay submit is x-ref="next"; both the grid
filters and the modal carry a check-number input, so the modal selectors are scoped
to #wizard-form.
Verification: invoice-pay spec 3/3; full suite 58/58 (no regressions from the seed
change).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>