diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..260a740 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,46 @@ +# 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. diff --git a/README.md b/README.md index b7bdc5d..62d9582 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,23 @@ 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: + +```sh +./scripts/backup-db.sh +``` + +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 ```