Background jobs
The daily jobs inside the msaving container: purge, backup, exchange rates.
app/launch.py starts the daily scheduler (backend/app/jobs/scheduler.py)
next to the API in the same container. It runs the jobs once at start, then every day at JOBS_HOUR (UTC,
default 19 = 02:00 in Vietnam), in this order, each as its own process so one failing doesn’t stop the others.
Each logs in with its own database role and can do only its own job. Output goes to the container’s log
(docker compose logs msaving).
| Job | Module | Login | Does |
|---|---|---|---|
| purge | app.jobs.account_deletion |
purge_login (account_purger) |
Purges accounts closed more than 30 days ago; deletes sessions unused for 30 days and old invites and reset links |
| backup | app.jobs.backup |
the database owner | pg_dump of the app (schemas public and msaving) into /backups; deletes dumps older than about 5.5 days |
| rates | app.jobs.fx_update |
fx_login (fx_updater) |
open.er-api.com (no key), currency-api if that fails, or Open Exchange Rates with OXR_APP_ID; writes fx_rates; safe to re-run |
The launcher also takes a backup before an update applies new migrations.
Account purge, in short
- A user deletes their account: it closes at once, restorable for 30 days.
- After 30 days the job deletes books only they used, keeps shared books (handing ownership to someone who stays), reduces their user row to a bare id, deletes their password, two-factor secret, recovery codes and sessions, and frees their username.
- It writes purged ids to
PURGE_LOG(/backups/purged_accounts.jsonl, outside the database) before committing. - After restoring a backup:
docker compose exec msaving python -m app.admin repurgepurges those ids again.
Backups
Owner-only files in the backups volume, about 6 days kept. They’re on the same disk as the server, so the
README tells operators to copy them elsewhere. Restore steps: the README, and the docstring of
backend/app/jobs/backup.py (its $ lines are run by the tests).
More: Deleting an account and Currencies and exchange rates.