Skip to content

Releases: natejswenson/local-budget

v0.3.0

Choose a tag to compare

@natejswenson natejswenson released this 30 Jul 17:20

Connector history

  • budget amazon backfill walks the full year range the ledger covers rather than a rolling window. Order history is year-scoped while the transactions page is days-back only, so orders backfill year by year and charges come in one long call — and the two can reach different distances into the past.
  • Resumable. A finished year is a row in the run ledger, so a job that dies partway keeps everything it stored and a re-run skips what is done. No new state.
  • The per-year gate needed an upper bound. Checking one year previously also counted every later year's charges, so a year that silently returned nothing still looked expected and the check passed vacuously — exactly where a long multi-year job most needs it.
  • Auth errors and bot challenges are never retried. A credential does not become valid on the third attempt, and re-hitting a challenge is how a soft block becomes a hard one. Transient failures back off and retry a bounded number of times.

Honest coverage

  • The reconciliation horizon is now a reported value. Matching goes through the retailer's own transaction records, and that page may not reach as far back as order history does. Charges older than the earliest stored transaction cannot be matched at all — so coverage now states how far back it actually works instead of reporting a low percentage with no explanation.
  • Deliberately not a fallback to matching on order totals: that would extend coverage by reintroducing the exact failure the matcher exists to prevent, since an order total frequently is not what settled on the card.

Purchases report

  • budget amazon report renders a standalone PDF of what was actually bought — grouped by kind, by month, biggest single items, repeat buys and top sellers.
  • Kept separate from the monthly budget report on purpose: that page is a fixed one-pager about a month, and hundreds of product titles would swamp it while answering a question its reader may not have asked.
  • Groupings are a keyword heuristic and the report says so on its face. The source carries no product category, so the rules stay visible and auditable rather than hidden behind a model call.
  • --since / --until scope it, and the range goes in the filename — a scoped render must not silently overwrite the all-history one.

Fixes

  • A split-shipment order matched several charges, so joining items through each of them counted the same product once per shipment and overstated every total.
  • Item prices are positive magnitudes; negating them rendered a whole report as if it were refunds.
  • A scoped report reported all-time coverage in its footer, describing a different document than the one being read.
  • Headings no longer orphan at the foot of a page, long tables may split while rows may not, and titles truncate on a word boundary rather than mid-word.

v0.2.0

Choose a tag to compare

@natejswenson natejswenson released this 30 Jul 15:12

Reports

  • The monthly PDF now renders in PRESS — the warm-paper editorial brand shared across the author's other tools. Flat cream paper edge to edge, ink rules for structure, and a single accent colour. Owned by report/brand.py and overridable via BUDGET_BRAND_FILE.
  • Bars are ink; over-budget is a mark, not a hue. The accent is spent on the overspend segment past the budget tick, so the colour is a measure of how far over a category went rather than a label saying it was.
  • Savings-type categories no longer set the bar scale. A large transfer into a floor category used to compress every ordinary spending row to a few pixels.
  • The report opens with a generated one-line summary instead of a bare grid of figures.

Amazon connector (new)

  • Pulls order and item detail for an account and reconciles it against the ledger, so an otherwise opaque marketplace charge can be explained line by line.
  • Matching goes through the retailer's own transaction list, not order totals — one order can ship in several boxes and settle as several charges days apart.
  • Ambiguity is never guessed. Two same-amount charges in the same window are recorded unmatched and surfaced for confirmation; a wrong match would attribute the wrong basket to a charge.
  • Coverage is reported in dollars, not transaction count — nine small matches and one large miss is not "90% covered".
  • Authentication captures a browser session rather than storing a password, so passkey-only accounts work and no reusable credential lands on disk.
  • A sync that returns nothing while the ledger shows charges in the window aborts and writes nothing, rather than reporting an empty month.

Transaction splits (new)

  • One charge can be apportioned across several categories, so a mixed order stops counting entirely against whichever category its merchant rule assigned.
  • Aggregates read an effective_txns view; an unsplit row yields itself, a split row yields one line per split.
  • A transaction's splits must sum to its amount exactly — enforced on write and auditable at any time via budget verify-splits. A violation would invent or destroy money in every total downstream, silently.
  • Item prices are scaled proportionally to what was actually charged, so every cent lands on a real line and no synthetic adjustment row appears.
  • Categories are never inferred in code; allocation is proposed and confirmed, never assumed.

Security and privacy

  • Sync error messages are read-denied to the agent layer, matching the existing treatment of import errors — a stored exception can embed the values it was binding.
  • Connector data is written as immutable imported fact; the agent can read it and never write it.
  • Example data, comments and documentation were scrubbed of real values throughout.

Automation

  • Adopted a devmain promotion model with auto-merge on green, branch cleanup on merge, and a manual gate before any release is tagged.
  • main now requires a passing check and forbids force-pushes and deletion; dev stays push-open but deletion-locked.

v0.1.1

Choose a tag to compare

@natejswenson natejswenson released this 30 Jul 04:23

Bug fixes

  • Recurring/anomaly detection now collapses bank-descriptor drift. Bank statements label the same merchant differently over time (e.g. Hulu as HLU HULU.COM BILL, HULU, HULU SANTA MONICA), which fragmented recurring-charge detection and silently dropped subscriptions like Hulu and Netflix out of the "Subscriptions & recurring bills" report section. Detection now groups by the existing canonical-merchant alias instead of the raw, drifting descriptor.
  • Floor-marked spend categories (e.g. Investments) now report as savings, not spend. Money moved into an investment account was counted as ordinary spend, dragging "Net" deeply negative even though the money never left the user's own accounts. Floor-marked categories now report in a separate Savings bucket; Net reflects ordinary cash flow (income − spend), independent of how much also went to savings that month.

Full Changelog: v0.1.0...v0.1.1