# Backup & Restore

## What must be backed up

| Item | Path | Contains |
|---|---|---|
| Database | MySQL `CPANEL_USER_fxtcrm` | contacts, campaigns, events, suppression, settings, users |
| Environment | `~/fxt-crm-app/.env` | credentials, APP_KEY (**without APP_KEY encrypted settings and 2FA secrets are unrecoverable**) |
| Uploads | `~/fxt-crm-app/storage/app/` | in-flight import files, branding logo |

Application code is reproducible from the release zip — data is not.

## Automated backups (recommended setup)

1. **cPanel → Backup Wizard** (or JetBackup on most Namecheap plans): enable daily
   account backups; download a full backup monthly and store off-server.
2. **Database dump via cron** (extra safety, keeps 14 days):

```cron
30 1 * * * /usr/bin/mysqldump -u CPANEL_USER_fxtcrm -p'DB_PASSWORD' CPANEL_USER_fxtcrm | gzip > /home/CPANEL_USER/backups/fxtcrm-$(date +\%u).sql.gz
15 1 * * 0 cp /home/CPANEL_USER/fxt-crm-app/.env /home/CPANEL_USER/backups/env-$(date +\%Y\%m\%d).bak
```

Create `~/backups` first (`mkdir -p ~/backups && chmod 700 ~/backups`) — it lives outside
the web root. Weekday-numbered dumps rotate automatically (7 dailies); download them
off-server regularly.

## Manual backup (before every upgrade)

```bash
cd ~
mysqldump -u CPANEL_USER_fxtcrm -p CPANEL_USER_fxtcrm | gzip > backups/pre-upgrade-$(date +%Y%m%d).sql.gz
cp fxt-crm-app/.env backups/env-pre-upgrade-$(date +%Y%m%d).bak
tar czf backups/storage-app-$(date +%Y%m%d).tgz fxt-crm-app/storage/app
```

## Restore procedure

1. Put the site in maintenance: `cd ~/fxt-crm-app && php artisan down`
2. Restore code (if needed): extract the release zip to `~/fxt-crm-app`.
3. Restore `.env` from backup; verify `APP_KEY` matches the backup era.
4. Restore the database:

```bash
gunzip < ~/backups/fxtcrm-N.sql.gz | mysql -u CPANEL_USER_fxtcrm -p CPANEL_USER_fxtcrm
```

5. Restore uploads: `tar xzf ~/backups/storage-app-DATE.tgz -C ~/`
6. Clear caches and reopen:

```bash
php artisan config:cache && php artisan route:cache && php artisan view:cache
php artisan up
```

7. Verify: login works, System Status green, campaign/contact counts look right.

**Test a restore at least once** on a staging subdomain — a backup that has never been
restored is a hope, not a backup.

## Upgrade procedure

1. Manual backup (above).
2. `php artisan down`
3. Extract new release over `~/fxt-crm-app` (never overwrite `.env` or `storage/`).
4. `composer install --no-dev --optimize-autoloader` (if composer.lock changed).
5. `php artisan migrate --force`
6. `php artisan config:cache && php artisan route:cache && php artisan view:cache`
7. Layout Option B only: re-copy `public/build/` to the document root.
8. `php artisan up`, then run the post-deployment checklist in NAMECHEAP_DEPLOYMENT.md.

Rollback = restore procedure with the pre-upgrade dump.

## Data retention

*Settings → General → Data retention*: when enabled, a daily job prunes
`campaign_events`, `provider_webhooks`, `import_rows` and `cron_runs` older than the
configured number of months (default 24). Contacts, campaigns, suppression records and
audit logs are **never** auto-pruned. Contact deletion tools (single + bulk) satisfy
GDPR erasure requests — remember the suppression list intentionally retains the bare
email address as a legal do-not-contact record.
