MSaving

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

  1. A user deletes their account: it closes at once, restorable for 30 days.
  2. 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.
  3. It writes purged ids to PURGE_LOG (/backups/purged_accounts.jsonl, outside the database) before committing.
  4. After restoring a backup: docker compose exec msaving python -m app.admin repurge purges 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.

Edit this page · Report a problem