Skip to content

Releases: aroesec/loot

v0.3.0

Choose a tag to compare

@aroesec aroesec released this 30 Aug 22:40

Images: ghcr.io/aroesec/loot:0.3.0

Added

  • Net worth on Buffer & goals, with how much of it is unknown stated alongside
    it. An account with no balance is counted as unknown rather than as zero, and
    the page says how many are missing — a linked current account beside an
    unlinked mortgage would otherwise read as a healthy figure that is wrong by
    the size of a house
  • Balances can be typed in on Settings, so net worth does not require linking a
    bank. A balance is the one thing a statement cannot tell the ledger
  • Budgets can carry their balance between months, per budget: carry what is
    left, carry both ways, or neither. Off by default, and switching it on is not
    retroactive
  • A business mileage log, rated by the day each trip was driven. Rates change
    mid-year — 2026 ran at 72.5¢ through June and 76¢ after — so a year's miles
    are summed per trip rather than multiplied by one rate. Shown on Schedule C
    but not added to the deductible total, because the standard rate replaces
    deducting what the vehicle actually cost rather than adding to it
  • Accounts and roster entries can be renamed and corrected after they are
    created
  • The split form arrives filled in the way you last split that merchant. It
    suggests and never applies — the same shop is 70/30 one week and entirely
    household the next, and the total cannot say which

Fixed

  • Security. A theme value could break out of the <style> element it is
    rendered into and run script on every page, including /login, which is
    served before anyone signs in. Setting one needs a session, so this was a way
    to persist rather than a way in. Values are now checked against what a token
    can legitimately be, at render as well as on save
  • Security. A password digest is now required to be the length the app
    produces. A hash truncated in transit was checked against a correspondingly
    shorter key and still accepted the password
  • The budgets header subtracted spending from the sum of the targets while the
    lines below used the carried figure, so the page disagreed with itself once
    anything rolled over
  • A mileage distance beyond what the column holds, and a date like 2026-13-45
    that is shaped right but is not a day, both reached Postgres and failed
    there. Both are refused by the form now

Changed

  • The JSON export carries the mileage log and the balance history
    (formatVersion 4). Plaid does not hand history back, so an export without it
    would lose the record permanently

v0.2.0

Choose a tag to compare

@aroesec aroesec released this 30 Aug 22:40

Images: ghcr.io/aroesec/loot:0.2.0

Added

  • Business logo, set during first run or from Settings, shown on business
    reports. PNG, JPEG or WebP up to 1MB
  • A team roster for business mode: employees and contractors, with name, type
    and an optional email. It is a contact list for your own reference — nothing
    in it is linked to a transaction or a report
  • Linking a bank is now offered during first run, not only afterwards in
    Settings

Changed

  • First-run setup asks personal-or-business as a choice you can switch at any
    point rather than a step you commit to. The fields below it change as you
    switch, so the other option is no longer behind a click
  • The JSON export now carries the team roster (formatVersion 2). The format
    only ever grows by adding keys, so anything reading version 1 still finds
    what it knew about
  • Only main deploys to Vercel now. A preview build needs DATABASE_URL and
    SESSION_SECRET, which are production-scoped and cannot be given to a fork,
    so the preview check had failed on every pull request this repo has had.
    docs/deploy.md explains how to turn previews back on with their own
    database

v0.1.1

Choose a tag to compare

@aroesec aroesec released this 27 Aug 17:53

A documentation and hygiene release. No behaviour changes.

  • The docs in 0.1.0 told you to pull ghcr.io/aroesec/loot:v0.1.0, which does
    not exist: docker/metadata-action strips the v, so the git tag v0.1.0
    publishes as 0.1.0. Corrected everywhere.
  • Removed a city name from a comment illustrating CSV escaping. It had already
    been scrubbed from the repo and came back in a later commit.
docker pull ghcr.io/aroesec/loot:0.1.1

Everything in 0.1.0
otherwise applies.

v0.1.0

Choose a tag to compare

@aroesec aroesec released this 27 Aug 01:22

First tagged release of Loot, a self-hosted personal finance ledger.

Running it

docker pull ghcr.io/aroesec/loot:0.1.0

Or from source: Node 22+, pnpm, and a Postgres database.

pnpm install
cp .env.example .env.local     # DATABASE_URL, APP_PASSWORD, SESSION_SECRET
pnpm db:migrate && pnpm db:seed
pnpm dev

Three variables and a database is the whole requirement. The model and bank
syncing are optional, and the app is fully usable without either.

What it does

Imports CSV and PDF statements, deduplicating by fingerprint so the same file
can be uploaded repeatedly. Classifies with merchant rules first and a model
second, and files anything it cannot place as Uncategorized rather than
guessing. Corrections teach rules and re-file matching history.

Credit card payments are excluded from spending and reconciled back to the
charges they settled, so a swipe and its payment do not both hit the budget.
Payments to cards the ledger cannot see are counted as debt rather than
silently dropped.

Budgets, recurring detection, spending trends, a cash buffer measured against
your own median month, and comparison against published national averages
adjusted for household size and region.

Business mode adds a profit and loss, quarterly periods, a Schedule C summary
with CSV export, and an estimated tax set-aside that keeps computed
self-employment tax visibly separate from the income tax rate you supply.

Optional Plaid syncing, web push and SMS alerts, an MCP server, verified
pg_dump backups, and full data export as CSV or JSON.

Notes

latest moves with main. Pin to 0.1.0 or a sha- tag for anything you
depend on. The image does not run migrations on start.

The major version stays at 0 until the schema settles.