Booky learns your timezone — a four-phase rebuild that lands in a single day
Until this commit, every date in Booky was reasoned in UTC under the hood. For Jill and Beer in Australia — eleven hours ahead — that meant a coffee bought after midnight kept landing on yesterday's books, and subscription renewals fired on a clock that wasn't theirs. This commit closes the gap, for everyone — not just AU. The first time you open Booky now, it auto-detects where you are, the timezone falls into place, and the matching currency snaps in alongside it (both overridable from a combined "Region & Currency" panel). Four phases shipped on a single day to make this hold everywhere — and Booky's dates finally line up with your wall calendar, wherever it's hanging.
Analysis page reacts to your filter — pick Expense, the chart actually changes
Picking All / Income / Expense at the top of the Analysis page now updates the chart and the cashflow numbers too — before this, the filter only changed the table below.
Mobile gets the rebuild it needed — proper bottom nav, real Profile page, back buttons everywhere
Bottom nav extracted into a single source so the four main pages stay consistent, the Profile page rebuilt from scratch with sectioned settings, sub-pages get back buttons, and a slide-up filter sheet replaces the desktop sidebar on History. Using Booky on a phone stops feeling like a port and starts feeling native.
Snap, look, rotate, then OCR — Booky finally lets you check the photo first
Up to this commit, snapping a receipt sent the photo straight into OCR. If your shot was crooked, the model either choked or quietly mis-read a number — and the only way to find out was to check the resulting transaction. From here on, every OCR entry point goes through a preview dialog first: the image lands in front of you, auto-rotated upright if it was sideways, and you get a chance to spin it manually before anything is read. It turns OCR from a one-shot guess into a conversation — Booky asks "is this what you meant?" before it commits.
Phase 2 OCR — batch upload + explicit Split mode
Multi-receipt batch upload lands. Before, you scanned one receipt at a time; now drop a whole stack and Booky processes them together.
Desktop OCR receipt linking + smart amount-mismatch dialog
Booky meets Mate
Up until now, Booky lived inside its own browser tab. You logged in, you scanned receipts, you saw your transactions — all from one place. From this commit on, Booky speaks. The Android client gets a way in. Mate gets a way in. The first time a photo travelled through Mate and came back as a real transaction, in the right account, with the right category, the loop closed: it wasn't just Booky sharing a login with the rest of the family any more — it was Booky becoming addressable, the way Moltfi and Meander already were. Joined the ecosystem properly.
Third rewrite + receipt OCR ships
Two big things in the same commit. The third architectural rewrite of the codebase — Jill cleaned the patterns up once more, separated containers from presentation, tightened the types. And buried in the same diff: receipt OCR. Snap a photo, get a structured transaction back. Worth pausing on the OCR side. Jill is a web designer by trade, not a coder. Building OCR used to be a serious programmer's job. She did it herself, with AI filling in the parts she didn't know. Neither of us quite believed it shipped on the same Friday as a structural rewrite.
Mobile / desktop architectural split
Live on the internet
First time Booky existed at a URL anyone could open. Up until this point it ran on Jill's laptop and our dev server, full stop. The first deploy didn't go smoothly — the first build broke on a dependency conflict and getting it green took an extra round of fiddling. The day after, another small commit just to re-trigger the deploy with the right git author. Deploys are like that. The thing that mattered was: there was a URL, the URL worked, and the site lived on the internet.
Dark mode + daily FX rate cron
The multi-currency story finally lines up. Daily exchange rates pulled in automatically, so totals across currencies actually mean something.
Trash Manager — soft-delete, restore, auto-purge
First real data-lifecycle feature. Implies trust in undo, not just trust in delete.
Per-row CSV import error collection
Plugged into everydays.tools — multi-user
Booky stops being something only Jill could log into. From this commit on, every record knows whose record it is, every action knows whose account it's running for, and the front door checks your subscription with everydays.tools before letting you in. Single-user prototype on day one; multi-tenant SaaS on this day. Same product, different shape underneath.
Recurring subscriptions — auto-generation + calendar projection
Bills don't pay themselves and people forget. Tracking them as data, not as memory.
Whole-app design system reset
Migrate icons → lucide-react
Splitting the backend monolith + retiring Python
Two big moves the same day. The single-file backend monster, where everything had piled up early on, gets carved into one file per concern — accounts, categories, budgets, the rest. Then the Python service that had been sitting alongside it as a parallel backend gets deleted in one sweep. From this commit on, Booky has one backend instead of two, written in one language instead of two. The polyglot phase ends here.
Virtual scrolling for transaction lists
Tried react-virtuoso, reverted, shipped batch mutations instead
Same afternoon, three commits: a WIP adding react-virtuoso, a revert with the message "unstable", and finally a fresh approach using useTransition + optimistic UI for the same scrolling problem. Shiny library lost. React primitives won. No extra dep.
Bidirectional reconciliation + editable split parents
Reconcile ships — Booky's killer feature
When you import a bank CSV, you might already have entered some of those transactions manually. Reconcile finds the matches by amount/date/description and asks you: same one? merge or skip? Without this, every import creates duplicates. With it, manual + automatic entry can finally coexist.
First reusable UI component — the category picker
Migrate Streamlit → Next.js
The bet: this is a real product, not a notebook. Time to commit to a frontend stack.
Streamlit Bank Import UI
First commit — PDF parsing from day one
A simple expense tracker on top, and underneath, a small Python helper that pulled transactions out of PDF bank statements. The PDF obsession was there before almost anything else. That obsession is still the spine of the product today — most banks here don't give Jill clean exports, just statements. Booky was born to deal with that.