# Backup and Restore Guide

## Backup scope

A usable backup must contain:

- The MySQL/MariaDB database.
- `storage/app/private` attachments and POD files.
- `storage/app/public` logos and stamps.
- The deployed release and its `VERSION` file.
- A securely stored copy of `.env` and encryption key, separate from the public backup.

## Recommended schedule

- Database: at least daily, with more frequent snapshots for active operations.
- Attachments: daily incremental and weekly full backup.
- Pre-upgrade: immediate database and attachment backup.
- Retention: daily, weekly and monthly tiers based on company policy.
- Keep one encrypted off-server copy.

## Example database backup

```bash
mysqldump --single-transaction --routines --triggers --default-character-set=utf8mb4 \
  -u DB_USER -p DB_NAME | gzip > transport-$(date +%F-%H%M).sql.gz
```

## Restore procedure

1. Put the application in maintenance mode.
2. Restore to an empty staging database first.
3. Restore private/public storage using matching backup timestamps.
4. Restore the original `APP_KEY`; otherwise encrypted credentials cannot be read.
5. Run `php artisan optimize:clear`.
6. Run migrations only when restoring into the intended release version.
7. Run `php artisan accounting:integrity-check` and the report reconciliation checks.
8. Validate sample invoices, bills, party balances, attachments and PDFs.
9. Return live service only after sign-off.

Perform and document a restore test regularly. An untested backup is not a disaster-recovery plan.
