It's been a while since I last posted here — sorry for the gap. Here's a catch-up covering v1.4.1 through v1.4.6. v1.4.5 (26 AUG) — BACKUP, EXPORT, AND A SAFETY NET FOR UPGRADES This is the headline release, and it's a big one for data safety. You can now export your own data from Settings — a full database backup, a full JSON export, or your transactions as CSV. More importantly: whenever a future update needs to change the database structure, Tally now takes a snapshot first and verifies it can be read back before touching anything. If that snapshot can't be produced and verified, Tally refuses to start rather than migrate your data unprotected. Snapshots are rotated automatically so the backup folder doesn't grow forever, and any partial file from an interrupted run gets cleaned up on the next start. There's a new Backup & Restore guide in the docs covering how to restore a snapshot by hand: https://github.com/jaydenroberts/tally/blob/main/docs/backup-restore.md Also in this release: the twelve-month trend chart was disagreeing with the headline spend figure for any month containing a debt payment — that's fixed, and as a result, if you record debt payments, those months on your trend chart will now read higher than before. The old figures were too low (a debt payment was being counted as spending when it shouldn't have been). Your headline income/spend numbers are unchanged, this only affects the chart. Spending/income totals are also now worked out from an explicit list of what counts, rather than a list of what to exclude, so a new transaction type can't silently get miscounted until every calculation is updated by hand. Known limitation carried forward: income and spending are still split by whether an amount is positive or negative rather than by its actual type, so a refund still shows as income rather than reducing spending. Fixing that properly needs the import pipeline to label rows first — tracked for later. v1.4.6 (25 SEP) — PLATFORM AND DEPENDENCY UPDATE, NOTHING VISIBLE CHANGED This one's under the hood. Almost every commit in this release is a dependency or platform bump — no application logic changed. The only first-party edits are the version number itself and a new version field on the health endpoint. The reason to update anyway: the interpreter and every major library were getting old, and the published image now passes a clean vulnerability scan with no fixable critical or high findings and no waivers. What moved: Python goes from 3.11 to 3.14 on the server, and the frontend build image from Node 20 to 26. In the browser bundle, React goes from 18 to 19, the router from 6 to 7, and the Vite build tool from 6 to 8. On the backend, FastAPI, Starlette, Pydantic, SQLAlchemy, bcrypt, pandas, axios, pytest, and both AI provider SDKs (OpenAI and Anthropic) all moved up. The HTTP client underneath the AI SDKs changed too: both SDKs dropped plain httpx for httpx2, which is pinned above the versions affected by two published advisories. New in this release, and genuinely useful for bug reports: the container now tells you which version it's running. The health endpoint reports it, and the image carries a Docker healthcheck that calls it. Because the latest tag gets republished every release, there was previously no way to tell which build a running container was actually on. Four things to know before you update: - pip is gone from the finished image. If you've ever run something like docker exec -it tally pip install <package> to add a Python package by hand, that will stop working. Stock Tally doesn't need it for anything; if you were relying on it for a personal customisation, you'll need to build your own image with that package added at build time instead. - The Python interpreter is now 3.14, up from 3.11. This changes nothing about how you use Tally, but if you've built any external script or automation against the container's Python directly, check it against 3.14 rather than assuming 3.11 behaviour. - The web interface is now built on React 19, up from 18. Nothing about the workflow changes — this is here so that if you notice anything render slightly differently, you know why. - An API request with no login token now returns 401 instead of 403. This comes from the FastAPI upgrade and applies to every authenticated endpoint. The web interface is unaffected — it already sent you to the login page on a 401. But if you've got a monitoring check or a script that tests for 403 on an unauthenticated call, switch it to expect 401. One thing worth planning for: on first start after updating, Tally writes an automatic snapshot of your database to /data/backups/pre-1.4.6.db, roughly the same size as your database. That's the v1.4.5 safety net doing its job. If it can't write that snapshot — no space, or the data path isn't writable — the container will refuse to start rather than carry on unprotected. So make sure your appdata share has room before you update. There's no database structure change in this release, so there's nothing to migrate; the snapshot is belt-and-braces. There's no automated test suite for the interface yet, so before this went out every page was driven through a real browser against the released image with the console open, on a database seeded with accounts, transactions, budgets, savings goals, debts and recurring entries. No errors, and every figure on screen matched the API. That's not the same as a human eyeballing every pixel, so if something looks off after updating, it's worth a bug report — this release's whole point is that a problem has very few likely causes, since nothing else changed. Also refreshed alongside this release: the Community Applications template. It drops a volume that hadn't done anything for several versions, exposes the backup and AI settings that were previously undocumented, and fixes a default that quietly gave new installs a shorter AI chat memory than intended. Note the default host port for NEW installs is now 8092 rather than 8091 — if you already have Tally installed, nothing changes for you and your existing port is kept. SECURITY — IF YOU'RE ON v1.4.1 OR OLDER, UPDATE. HERE'S WHY. Two fixes worth being direct about, both already shipped: v1.4.1.1 fixed an unauthenticated path-traversal hole in the static file server. The single-page-app fallback route was serving any file path it was handed without checking that the file actually lived inside the app's static directory — a crafted request could read files outside it, including the application database. That's now fixed: requested paths are resolved and confirmed to stay inside the static root before being served. v1.4.4.1 closed a set of vulnerabilities in third-party libraries Tally depends on — a denial-of-service weakness in the multipart form parser, an algorithm-confusion risk in the JWT library, a header-injection/request-routing weakness in the HTTP client, and a version pin on the PDF text-extraction library. No app behaviour changed, just the dependency versions. If your container is still on v1.4.1 or earlier, update it — this post is the first time I'm flagging either one here. WHAT ELSE LANDED SINCE v1.4.0 Import matching got smarter across a couple of releases: it's now merchant-aware (so a bank row can't validate the wrong manual estimate just because the amount and date happened to line up), uncertain matches get surfaced for you to confirm instead of guessed at, debt payments reconcile against your estimates the same way ordinary spending does, and the review step now shows what will merge versus what's genuinely new before you commit. AI chat conversations now persist — a session sidebar to reopen past chats, automatic titles, delete when you're done with one. Recurring transactions generate on a daily timer now instead of only at startup, so a long-running instance doesn't need a restart to catch up on due entries. And v1.4.2 was a broad security-and-correctness audit pass: CORS locked down to an explicit allow-list, login rate-limiting, the container no longer runs as root, password changes now invalidate existing sessions, plus a large batch of money-accuracy fixes (deleting a transaction linked to a debt payment or savings goal now correctly reverses that money, transfers and debt payments no longer distort your income/expense totals, and more). Full line-by-line detail is in the changelog if you want it. UPGRADING Community Applications: open the Tally entry and hit Update. Or manually: docker pull jaydenroberts/tally:latest and recreate the container. This is safe and in-place from any 1.4.x version — database migrations run automatically, no manual steps. v1.4.6 doesn't change the database structure, so there's nothing to migrate for this one, though it will still write the safety snapshot described above. And as of v1.4.5 the upgrade protects itself: if a future version needs to change the database structure, it snapshots and verifies first, and won't proceed if that fails. NEW ENVIRONMENT VARIABLES SINCE v1.4.0 All optional, all with sensible defaults — nothing breaks if you don't set them: ALLOWED_ORIGINS — comma-separated list of origins allowed to call the API from a browser. Only needed if you access Tally from a hostname other than the default local one. MAX_UPLOAD_BYTES — max size of a statement file you can upload through the import wizard. Defaults to 10 MB. CHAT_HISTORY_TURNS — how many prior turns of a conversation get replayed as context to the AI. Defaults are provider-aware (30 for hosted APIs, 10 for local Ollama). No new ones in v1.4.6, though several existing ones are now surfaced in the Community Applications template that previously weren't — the backup settings in particular. ONE DEPLOYMENT NOTE — SINGLE-TENANT BY DESIGN Worth stating clearly, since Tally has an owner/viewer role system: those roles limit what actions a user can take, not what data they can see. Any authenticated user, owner or viewer, can see all accounts and transactions in the instance. That's deliberate rather than an oversight — I built Tally for my own family, where everyone under the login set already shares the same finances. It does mean it isn't suited to running as a general multi-user service. I don't run mine on the open internet, and my recommendation is to keep yours on your LAN or behind a private tunnel or VPN. LINKS Full release notes: https://github.com/jaydenroberts/tally/releases/tag/v1.4.5 and https://github.com/jaydenroberts/tally/releases/tag/v1.4.6 Docs: https://github.com/jaydenroberts/tally/tree/main/docs Issues: https://github.com/jaydenroberts/tally/issues STILL ACTIVE, MORE COMING This is still actively worked on — it's not a dump-and-abandon project. There's more on the way, including cleaning up the income/refund handling mentioned above. I'd genuinely like to hear from anyone running this: what's awkward to use day to day, what you wish it did that it doesn't, and especially what bank statement formats are giving the importer trouble — that's the area most dependent on seeing real-world files I don't have. Bug reports are welcome too, same as always. Post here or open an issue.