# Backup, restore and rollback

## 1. What is backed up

`scripts/backup-all.sh` runs nightly by cron, and also before every upgrade and adoption. It saves:
- the **central database**;
- **every business database**, each dumped with its own credentials (`--single-transaction`, routines, triggers, events, `--hex-blob`);
- both `.env` files and the tenant registry;
- a `SHA256SUMS` file.

The newest 7 backups are kept in `~/kaabe-backups/`.

**Copy backups off the server regularly.** A backup on the same server does not protect against losing the server.

## 2. Manual backup now

```bash
bash ~/kaabe/scripts/backup-all.sh
```

## 3. Restore one database

This example restores into a **new, empty** database first, then compares. Never restore over a live database without a fresh backup of it.

```bash
cd ~/kaabe-backups/<timestamp> && sha256sum -c SHA256SUMS
# create an empty database + user in cPanel → MySQL Databases (e.g. <cpaneluser>_restoretest)
gzip -dc <business>__<db>.sql.gz | mysql -u <cpaneluser>_restoretest -p <cpaneluser>_restoretest
M7_DB_PASSWORD='<password>' php ~/kaabe/migration/m7_profile.php --host=localhost --db=<cpaneluser>_restoretest \
  --user=<cpaneluser>_restoretest --label=restored --out=/tmp/restorecheck
```

To replace a business database with a backup:
1. Suspend the business in the Super Admin.
2. Back up its current state (§2).
3. Import the backup into the business database. In cPanel this is phpMyAdmin → Import, or the `mysql` command above with the business's database and user.
4. Resume the business.
5. Run `php artisan kaabe:sales-sync <slug> --reconcile=400` so the central totals match the restored data.

## 4. Rollback of a code upgrade

See `UPGRADE.md` (`scripts/rollback-release.sh`).

## 5. Rollback of an adoption (existing business such as `ssgplatforms_deeq`)

Adoption only **adds** objects, so rolling back removes only Kaabe's objects:
1. Super Admin → the business → *Suspend*, or point the old URL back to the old installation.
2. Run on the business database (phpMyAdmin → SQL). The IDs of the role templates Kaabe added are stored in `phppos_kaabe_meta.kaabe_templates_added`:
   ```sql
   SELECT value FROM phppos_kaabe_meta WHERE `key` IN ('kaabe_templates_added', 'platform_key_sha1');
   -- with the template ids from the first row (e.g. 7,8,9,10,11):
   DELETE FROM phppos_permissions_template_actions WHERE template_id IN (7,8,9,10,11);
   DELETE FROM phppos_permissions_template WHERE template_id IN (7,8,9,10,11);
   DELETE FROM phppos_permissions_templates WHERE id IN (7,8,9,10,11);
   DELETE FROM phppos_keys WHERE `key` = '<platform_key_sha1 value>';
   DELETE FROM phppos_app_config WHERE `key` IN ('kaabe_entitlements', 'kaabe_status');
   DROP TABLE IF EXISTS phppos_kaabe_location_meta, phppos_kaabe_meta;
   ALTER TABLE phppos_sales DROP INDEX kaabe_sale_time, DROP INDEX kaabe_last_modified;
   ```
3. **Passwords:** any password already upgraded to bcrypt works only with the Kaabe POS code. If the old code must run again, restore `phppos_employees.password` from the pre-adoption backup.
4. **Verify:** compare with the BEFORE profile made by `adopt-existing.sh`:
   ```bash
   php ~/kaabe/migration/m7_compare.php <adoption-folder>/before.json <new-profile>.json
   ```

`php artisan kaabe:rehearse` performs and verifies exactly this rollback on a temporary copy (`rollback.txt`, `rollback-validation.md`).

## Tested procedure (1.0.0)
Executed in the test environment:
1. `bash scripts/backup-all.sh` → folder with central + every business `.sql.gz`, `config.tar.gz`, `tenants.php`, `SHA256SUMS`; files are mode 600, folder 700.
2. `cd ~/kaabe-backups/<stamp> && sha256sum -c SHA256SUMS` → all OK.
3. Restore into a **new empty database** (`gzip -dc <file>.sql.gz | mysql -u <user> -p <newdb>`) → `migration/m7_profile.php` + `m7_compare.php` showed the copy identical to the live database (counts and checksums).
4. Disaster test: products and sales deleted in a business → Super Admin: suspend business → restore its dump **with the business's own database user** → reactivate → `php artisan kaabe:sales-sync <slug> --reconcile=400` → all products and sales back, owner signs in, central totals reconciled.
5. Adoption rollback (`kaabe:rehearse`): the copy returned to its exact pre-adoption state (54/54 measures identical).

