Files
ced4568 b1b22b9285 feat(backup): encrypted Postgres backup/restore + off-host adapter
pg_dump -> gzip -> gpg AES-256 symmetric encryption, plaintext deleted
immediately, optional off-host rsync-over-SSH copy (Hetzner Storage Box or
any SSH target), retention pruning, Prometheus textfile-collector metrics
for backup success/age/size.

Genuinely tested end-to-end, not just written: real production migrations
(17 total, correct cross-service order) applied to a disposable Postgres,
sample data inserted, backed up, restored into a second disposable
Postgres, verified table-for-table and byte-for-byte. Exit 0.
2026-08-18 17:13:19 -05:00

27 lines
1.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Sanity-checks a restored database — confirms the expected Platform API schema landed and has
# data, not just that psql exited 0 (a restore that silently imported zero rows would still
# "succeed" by that measure). Used both by restore-postgres.sh's own suggestion and by
# test-backup-restore.sh's automated local test.
set -euo pipefail
DB_URL="${1:?usage: verify-restore.sh <db-url>}"
EXPECTED_TABLES=(students cohorts instructors sessions scenario_attempts assessment_definitions achievements audit_events)
FAIL=0
for t in "${EXPECTED_TABLES[@]}"; do
exists=$(psql "$DB_URL" -tAc "SELECT to_regclass('public.$t') IS NOT NULL")
if [ "$exists" != "t" ]; then
echo "MISSING TABLE: $t" >&2
FAIL=1
fi
done
if [ "$FAIL" = "1" ]; then
echo "FAIL: restored database is missing expected tables" >&2
exit 1
fi
MIGRATIONS_APPLIED=$(psql "$DB_URL" -tAc "SELECT count(*) FROM schema_migrations" 2>/dev/null || echo 0)
echo "OK: all expected tables present. $MIGRATIONS_APPLIED migrations recorded in schema_migrations."