# 06 - Backup

## Scope

QuoteForge creates rotating local ZIP backups of:
- a consistent SQLite snapshot saved as `qfs.db`;
- `config.yaml` when present.

The backup intentionally does not include `local_encryption.key`.

## Location and naming

Default root:
- `<db dir>/backups`

Subdirectories:
- `daily/`
- `weekly/`
- `monthly/`
- `yearly/`

Archive name:
- `qfs-backp-YYYY-MM-DD.zip`

## Retention

| Period | Keep |
| --- | --- |
| Daily | 7 |
| Weekly | 4 |
| Monthly | 12 |
| Yearly | 10 |

## Behavior

- on startup, QuoteForge creates a backup if the current period has none yet;
- a daily scheduler creates the next backup at `backup.time`;
- duplicate snapshots inside the same period are prevented by a period marker file;
- old archives are pruned automatically.

## Safety rules

- backup root must be outside the git worktree;
- backup creation is blocked if the resolved backup root sits inside the repository;
- SQLite snapshot must be created from a consistent database copy, not by copying live WAL files directly;
- restore to another machine requires re-entering DB credentials unless the encryption key is migrated separately.

## Restore

1. stop QuoteForge;
2. unpack the chosen archive outside the repository;
3. replace `qfs.db`;
4. replace `config.yaml` if needed;
5. restart the app;
6. re-enter MariaDB credentials if the original encryption key is unavailable.
