heezy-finance Roadmap¶
Phase 1 — Fix the Data ✅ Complete (2026-06-18)¶
| Item | Status |
|---|---|
receipts.date_ts migration + backfill |
✅ |
merchant_normalized on receipts |
✅ |
category + merchant_normalized on bank_transactions |
✅ |
| Bank transactions integrated into dashboard | ✅ |
| Gas spend fixed: $140.52 (was $36) | ✅ |
| Bank source filter + 🏦 badge in Purchases | ✅ |
| Bank page with category cards + monthly chart | ✅ |
| BoA parser: CC detection | ✅ |
| Cap1 parser: fixed stmt_id bug | ✅ |
| Statement NFS ingest pipeline (end-to-end) | ✅ |
| Ingest pipeline: auto-category + merchant on insert | ✅ |
| docs.heezy.info live on Cloudflare Pages | ✅ |
Phase 2 — Complete Bank Coverage ✅ Complete (2026-06-20)¶
| Item | Status | Notes |
|---|---|---|
| Bank page deployment | ✅ | Category breakdown, monthly trends, top merchants |
| Bank integration into all views | ✅ | Overview, Purchases, Categories all include bank data |
payment_type on receipts |
✅ | Dropdown UI added: cash / credit / debit / check / other |
| Purchases table sortable | ✅ | Date, Source, Vendor, Item, Total, Category columns sortable |
| Purchases date defaults | ✅ | Start Date = 1st of month, End Date = today |
| Rule-based bank categorization | ✅ | Ollama too slow on CPU; keyword rules working well |
| More BoA monthly statements | ✅ | Jan–Jul 2026 checking loaded |
| CC statements (BoA Visa, Cap1, Chase) | ✅ | BoA CC 14 statements, Chase CC 14 back to Oct 2025 |
| Historical statement backfill | 🔲 | Nothing pre-Oct 2025 loaded on any account |
| Blocked: June 2026 statements | ✅ | Loaded |
Gmail auto-fetch is not viable
BoA and Capital One send notification-only emails with no PDF attachments.
Manual workflow: download from bank portal → drop to /nfs/heezy/ingest/raw/statements/new/ → picked up within 5 min.
CI/CD Lesson: Push to Gitea, Not GitHub¶
Issue: Pushing to GitHub origin instead of Gitea canonical repo breaks deployments.
Root Cause: GitHub is a mirrored backup only; act-runner watches Gitea. Pushing to origin (GitHub) doesn't trigger the pipeline.
Fix: Always push to Gitea remote first, then origin.
# ❌ Wrong — GitHub doesn't trigger act-runner
git push origin main
# ✅ Correct — Push to Gitea first, then GitHub
git push gitea main
git push origin main
Deployment Pipeline:
1. Push → Gitea main
2. Gitea webhook → act-runner triggers .gitea/workflows/deploy-heezy-finance.yml
3. Workflow builds Docker image, pushes to ECR
4. Workflow writes .deploy-trigger file to heezy-k8s repo
5. heezy-k8s auto-deploy workflow: kubectl apply -k, rollout restart, rollout status
6. Pod updates with new image
See CI/CD for full details.
Phase 3 — Global Date Range + Lookback ✅ Complete (2026-06-20)¶
| Item | Status | Notes |
|---|---|---|
| Global date range selector | ✅ | Utilities/Mortgage historical lookback working |
| Utilities category drill-down | ✅ | Monthly breakdown with per-vendor trends |
| Mortgage payment tracking | ✅ | Historical payment records by date range |
| Category drill-down modal | ✅ | Click category cards to view monthly detail |
| Feature verification | ✅ | All 4 phases verified live on finance.heezy.info |
Phase 4 — Hockey Holdem Receipt ✅ Complete (2026-06-20)¶
| Item | Status | Notes |
|---|---|---|
| Receipt categorization | ✅ | Hockey Holdem vendor recognized + categorized |
| Line item detail modal | ✅ | Click receipt to view itemized breakdown |
| Payment type tracking | ✅ | Cash, credit, debit payment types recorded |
| Full integration | ✅ | Receipt appears in all views (Overview, Purchases, Hockey category) |
Phase 5 — Parser Fixes & Account Coverage ✅ Complete (2026-07-07)¶
| Item | Status | Notes |
|---|---|---|
| Fix Cap1 false-detected as EDJ | ✅ | Cap1 PDFs contain "EDWARD JONES" in txn descriptions; moved Cap1 check before EDJ in detect_bank() |
| Fix Chase Amazon closing date | ✅ | Opening/Closing Date X - Y regex now captures second (closing) date |
| Add missing accounts (BoA 7503, Chase 2609) | ✅ | Both inserted with display_group='debt' |
| Clean up bad statement rows from failed uploads | ✅ | Deleted edjbrok0000_2026-06-30, chasecrd2609_2026-05-20, stale account_balances row |
Fix boacrdNone ghost rows |
✅ | Guard added in scan_statements.py: skip insert_bank_statement when account_last4=None and type is credit_card. 12 existing rows deleted. Now 0 |
Phase 6 — Infrastructure Resilience ✅ Mostly Complete¶
Focus: Remove node affinity pinning, fix PVC pattern for multi-node resilience.
| Item | Status | Notes |
|---|---|---|
| Remove nodeSelector / nodeAffinity | ✅ | Gone from the deployment and from heezy-statement-scanner / heezy-budget-alerts. The pod currently runs on nebula-4, having moved off nebula-5 on its own |
| Implement & test failover | ✅ | Verified by real reschedules across nodes |
| Audit PVC necessity | 🔲 | /data is still mounted but app state lives in Postgres. Unclear the volume is needed at all |
| Design storage solution | 🔲 | PVC is still 2Gi RWO Longhorn. Strategy is Recreate to avoid a multi-attach deadlock, which costs a few seconds of downtime per deploy |
Phase 7 — Reconciliation ✅ Complete¶
Shipped inside the dashboard, not as the separate heezy-finance-reconcile service originally
sketched. A dedicated service was not worth the operational cost for matching that runs in
milliseconds at request time.
| Item | Status | Notes |
|---|---|---|
| Reconcile page | ✅ | /reconcile, see Reconcile Tab |
| Receipt to transaction matching | ✅ | Exact (date, amount) key, done in Python at request time |
| Manual link and override | ✅ | POST /api/reconcile/link, receipts.bank_transaction_id |
| Inline category reassignment | ✅ | POST /api/reconcile/update-category, feeds spending and budget analytics |
| Acknowledge / hide rows | ✅ | bank_transactions.reconcile_acknowledged |
| Orphaned receipt surfacing | ✅ | Receipts in range with no matching transaction |
| Fuzzy matching (date ±2 days, amount within 1%, merchant similarity) | 🔲 | Match is still exact-only. Confidence scoring never built |
| Order to transaction matching | 🔲 | orders.bank_transaction_id exists but nothing populates it |
Phase 8 — Budgeting & Targets ✅ Complete¶
| Item | Status | Notes |
|---|---|---|
| Monthly per-category budgets | ✅ | spend_budgets, Budget page |
| Annual per-category budgets | ✅ | annual_budgets, keyed on (category, year), for lumpy categories |
| Fixed vs variable cost split | ✅ | FIXED_COST_CATS in categories.py |
| Daily Discord budget alerts | ✅ | heezy-budget-alerts CronJob, 14:00 UTC |
| Financial targets page | ✅ | Emergency fund, 529s, investments, mortgage payoff, retirement/FIRE. See Targets Tab |
| Mortgage statement ingest | ✅ | mortgage_statements table, 9 statements |
Phase 9 — Classification Quality ✅ Complete¶
| Item | Status | Notes |
|---|---|---|
Taxonomy moved to categories.py |
✅ | app.py and item_classifier.py share one list |
| Rules → cache → LLM pipeline | ✅ | item_category_cache, 135 entries. LLM is last resort, answers are stable across re-runs |
real to numeric migration |
✅ | Every money column is numeric |
| Merchant rules split one per chain | ✅ | Was rendering every Meijer, Costco and Aldi debit as a vendor named "grocery" |
Open Work¶
| Item | Priority | Notes |
|---|---|---|
Backfill 12 receipts with NULL date_ts |
Medium | They are invisible to every date-filtered query |
| Surface the silent balance-skip | Medium | upsert_account_balance() logs WARN when no account matches; the upload response says nothing |
| Add liveness / readiness probes | Medium | A pod that cannot reach Postgres still reports Running |
| Fuzzy reconcile matching | Low | Exact (date, amount) misses pending-vs-posted date drift |
FK from statements to accounts |
Low | Still matched by institution + last4 + type string |
Normalize bank_statements.statement_period_start/end |
Low | Raw PDF text |
| Capital One and Edward Jones backfill | Low | Cap1 stops at 2026-06, EDJ starts at 2026-05 |
Current DB State¶
Counts as of 2026-08-11.
| Table | Count | Notes |
|---|---|---|
orders |
284 | 25 distinct vendors, 7 without a grand_total |
order_items |
367 | Rule, cache, or LLM categorized |
receipts |
155 | 12 without date_ts |
receipt_items |
821 | |
bank_statements |
80 | BoA, Cap1, Chase, EDJ, one manual Venmo row |
bank_transactions |
1,582 | Dashboard shows debits only |
mortgage_statements |
9 | Fifth Third |
accounts |
27 | 17 active |
account_balances |
84 | |
spend_budgets / annual_budgets |
13 / 5 | |
item_category_cache |
135 |
Last updated: 2026-08-11