# Quartermaster (repo instructions) ## Database safety rule The SQLite database at `./quartermaster.db` (or whatever path `QUARTERMASTER_DB_URL` points at) holds real user data. It is `.gitignored`, so losing it means the data is gone. **Before any operation that interacts with the database at the schema or destructive level**, run: ```sh ./scripts/backup-db.sh ``` That includes: * `rm`, `mv`, truncate, or otherwise replace `quartermaster.db` * Ad-hoc `sqlite3` sessions that might `DROP`, `DELETE`, or `UPDATE` * Any script that does data migration or cleanup outside the running application Alembic runs `scripts/backup-db.sh alembic` automatically on every `alembic upgrade`, `alembic downgrade`, or `alembic revision --autogenerate` via the hook in `alembic/env.py`, so you do not need to call it manually for ordinary schema work. The hook is defense in depth, not a substitute for thinking. Routine writes through the running web application are NOT covered by this rule. Those are normal application behaviour, not "interactions" in the sense meant here. ## Where backups go Default: `/backups/quartermaster-YYYYMMDD-HHMMSS-{slug}.db`. For the standard `./quartermaster.db` that resolves to `./backups/`. Override with `QUARTERMASTER_BACKUP_DIR=/some/path`. The `backups/` directory is `.gitignored`. Retention is forever: backups are small. Prune manually if you need to. ## Restoring A backup is a complete SQLite file. To restore, stop the app, replace `quartermaster.db` with the chosen backup (`cp backups/... quartermaster.db`), then restart. ## Current Project State * **Phase**: shipped MVP + posting ledger. Working daily-use tool. * **Last worked on**: 2026-04-17 * **Last commit on main**: `19cac8f` — Backing transaction ledger: Postings replace the applied field (#20) * **Open PRs**: none * **Open issues**: none * **Test count**: 117 / 117 passing * **Migrations**: 5 applied; latest `cc60e7f73a1c` * **Blocking issues**: none After pulling new work, always: ```sh uv run alembic upgrade head ``` The backup hook fires before any migration, so this is safe against the live DB. ## Session Log Most recent 3 sessions (full history in the [wiki](https://forgejo.labbity.unbiasedgeek.com/archeious/quartermaster/wiki)). ### Session 1 — 2026-04-17 Greenfield to working ledger. 10 PRs merged in one sitting: scaffold (#2) → monthly view with snapshot + deviation (#4) → backups + CLAUDE.md safety rule (#6) → zero amount header (#8) → gitignore wiki (#10) → section groups + sinking funds (#12) → notes field (#14) → month lifecycle Planning / Active / Closed (#16) → UI redesign in Barlow Condensed with logo (#18) → posting transaction ledger (#20). Key architectural decisions: snapshot-over-mirror for months; Primary Debt Target is a pointer, not a pre-allocated amount; nothing auto-sweeps — close requires applied zero at $0; `applied` is derived from postings only, no column. UI went through three mockups before settling on Barlow Condensed + cream paper + burgundy accent sampled from the logo shield. One incident: I wiped the live DB several times during early dev churn before the backup script existed. The script + alembic hook + repo-level CLAUDE.md safety rule are the fix. Full retro: [Session1](https://forgejo.labbity.unbiasedgeek.com/archeious/quartermaster/wiki/Session1).