simple-mode-fields* rendered its single account row by rebinding the form cursor to a
synthetic MapCursor rooted at accounts[0] (faking a deep starting position). Replace that
with explicit-data rendering: account-field-name builds the exact field names the cursor
would produce at [:step-params :transaction/accounts 0 field] (via path->name2), and
account-field-errors reads errors from the same path -- no re-rooted cursor.
This is the render-fn rewrite the earlier with-field-default shortcut couldn't be (that
mutated the cursor and broke the simple-mode swap). Scorecard: faked cursor roots 2 -> 0
(both heuristic-1 items now clear for this modal). Parity held: swap spec 6/6 (its vendor
tests run in simple mode), Shared Location save green, full suite 31 pass / no regression.
- gotchas.md: de-faking a cursor is not a drop-in -- with-field-default mutates the
cursor (transact!) as a render side effect and broke the simple-mode swap; the de-fake
belongs with the render-fn rewrite, verified against the swap spec.
- scorecard.md: append the Phase 2 (in-progress) Transaction Edit row -- no-cursor 1->0,
LOC 1608->1555, parity held (swap 6/6 + Shared Location). Faked roots / snapshot /
Selmer / route-collapse remain as the wholesale-rendering continuation of Phase 2.
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.
- playwright.config.ts: honor BASE_URL env (and skip the auto-started webServer when
set) so a server booted from a specific worktree on a non-default port can be tested
without fighting over :3333.
- skill test-recipes.md: record the recipe for running e2e from a non-default worktree
(in-process test server + reseed helper) and the measured baseline on the merged
hx-select reference: swap-doctrine 6/6 green; transaction-edit.spec.ts has a
pre-existing Shared-Location save failure that masks 7 via serial mode; full suite
30 pass / 2 fail / 7 skip. Gate for the refactor = swap spec + REPL pure-fn checks.
New repository-based skill at .claude/skills/invoice-template-creator/:
- SKILL.md: Complete guide for creating invoice parsing templates
- references/examples.md: Common patterns and template examples
- Covers vendor identification, regex patterns, field extraction
- Includes testing strategies and common pitfalls
Updated AGENTS.md with reference to the new skill.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>