fix(ssr): strip UI-only :mode before transaction upsert (500 on advanced manual save)

The :manual save handler builds its tx-data from the wizard snapshot and stripped the
control fields :action and :amount-mode, but not :mode (simple/advanced) added by the
recent manual-coding work. manual-coding-section* emits step-params[mode] on every
render, so EVERY advanced manual save posted :mode "advanced" into :upsert-transaction
and 500'd with ":db.error/not-an-entity :mode". Strip :mode alongside :action so the
upsert only sees real schema attributes.

Also fix the e2e helper that masked this: selectAccountFromTypeahead poked the Alpine v2
internal `el.__x.$data`, which is undefined on Alpine v3 (this app loads alpinejs@3.x),
so it silently no-op'd and the account posted empty. Drive the typeahead via the real
Alpine v3 path (Alpine.$data + tippy dropdown + click), mirroring transaction-edit-swap.

Unmasks the previously-failing "Shared Location spread on save" test (was first in a
serial file, hiding 7 siblings). Verified: that test passes; transaction-edit-swap stays
6/6. Skill gotchas.md records the :mode-strip rule, the Alpine-v3 API requirement, and
the modal-won't-close diagnosis recipe.
This commit is contained in:
2026-06-03 06:05:42 -07:00
parent ed3344438b
commit 69eed1f8a6
3 changed files with 59 additions and 58 deletions

View File

@@ -1235,7 +1235,10 @@
[{:as request
transaction :entity
:keys [multi-form-state]}]
(let [tx-data (-> multi-form-state :snapshot (dissoc :action))
(let [;; :mode is a UI-only field (simple/advanced); :action/:amount-mode are control
;; fields. None are Datomic attributes, so strip them before building the upsert
;; (otherwise :upsert-transaction fails with :db.error/not-an-entity :mode).
tx-data (-> multi-form-state :snapshot (dissoc :action :mode))
tx-id (:db/id tx-data)
client-id (->db-id (:transaction/client tx-data))
existing-tx (d-transactions/get-by-id tx-id)