Household budget tracker: sections for incomes, bills, debt, essentials, subscriptions. FastAPI + HTMX + SQLite.
Find a file
archeious 0f2f549d85 feat(notes): render and wire notes inputs on budget and month pages
Each entry row gains a secondary notes row with an inline-editable
text input. Budget entries post to a new /entries/{id}/notes
endpoint; month entries reuse the existing update route. Add forms
gain an optional "notes (optional)" input that spans the form row.
Notes render muted with a dashed underline on hover to signal
editability without cluttering the layout. Changing notes on a
month row does not flip the deviation state since the financial
values are unchanged.

Refs #13

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 12:51:31 -06:00
alembic feat(db): add nullable notes column to entry and month_entry 2026-04-17 12:51:22 -06:00
scripts feat(ops): add backup-db.sh for safe sqlite snapshots 2026-04-17 11:51:46 -06:00
src/quartermaster feat(notes): render and wire notes inputs on budget and month pages 2026-04-17 12:51:31 -06:00
tests test: cover group mapping, subtotals, default state, and OOB swaps 2026-04-17 12:44:21 -06:00
.gitignore chore: gitignore the local wiki checkout 2026-04-17 12:14:52 -06:00
.python-version chore: init uv project with FastAPI, SQLAlchemy, Alembic 2026-04-17 11:03:59 -06:00
alembic.ini feat(db): add Entry and DebtTarget models with initial migration 2026-04-17 11:04:06 -06:00
CLAUDE.md docs: document DB safety rule in CLAUDE.md and README 2026-04-17 11:51:52 -06:00
LICENSE Initial commit 2026-04-17 10:57:47 -06:00
pyproject.toml chore: init uv project with FastAPI, SQLAlchemy, Alembic 2026-04-17 11:03:59 -06:00
README.md docs: document monthly view, updated layout, and deferred work 2026-04-17 11:57:30 -06:00
uv.lock chore: init uv project with FastAPI, SQLAlchemy, Alembic 2026-04-17 11:03:59 -06:00

quartermaster

Household budget tracker. FastAPI + HTMX frontend, SQLite backend.

Pages

  • / budget configuration. One section per category (Incomes, Fixed Amount Bills, Debt Minimums, Primary Debt Target, Food and Essentials, Subscriptions, Other). Every section accepts name + amount entries and shows a running total. The Primary Debt Target is a pointer to a Debt Minimums row.
  • /month/YYYY-MM monthly view. Snapshots the budget at creation time and tracks an applied amount per entry alongside the planned amount. Each row is annotated when its name or planned value has been edited away from the snapshot, or when the row was added after creation. Per-month debt target is independent of the budget's target after snapshot.

Navigate between months with the prev / next buttons or the dropdown picker. A "This month" link on / jumps to the current YYYY-MM; if it has not been created yet, you land on the create flow.

Requirements

  • Python 3.12+
  • uv for dependency management

Setup

uv sync
uv run alembic upgrade head

The SQLite file lives at ./quartermaster.db by default. Override with the QUARTERMASTER_DB_URL environment variable (any SQLAlchemy URL).

Run

uv run uvicorn quartermaster.main:app --reload

Open http://127.0.0.1:8000.

Tests

uv run pytest

Tests run against an in-memory SQLite database; no migration step needed.

Backups

The SQLite data file is precious and gitignored. Before any schema change or destructive operation, back it up:

./scripts/backup-db.sh <reason>

Backups land next to the database in ./backups/ by default (QUARTERMASTER_BACKUP_DIR=/some/path to override) as quartermaster-YYYYMMDD-HHMMSS-{slug}.db using SQLite's online backup API (safe even while the app is writing). Alembic invokes the script automatically before every migration via alembic/env.py; retention is forever for now. To restore, stop the app, copy the chosen backup over quartermaster.db, and restart.

Project Layout

src/quartermaster/
  main.py            FastAPI app factory
  routes.py          Budget configuration HTTP handlers
  routes_month.py    Monthly view HTTP handlers
  service.py         Budget queries, totals, target logic
  month_service.py   Snapshot, deviation, per-month CRUD
  models.py          SQLAlchemy models and Section enum
  db.py              Engine, session, PRAGMA foreign_keys=ON
  config.py          DB URL resolution
  templates/         Jinja2 templates (base, index, month, partials)
  static/            CSS
alembic/             Migrations
tests/               pytest suite

Deferred

A transaction log that rolls up into applied on a per-entry per-month basis is deferred. Once implemented it may replace the hand-edited applied field.