- Alphabetize the import.clj :require block (AGENTS.md Import Formatting).
- Remove unused imports (digest, strip) flagged by clj-kondo.
- Make the client-not-found classify-table test independent: it previously
reused the bank-account-not-found input and added zero marginal coverage;
now seeds an orphan bank account so only the client error fires.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implement the SSR/alpine/htmx manual transaction import, wiring the
already-declared but unhandled ::external-import-page/parse/import routes.
Mirrors the SSR ledger import: paste the exact master-branch Yodlee
positional-column TSV, review parsed rows in an editable grid with per-row
error/warning badges, and import. Every master validation is preserved and
the existing import.transactions engine is reused unchanged
(via import.manual/import-batch), so core components are untouched.
- New ns auto-ap.ssr.transaction.import (page, paste/parse, editable grid,
two-tier validation, import handler) + admin-only transactions Import nav.
- Two-tier validation: fixable problems (bad date/amount, unknown client or
bank-account code, missing fields) are hard errors that block the whole
batch; inherent skip-conditions (non-POSTED, before start-date/locked,
already-imported) are warnings computed from the engine's own
categorize-transaction so the grid preview matches the import result.
- Tests: failing-first Playwright e2e (e2e/transaction-import.spec.ts) plus
unit/integration coverage (ssr/transaction/import_test.clj, 10 tests).
- Deterministic bank-account code in the e2e seed.
Plan: docs/plans/2026-06-01-001-feat-manual-transaction-import-ssr-plan.md
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When a transaction is pre-coded, the snapshot stores :transaction-account/account
as a Datomic ref map {:db/id N} rather than a bare integer. simple-mode-fields*
and the simpleAccountId Alpine initializer both need the integer id, not the map,
to correctly populate the account typeahead value and the x-hx-val binding.
The hx-vals attribute with a JavaScript IIFE was causing a SyntaxError
when navigating to the transactions page from any other page. Replaced
with hx-include="#transaction-filters" which correctly preserves
filter state across transaction sub-pages.
- Add new memo filter to transaction page (searches :transaction/memo)
- Enhance existing description filter to use case-insensitive regex
- Both filters support wildcard matching via .* pattern
- Add e2e tests for filter functionality
- Update test data with memo fields
Fixes substring search in company dropdown. The search query was
using raw user input instead of the cleansed version that adds a
wildcard suffix (e.g. 'dough' -> 'dough*'). Without the wildcard,
Solr performs exact token matching, so searching 'dough' would not
match 'Doughballs'.
When typing in the company dropdown search, check for an exact match
on client code via Datomic before falling back to Solr name search.
This allows users to quickly find clients by typing their code (e.g. NGRV).
- vendor-default-account now uses raw vendor default account (not client-specific override)
- Account name is clientized via d-accounts/clientize only for single-client contexts
- Added single-client-id helper that returns client ID only when user has exactly one client
- Added multi-client e2e test verifying no pre-population across multiple clients
- Updated test server to support multi-client mode switching via /test-set-client-mode
- Test server now seeds a second client for multi-client scenarios
- Add vendor-changed HTMX handlers for both bulk code and individual edit
- Pre-populate default account at 100% when vendor is selected and no accounts exist
- Fix render-accounts-section to render from step-params correctly
- Change bulk code vendor-changed from hx-get to hx-post to include form data
- Add routes for vendor-changed endpoints
- Update e2e tests to cover vendor pre-population
- Run lein cljfmt fix across codebase
- Create requirements document based on master cljs implementation
- Add Playwright e2e tests covering happy path, validation, and distribution
- Fix hiccup id syntax in SSR bulk code form (div#id.class order)
- Add missing account location validation to SSR bulk code submit
- Enhance test server with multiple transactions and fixed-location account
The format specifier $%,.2f requires floating-point values but
(reduce + 0 ...) can return a Long when all amounts sum to an integer.
Added explicit (double ...) casts and changed initial value to 0.0
to ensure the format call always receives a double.
The previous attempts to set up form cursor context in toggle-amount-mode
were failing because the cursor library's dynamic binding model is complex
and requires specific initialization through fc/start-form.
Instead of trying to recreate the cursor context, this fix:
1. Creates transaction-account-row-no-cursor* that renders rows with explicit
field names and values (no cursor functions)
2. Rewrites toggle-amount-mode to directly construct the data-grid HTML
using map-indexed over the accounts vector
3. Removes the broken manual cursor binding attempts
4. Removes unused auto-ap.cursor import
This ensures the toggle handler works independently of the wizard's cursor
context while still producing identical HTML output.
The toggle-amount-mode handler was failing because account-grid-body*
uses fc/cursor-map which requires the form cursor context to be set up.
Added manual cursor binding in toggle-amount-mode to create a cursor
pointing to the transaction/accounts vector and bind it to fc/*current*
before rendering the grid.
The radio-card component was ignoring HTMX attributes (:hx-post, :hx-target,
etc.) passed to it. Modified the component to extract these attributes and
merge them into each radio input element, so the $/% toggle now properly
triggers HTMX requests when changed.
The assoc-in call had too many arguments, so the request state wasn't being
updated with the new mode or converted accounts. Using -> threading with
separate assoc-in calls ensures both the accounts and mode are properly set
before re-rendering the grid.
- Fix Math/abs nil error when adding new accounts by using (or value 0.0)
- Fix Math/abs nil in account-grid-body* and save-handler for safety
- Make $/% radio toggle display side-by-side using :orientation :horizontal
- Apply fixes to edit-wizard-new-account render, account-grid-body*, and save-handler
When editing a transaction manually, users can now toggle between viewing
account amounts as dollar values or percentages. The toggle appears in the
table header as a radio button group ($ / %).
Key features:
- Global toggle switches all accounts simultaneously
- $→%: amounts are converted to percentages of the transaction total
- %→$: uses percentages->dollars with spread-cents for accurate cent distribution
- Form state preserves vendor, memo, approval status when toggling
- Save handler converts % back to $ before persisting to Datomic
- Uses HTMX to re-render only the account grid body on toggle
New route: /toggle-amount-mode
New functions: ->percentage, percentages->dollars, convert-accounts-mode,
account-grid-body*, toggle-amount-mode
When a transaction is saved via the edit modal, return the updated row
HTML with {:flash? true} instead of an empty div. This makes the row
flash with the live-added animation, matching the behavior of other
pages like invoices and accounts.
Uses hx-retarget to swap the specific row in the table while also
triggering modalclose to close the modal.
When a transaction account had 'Shared' location, spread-account was
creating multiple accounts with the same :db/id but different locations,
causing a datoms-conflict error in Datomic.
Now generates unique tempids for all spread accounts beyond the first,
preventing entity ID collisions while preserving the original account's
tempid for the first location.
Fixes: Two datoms in the same transaction conflict on :transaction-account/location
When validation errors occur at the root level (e.g., from :fn validators
in multi schemas), they are returned as a vector directly rather than a
map with :errors key. Update default-step-footer to handle both cases.
- Add require-approval schema validation for :manual action
- Fix keyword comparison to use :transaction-approval-status/approved
- Move require-approval function before schema definition
- Also fix save handler validation to use correct keyword
Add 2 more route handler tests:
- execute-dialog-route-works: Tests execution dialog for rules
- new-dialog-route-returns-empty-form: Tests new rule form
Total: 17 tests with 26 assertions, all passing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive tests for the SSR admin transaction rules module:
- Rule matching by description pattern
- Rule matching returns empty for no matches
- Validation accepts valid data with 100% account allocation
- Validation rejects invalid account totals
- Rule matching by amount range
- Rule matching by bank account
- Security tests for non-admin access
- Execute validation tests
All 8 tests passing with 9 assertions. Tests focus on the unique
rule matching engine functionality that differentiates transaction
rules from other admin modules.
Includes implementation plan documenting 23 test scenarios
and 6-phase approach for complete coverage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added comprehensive test suite for account creation, validation, and grid views
- Documented Datomic entity reference handling patterns in test comments
- Created 5 test improvement todo documents addressing common test anti-patterns
- Todo items cover: removing debug statements, fixing test nesting, strengthening assertions, extracting helpers, and removing doc-only tests