Add developer-only restore simulation harness
Some checks failed
CI / backend (push) Has been cancelled
CI / naming (push) Has been cancelled
CI / gates (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / lean-build (push) Has been cancelled

FOR DEVELOPER USE ONLY. Adds a live restore round-trip diagnostic that fingerprints every base table via CHECKSUM TABLE, backs up and restores through the real sentinel path, and proves all 110 tables return to backup-time state.

Documents expected drift so future runs are not misread: apitokens last-used churn, external endpoint-agent writes (computers/endpointstates/events/applications) that cannot be quiesced, and that live asset-row deletion is not permitted under RESTRICT/CMMC. Restore remains a full drop-and-recreate replace, so a missing or corrupted asset is still fully restored - verified, no restore.sh change needed.

Writes simulate-restore-results.txt to the script dir and ships a lightweight README with the testing cadence and parameters.
This commit is contained in:
benjamin.baker
2026-09-04 05:01:03 -04:00
parent debe1fce69
commit 3c9321f16c
3 changed files with 284 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
# Restore Simulation (FOR DEVELOPER USE ONLY)
`simulate-restore.sh` is a developer diagnostic that proves the backup/restore
pair round-trips the live database. It is NOT an operator tool and NOT part of
the shipped feature. It mutates a live database on purpose - never run it
against production or anything you cannot disturb.
## Testing cadence
- Before merging any change to `scripts/backup/*.sh`, `docker-compose.backup.yml`,
or `shopdb/core/api/shopdbbackups.py`.
- Before cutting a release that touches the backup/restore surface.
- After a schema migration that adds or drops tables (new table archetype).
- Ad hoc when investigating a restore-fidelity concern.
## What it does
1. Requests a backup through the real `.backup-requested` sentinel.
2. Fingerprints every base table with `CHECKSUM TABLE` (the restore target).
3. Quiesces the `api` service, mutates the table archetypes:
- core standalone (vendor rename, setting flip)
- consumable ledger (`modelsupplies.quantityonhand` bump)
4. Requests a restore through the real `.restore-requested` sentinel.
5. Re-fingerprints and asserts every table returned to backup-time state.
6. Writes `simulate-restore-results.txt` next to the script.
## Testing parameters
- Stack must be up with the backup profile:
`docker compose -f docker-compose.yml -f docker-compose.backup.yml --profile backup up -d`
- Run from git bash on the host: `bash scripts/backup/simulate-restore.sh`
- Coverage: all `BASE TABLE` rows in `shopdb_flask` (110+ tables), one pass.
## Expected drift (NOT failures)
- `apitokens`: the app rewrites token last-used continuously; restore is
correct at backup time.
- Endpoint-agent tables (`computers`, `endpointstates`, `endpointevents`,
`endpointapplications`): external fleet agents keep writing after restore and
cannot be quiesced from here.
- Asset ROW deletion is not permitted in a live/CMMC environment (RESTRICT +
compliance). The cascade edge is reported informationally only. A missing or
corrupted asset is still fully restored because the dump drops and recreates
the table - restore fidelity does not depend on a live delete.