Commit Graph
6 Commits
Author SHA1 Message Date
siddharthd 5db42f086f fix(orders): match the card leg by masking, not by card brand
ci / lint-test (push) Failing after 45s
Backfill dry-run over 130 real messages surfaced one 422: 'payments sum to 1.17
but receipt states 16.50'. The receipt is a mixed Uber payment —
Uber Cash $1.17 + Westpac ••••8032 $15.33 — and the card regex only matched
Visa|MasterCard|American Express|Amex, so an issuer-named leg was dropped
entirely. validateOrderTotals correctly refused it rather than recording $1.17
as the cost of a $16.50 order.

Anchors on the ••••NNNN masking instead, which also covers the form already
seen in the corpus ('Mastercard ••••3893 (CBA Ultimate) CHF 51.23'). Fixture
and regression test added.

Also repoints .env.test at the current postgres-personal container IP and
documents why: the container publishes no host port, so the address changes on
every recreate and the whole integration suite fails with connection errors
until it is refreshed.
2026-07-27 01:39:42 +10:00
siddharthd d06088fe34 docs: monthly expense baseline and emergency reserve analysis
ci / lint-test (push) Successful in 37s
One-off analysis, nothing built. Realistic baseline $4,140/mo -> $24,800 for
six months, against $89,770 already accessible ($81,017 loan redraw + $8,753
offset).

Records four corrections the raw data needs before any restatement:
misfiled Raiz/Vanguard/moomoo debits counted as spend, `other` credits read as
negative spend, `government` conflating ATO with rates/rego, and `fees` being
mostly annual.

CLAUDE.md gains two traps found while doing it: partial split coverage inside a
category is usually correct rather than a gap (only shared utilities and
subscriptions are split), and the loan repayment is voluntarily above contracted
($2,500 vs $1,190.54 per fortnight) with the difference recoverable via redraw.
2026-07-26 16:57:23 +10:00
siddharthd c465742635 docs: capture this session's learnings for a future pickup
ci / lint-test (push) Successful in 40s
CLAUDE.md gains the traps a new session would otherwise re-discover:

- Rules: a zero-condition rule matches everything (rule 43 would split all ~3,700
  transactions); preview-then-apply-by-id is the safe pattern and why it beats
  auto-applying on ingestion; how run provenance works.
- Shared expenses: transaction_splits.settled is dead data; getParticipantBalances
  is correct and must not be 'fixed'; settlement cannot be attributed per trip.
- The shared loan: separate ledger, fixed 50% with a tracked receivable, why the
  share must not be derived from actual payments, and why interest stays as spend.
- Extraction: balance assertions are the check that works, do not derive
  opening_balance or add a totals assertion (both would be tautological), Gemini
  invents summary fields it was not given, empty statements must not throw, FX is
  per-date, and CSV comparisons need millisecond ordering.

The design doc records Phase 0 as done - including that the original Phase 0 plan
was wrong, since reading the code first is what prevented breaking a working
balance page.

Known Gaps lists what is open: the unbuilt phases, 11 failing assertions, the
uncategorised Up rows, and the CSVs sitting in 030490e's history.
2026-07-26 16:19:02 +10:00
siddharthd ba87ff86e7 docs: record loan decisions — separate ledger, 50/50 fixed, $4,000 receivable
ci / lint-test (push) Successful in 35s
The loan is a separate ledger, not a settlement context: a contribution must
never be able to settle a dinner.

The share is fixed at 50%, not derived from actual payments. During Sonu's leave
the obligation did not change, only the payment did - a percentage-of-actual
model would silently redefine her share as 30% and make the shortfall vanish. So
the model needs an expected schedule alongside actual contributions, with the
difference as a tracked receivable. Currently $4,000.00 over Jul 2025 - Jun 2026.

On interest: recorded the mechanics (it is debited to the loan and repaid as part
of the balance - the reconciliation is exact) alongside the counter-argument that
$16,523.64 left and bought nothing, which is what an expense is. Recommends
keeping it as spend with a fixed/discretionary grouping to address the real
concern, but flags it as a judgement call rather than settling it.
2026-07-26 16:03:53 +10:00
siddharthd 4b7a7e5d9c docs: design proposal for shared expenses, settlement and the shared loan
ci / lint-test (push) Successful in 35s
Three problems that look separate are one: the app records money moving, and
separately records who owes whom, and the two never meet.

Documents what is broken with evidence - two half-built settlement models,
settlements existing twice unlinked, and Sonu's $37,980 of loan contributions
sitting unrecognised as generic transfers - then proposes settlement contexts,
payments as transactions rather than a side table, and loan co-ownership.

Nothing built. Five open questions, two of which are decisions about the
arrangement rather than the software.
2026-07-26 15:57:03 +10:00
siddharthd 856e1a51ab docs: agent/MCP access guide — connect + query finance data from any MCP client
ci / lint-test (push) Successful in 38s
2026-07-25 22:27:19 +10:00