# Backup SQLite (T2/P0-4) ## Ce se salveaza si de ce Baza SQLite (`AUTOPASS_DB_PATH`, prod `/data/autopass.db`) e sistemul legal de evidenta al declaratiilor RAR AUTOPASS (Legea 142/2023). `FINALIZATA` e **terminal** la RAR — nu exista anulare/corectie prin API. Pierderea volumului fara backup inseamna, la restaurare dintr-un mediu gol, retrimiterea acelorasi randuri si duplicate pe care RAR le accepta fara sa poata fi corectate. De aceea backup-ul e trigger dur: **configureaza-l inainte de prima declaratie reala in prod**, nu dupa. Backup-urile sunt criptate (gpg AES256) pentru ca snapshot-ul contine PII criptat Fernet (nume, VIN, date client) plus metadate — un backup necriptat pe disc/remote ar fi un al doilea loc unde datele astea pot scapa. ## Rulare manuala ```bash # in container (api sau worker, acelasi image + volum): docker compose exec api bash tools/backup_db.sh # local (dev), cu parola de test: AUTOPASS_DB_PATH=./data/autopass.db \ AUTOPASS_BACKUP_DIR=./data/backups \ AUTOPASS_BACKUP_PASSPHRASE_FILE=/cale/catre/parola \ bash tools/backup_db.sh ``` Scriptul foloseste `sqlite3.Connection.backup` (online, sigur cu WAL activ — NU `cp`), comprima (gzip) si cripteaza (gpg simetric). Fara `AUTOPASS_BACKUP_PASSPHRASE_FILE` sau `AUTOPASS_BACKUP_PASSPHRASE` seteaza, scriptul **refuza** sa scrie un backup necriptat si iese cu cod diferit de 0. Pastreaza ultimele `AUTOPASS_BACKUP_KEEP` (implicit 14) fisiere in `AUTOPASS_BACKUP_DIR` (implicit `/data/backups`, pe volumul persistent). Daca `AUTOPASS_BACKUP_RCLONE_REMOTE` e setat si `rclone` e disponibil, urca automat backup-ul nou catre remote (off-site); altfel sare peste, cu log explicit. ## Programare Doua variante, alege una: 1. **Serviciu compose optional** (`docker-compose.yml`, serviciu `backup`, profil `backup`, comentat implicit) — ruleaza scriptul intr-o bucla cu `sleep 86400` in propriul container, pe acelasi volum `autopass-data`. Activare: ```bash docker compose --profile backup up -d backup ``` sau, in Dokploy, seteaza `COMPOSE_PROFILES=backup` in mediul aplicatiei. Preferata pentru un deploy Dokploy: calatoreste cu image-ul si nu depinde de acces SSH separat la hostul care ruleaza containerele (host care in Dokploy poate fi gestionat/efemer). 2. **Cron pe host** — daca ai acces SSH direct la masina care ruleaza containerele: ```cron 0 3 * * * cd /cale/catre/autopass && docker compose exec -T api bash tools/backup_db.sh ``` In ambele cazuri, parola de criptare trebuie sa fie accesibila containerului (secret montat, indicat prin `AUTOPASS_BACKUP_PASSPHRASE_FILE`) — nu doar in mediul shell al cron-ului de pe host. ## Restaurare (pas cu pas) 1. **Opreste worker-ul** (`docker compose stop worker`) — altfel worker-ul poate scrie in baza in timp ce o inlocuiesti, sau poate re-prelua randuri `sending` in timp ce restaurarea e pe jumatate facuta. 2. Alege backup-ul de restaurat (fisier `autopass-YYYYmmdd-HHMMSS.db.gz.gpg` din `AUTOPASS_BACKUP_DIR`). 3. Decripteaza + dezarhiveaza intr-un fisier temporar (NU suprascrie direct baza vie): ```bash gpg --batch --decrypt --passphrase-file /cale/catre/parola \ --output /tmp/restore.db.gz autopass-20260706-030000.db.gz.gpg gzip -d /tmp/restore.db.gz ``` 4. Verifica integritatea inainte sa promovezi fisierul (vezi sectiunea urmatoare). 5. Muta fisierul verificat peste `AUTOPASS_DB_PATH` (backup-uieste intai baza curenta daca mai exista, chiar corupta — pastreaz-o pentru investigare). 6. Porneste din nou worker-ul (`docker compose start worker`). ## Verificare (restore_check) Un backup neverificat nu e backup. `tools/restore_check.sh` decripteaza + dezarhiveaza cel mai recent backup (sau unul explicit, ca argument) intr-un fisier temporar si ruleaza `PRAGMA integrity_check` + `SELECT count(*) FROM submissions`. Iese cu cod diferit de 0 daca decriptarea, integritatea sau interogarea esueaza. ```bash AUTOPASS_BACKUP_PASSPHRASE_FILE=/cale/catre/parola tools/restore_check.sh # sau explicit: tools/restore_check.sh /data/backups/autopass-20260706-030000.db.gz.gpg ``` Ruleaza-l periodic (ex. dupa fiecare backup programat) — un backup care nu se poate restaura si verifica nu ofera nicio garantie reala. ## Unde stau parolele Parola de criptare (`AUTOPASS_BACKUP_PASSPHRASE_FILE`) e un secret separat de `AUTOPASS_CREDS_KEY` (Fernet, creds RAR) — nu le refolosi una pe cealalta. In prod, monteaz-o ca fisier secret (nu variabila de mediu inline in `.env` necriptat pe disc) si restrictioneaza accesul la fisier. `AUTOPASS_BACKUP_PASSPHRASE` (variabila inline) e doar pentru teste locale/CI, nu pentru prod.