Bug bash round 3: money #1398

Open
opened 2026-10-07 19:01:30 +00:00 by kayg · 5 comments
Owner

AREA: Money Tab. Budgets, accounts, transaction entry/edit/split/transfer, categories and assigning money, month rollover, imports (YNAB/Actual/CSV) including the import wizard review step, reconciliation, per-currency formatting, big budgets (50k transactions). Number correctness is a hard rule: every balance shown must equal a recomputation from raw transactions; add property tests for any numeric bug. Rounding, negative zero, very large and very small amounts, decimal separators per currency. Do not redesign the wizard (owner grill pending); fix bugs only.

Tracking issue for the 2026-10-08 night bug bash round 3. Every bug found gets its own issue, linked here.

AREA: Money Tab. Budgets, accounts, transaction entry/edit/split/transfer, categories and assigning money, month rollover, imports (YNAB/Actual/CSV) including the import wizard review step, reconciliation, per-currency formatting, big budgets (50k transactions). Number correctness is a hard rule: every balance shown must equal a recomputation from raw transactions; add property tests for any numeric bug. Rounding, negative zero, very large and very small amounts, decimal separators per currency. Do not redesign the wizard (owner grill pending); fix bugs only. Tracking issue for the 2026-10-08 night bug bash round 3. Every bug found gets its own issue, linked here.
Author
Owner

Starting Round 3 on job/bash3-money.

Worktree HEAD at start: 0419170fe456b58614befcb12d9c9d255118f1c0. origin/dev currently resolves to d395b6e25da20d8c67b8b9fc1a593b813939c8a7; I will merge that once before final gates as instructed.

I am reviewing the prior Money bash reports and will begin with flows they left untested.

Starting Round 3 on `job/bash3-money`. Worktree HEAD at start: `0419170fe456b58614befcb12d9c9d255118f1c0`. `origin/dev` currently resolves to `d395b6e25da20d8c67b8b9fc1a593b813939c8a7`; I will merge that once before final gates as instructed. I am reviewing the prior Money bash reports and will begin with flows they left untested.
Author
Owner

The real production walkthrough reproduces the known cancellation-return defect #1410. After creating a populated CSV Budget and opening a review, the app accepts cancellation; the existing Money E2E then times out after 30 seconds waiting for /money/household/2026-10 at 390 px in light mode (apps/web/e2e/money.mjs:664). This matches #1410, so I am not filing a duplicate. The run used the production web build and the shared server from origin/dev in a disposable target/tmp data directory.

The real production walkthrough reproduces the known cancellation-return defect #1410. After creating a populated CSV Budget and opening a review, the app accepts cancellation; the existing Money E2E then times out after 30 seconds waiting for `/money/household/2026-10` at 390 px in light mode (`apps/web/e2e/money.mjs:664`). This matches #1410, so I am not filing a duplicate. The run used the production web build and the shared server from `origin/dev` in a disposable `target/tmp` data directory.
Author
Owner

Finding: the real YNAB JSON Review metric reads “2 split · 1 transfer · 2 cleared” when the source contains two split rows. Filed cosmetic issue #1437 with production screenshot evidence at artifacts/money-bash3/ynab-split-transfer-review-light-1440.png. The split, paired Transfer, and account totals are still under verification; I will preserve the existing import behavior while correcting the count wording.

Finding: the real YNAB JSON Review metric reads “2 split · 1 transfer · 2 cleared” when the source contains two split rows. Filed cosmetic issue #1437 with production screenshot evidence at `artifacts/money-bash3/ynab-split-transfer-review-light-1440.png`. The split, paired Transfer, and account totals are still under verification; I will preserve the existing import behavior while correcting the count wording.
Author
Owner

Finding: after a YNAB JSON export reaches Review, the UI displays “The temporary copy could not be removed” although the real Files API confirms cleanup (POST /api/v1/files/trash 200, then GET /api/v1/files/stat 404). Filed cosmetic issue #1438 with screenshot and trace evidence. This is a Money-owned false cleanup failure; I will make the client verify that the staged path is gone instead of comparing the Trash result to the source path.

Finding: after a YNAB JSON export reaches Review, the UI displays “The temporary copy could not be removed” although the real Files API confirms cleanup (`POST /api/v1/files/trash 200`, then `GET /api/v1/files/stat 404`). Filed cosmetic issue #1438 with screenshot and trace evidence. This is a Money-owned false cleanup failure; I will make the client verify that the staged path is gone instead of comparing the Trash result to the source path.
Author
Owner

Round 3 report — Money Tab

Branch: job/bash3-money
Head: edeee3d86c
Base: merged origin/dev once before final gates.

Built

  • Revalidate a cached empty Budget catalog before the landing page shows its empty state (#1410).
  • Treat a successful one-item Files Trash response as staged-source cleanup success (#1438).
  • Use plural labels for multiple split and transfer rows (#1437).
  • Refreshed 14 exact Money metrics performance pins. Limits and ratchet counts did not change.

Findings

Issue Symptom Severity Result
#1410 Landing page could show no Budgets after a new Budget was published while an empty cached catalog remained. Major Fixed in 355f264e9.
#1438 Import review showed a cleanup error after Files successfully moved the staged source to Trash. Minor Fixed in 89c06896b.
#1437 Review showed singular “split” and “transfer” labels for counts greater than one. Cosmetic Fixed in a4da19cb8.
#688 / #641 At 50k Transactions, the register did not render within 240 seconds. Major Existing performance issue; not re-filed or changed in this round.

Coverage

Flow Tested Widths, themes, input methods Result or gap
Budgets, categories, assignment Yes Money production E2E: 390, 820, 1440 px; light and dark; macOS platform emulation; pointer-driven forms and assignment. Create, assignment and derived amounts passed. The cancellation landing regression is fixed.
Accounts and balances Yes Actual import at 390 px light with touch emulation and keyboard Enter; core Money E2E screenshot matrix at all six width/theme pairs. Imported Account balances equal recomputed raw Transaction sums. Closed Account state remains visible.
Transaction entry and edit Yes Production Money E2E plus MonthSwitcher/edit probe at 1440 px light; pointer entry/edit and Undo. Payee and multiline Notes edit, and Undo restores them.
Split and Transfer Partial YNAB JSON import/review/publish by pointer; review screenshots at 390/820/1440 px in light/dark; macOS platform emulation. Exact split legs, paired Transfer rows and per-Account sums passed. Creating or editing split/Transfer rows in the editor was not exercised; the current simple editor keeps those rows read-only.
Month rollover Yes January to February through the API and MonthSwitcher at 1440 px light. Available money carries into February correctly.
YNAB, Actual and CSV imports Partial YNAB CSV/JSON and Actual production import; Actual review at 390 px light; YNAB review screenshots at all six width/theme pairs. CSV pairing, replacement/Undo and JSON publication passed. The 15k Actual review reached Review but the existing #1205 assertion still expects a stale check count, so that run did not publish.
Reconciliation Partial Actual imported Account register at 390 px light. Reconciled-but-uncleared state survives import and its register control stays disabled. I found no statement-level reconciliation UI in Money, so that flow was unavailable to test.
Currency and number correctness Yes Amount property tests across 8 locales and USD/EUR, JPY, KWD, CLF and INR scales; large, cent and zero values through real CSV/API/UI. Exact integer minor units and displayed balances passed; no numeric bug was found.
50k Transactions Prior round only Prior local run; no new run in Round 3. #688 records Actual import 86.4 s, register API 13.0 s, Account API 21.6 s, and no register table within 240 s.

UX gaps closed

  • A newly published Budget no longer disappears behind an empty cached landing state.
  • A successful staged-file cleanup no longer shows a false error.
  • Split and Transfer counts use the correct plural form.

UX gaps left

  • The known 50k register rendering issue (#688/#641) remains.
  • The existing #1205 Actual 15k test expectation remains unchanged. Review showed 7,320 checks; the current formula yields 54×120 Account checks + 2×120×3 category checks + 120 Ready-to-Assign checks = 7,320.
  • I did not complete slow/offline network, two-tab concurrent editing, five-minute memory, exhaustive keyboard-only/screen-reader checks, or statement-level reconciliation. The full input and viewport matrix was not repeated for each individual flow.
  • No new numeric property test was added because no numeric defect was found; existing Money amount properties passed.

Screenshots attached to #1398

Before (pre-fix production UI, 1440 px light): YNAB JSON review

After: 1440 light, 390 light, 820 light, 390 dark, 820 dark, 1440 dark, and reconciled Account register at 390 light.

Gates

  • cargo fmt --check: passed, no output. No Rust code changed; Rust clippy/tests were not run.
  • bun run build: passed; Compressed 914 static variants; saved 21511182 bytes.
  • bun run check: exit 0. perf-lint: PASS; 0 violations; 22544 scoped exceptions; svelte-check found 0 errors and 4 warnings in 2 files (3 existing Mail CSS-selector warnings and the existing Money .ready warning).
  • bun run test --maxWorkers=2: all test stages printed success: Ran 140 tests in 0.037s, 8 pass, 0 fail, Test Files 297 passed (297), Tests 2119 passed (2119), Duration 255.01s. The enclosing zsh wrapper then printed zsh:1: read-only variable: status because its result-capture variable used zsh’s reserved status; this happened after the test summary. I did not rerun the suite.
  • Focused changed-file Vitest: 2 files, 13 tests passed. Money number review and production E2E probes passed.
  • Cleanup: cargo clean printed Removed 1 file, 356B total; web build output and job temp data were removed.

Decisions

  • The Design does not specify whether an empty cached Budget list should be treated as final. I chose to revalidate it before showing the empty state, while retaining the existing fast cached path for nonempty lists.
  • The Design does not specify the Files Trash response interpretation in this Money cleanup call. I treated exactly one returned Trash name as success for the single requested staged source.
  • I found no statement-level reconciliation screen in Money and did not add one during this bug-only round.

Files changed: apps/web/src/lib/money/store.svelte.ts, apps/web/src/lib/money/acknowledged-month.svelte.test.ts, apps/web/src/lib/money/import-session.svelte.ts, apps/web/src/lib/money/import-session.svelte.test.ts, apps/web/src/lib/money/import-ui.ts, apps/web/src/lib/components/money/MoneyImportMetrics.svelte, apps/web/src/lib/components/money/MoneyImportMetrics.svelte.test.ts, contracts/perf/exceptions.json, contracts/perf/adoption-1058.json.

## Round 3 report — Money Tab Branch: job/bash3-money Head: edeee3d86c84d7cf4c1cc7369d81ebbb80608be3 Base: merged origin/dev once before final gates. ### Built - Revalidate a cached empty Budget catalog before the landing page shows its empty state (#1410). - Treat a successful one-item Files Trash response as staged-source cleanup success (#1438). - Use plural labels for multiple split and transfer rows (#1437). - Refreshed 14 exact Money metrics performance pins. Limits and ratchet counts did not change. ### Findings | Issue | Symptom | Severity | Result | | --- | --- | --- | --- | | #1410 | Landing page could show no Budgets after a new Budget was published while an empty cached catalog remained. | Major | Fixed in 355f264e9. | | #1438 | Import review showed a cleanup error after Files successfully moved the staged source to Trash. | Minor | Fixed in 89c06896b. | | #1437 | Review showed singular “split” and “transfer” labels for counts greater than one. | Cosmetic | Fixed in a4da19cb8. | | #688 / #641 | At 50k Transactions, the register did not render within 240 seconds. | Major | Existing performance issue; not re-filed or changed in this round. | ### Coverage | Flow | Tested | Widths, themes, input methods | Result or gap | | --- | --- | --- | --- | | Budgets, categories, assignment | Yes | Money production E2E: 390, 820, 1440 px; light and dark; macOS platform emulation; pointer-driven forms and assignment. | Create, assignment and derived amounts passed. The cancellation landing regression is fixed. | | Accounts and balances | Yes | Actual import at 390 px light with touch emulation and keyboard Enter; core Money E2E screenshot matrix at all six width/theme pairs. | Imported Account balances equal recomputed raw Transaction sums. Closed Account state remains visible. | | Transaction entry and edit | Yes | Production Money E2E plus MonthSwitcher/edit probe at 1440 px light; pointer entry/edit and Undo. | Payee and multiline Notes edit, and Undo restores them. | | Split and Transfer | Partial | YNAB JSON import/review/publish by pointer; review screenshots at 390/820/1440 px in light/dark; macOS platform emulation. | Exact split legs, paired Transfer rows and per-Account sums passed. Creating or editing split/Transfer rows in the editor was not exercised; the current simple editor keeps those rows read-only. | | Month rollover | Yes | January to February through the API and MonthSwitcher at 1440 px light. | Available money carries into February correctly. | | YNAB, Actual and CSV imports | Partial | YNAB CSV/JSON and Actual production import; Actual review at 390 px light; YNAB review screenshots at all six width/theme pairs. | CSV pairing, replacement/Undo and JSON publication passed. The 15k Actual review reached Review but the existing #1205 assertion still expects a stale check count, so that run did not publish. | | Reconciliation | Partial | Actual imported Account register at 390 px light. | Reconciled-but-uncleared state survives import and its register control stays disabled. I found no statement-level reconciliation UI in Money, so that flow was unavailable to test. | | Currency and number correctness | Yes | Amount property tests across 8 locales and USD/EUR, JPY, KWD, CLF and INR scales; large, cent and zero values through real CSV/API/UI. | Exact integer minor units and displayed balances passed; no numeric bug was found. | | 50k Transactions | Prior round only | Prior local run; no new run in Round 3. | #688 records Actual import 86.4 s, register API 13.0 s, Account API 21.6 s, and no register table within 240 s. | ### UX gaps closed - A newly published Budget no longer disappears behind an empty cached landing state. - A successful staged-file cleanup no longer shows a false error. - Split and Transfer counts use the correct plural form. ### UX gaps left - The known 50k register rendering issue (#688/#641) remains. - The existing #1205 Actual 15k test expectation remains unchanged. Review showed 7,320 checks; the current formula yields 54×120 Account checks + 2×120×3 category checks + 120 Ready-to-Assign checks = 7,320. - I did not complete slow/offline network, two-tab concurrent editing, five-minute memory, exhaustive keyboard-only/screen-reader checks, or statement-level reconciliation. The full input and viewport matrix was not repeated for each individual flow. - No new numeric property test was added because no numeric defect was found; existing Money amount properties passed. ### Screenshots attached to #1398 Before (pre-fix production UI, 1440 px light): [YNAB JSON review](https://git.kayg.org/attachments/c3c976c2-960a-4154-9d40-529d826cfe7d) After: [1440 light](https://git.kayg.org/attachments/a6997e4d-bd0e-4b48-9a9c-db7bb93ea10f), [390 light](https://git.kayg.org/attachments/8049ea7c-183c-4f35-829f-6a0b738cfecc), [820 light](https://git.kayg.org/attachments/a56fe5e5-bff4-4d3b-9a08-63dea842407f), [390 dark](https://git.kayg.org/attachments/0dab12bb-a865-4908-98ea-b6fa122b28b6), [820 dark](https://git.kayg.org/attachments/50543c02-bce1-4061-9cb6-6b96a479b836), [1440 dark](https://git.kayg.org/attachments/df90ff82-e5b2-495e-a66b-1be491284a4f), and [reconciled Account register at 390 light](https://git.kayg.org/attachments/7690168b-e120-4f6f-a121-8952204991fc). ### Gates - cargo fmt --check: passed, no output. No Rust code changed; Rust clippy/tests were not run. - bun run build: passed; Compressed 914 static variants; saved 21511182 bytes. - bun run check: exit 0. perf-lint: PASS; 0 violations; 22544 scoped exceptions; svelte-check found 0 errors and 4 warnings in 2 files (3 existing Mail CSS-selector warnings and the existing Money .ready warning). - bun run test --maxWorkers=2: all test stages printed success: Ran 140 tests in 0.037s, 8 pass, 0 fail, Test Files 297 passed (297), Tests 2119 passed (2119), Duration 255.01s. The enclosing zsh wrapper then printed zsh:1: read-only variable: status because its result-capture variable used zsh’s reserved status; this happened after the test summary. I did not rerun the suite. - Focused changed-file Vitest: 2 files, 13 tests passed. Money number review and production E2E probes passed. - Cleanup: cargo clean printed Removed 1 file, 356B total; web build output and job temp data were removed. ### Decisions - The Design does not specify whether an empty cached Budget list should be treated as final. I chose to revalidate it before showing the empty state, while retaining the existing fast cached path for nonempty lists. - The Design does not specify the Files Trash response interpretation in this Money cleanup call. I treated exactly one returned Trash name as success for the single requested staged source. - I found no statement-level reconciliation screen in Money and did not add one during this bug-only round. Files changed: apps/web/src/lib/money/store.svelte.ts, apps/web/src/lib/money/acknowledged-month.svelte.test.ts, apps/web/src/lib/money/import-session.svelte.ts, apps/web/src/lib/money/import-session.svelte.test.ts, apps/web/src/lib/money/import-ui.ts, apps/web/src/lib/components/money/MoneyImportMetrics.svelte, apps/web/src/lib/components/money/MoneyImportMetrics.svelte.test.ts, contracts/perf/exceptions.json, contracts/perf/adoption-1058.json.
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-v0#1398
No description provided.