Repository Public MIT
1#!/bin/bash2# Restore drill: load the newest dump into a scratch database, verify row counts and every blob checksum, then drop it.3set -euo pipefail4cd "$(dirname "$0")/.."5export PATH="/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:$PATH"6set -a; . ./.env; set +a7BACKUP_DIR="${BACKUP_DIR:-$HOME/backups/skills-spboucher-ai}"8dump="$(ls -1t "$BACKUP_DIR"/db/skills-*.sql.gz | head -1)"9scratch="skills_restore_drill_$$"10createdb "$scratch"11trap 'dropdb --if-exists "$scratch"' EXIT12gunzip -c "$dump" | psql -q -v ON_ERROR_STOP=1 "$scratch" > /dev/null13live="$(psql -At "$DATABASE_URL" -c "select (select count(*) from releases)||'/'||(select count(*) from artifacts)||'/'||(select count(*) from users)")"14restored="$(psql -At "$scratch" -c "select (select count(*) from releases)||'/'||(select count(*) from artifacts)||'/'||(select count(*) from users)")"15bad=0; n=016while IFS='|' read -r key sha; do17 n=$((n+1))18 got="$(shasum -a 256 "$BACKUP_DIR/blobs/$key" 2>/dev/null | cut -d' ' -f1)"19 [ "$got" = "$sha" ] || { echo "MISMATCH $key"; bad=$((bad+1)); }20done < <(psql -At "$scratch" -c "select archive_object_key, sha256 from releases")21# The immutability trigger must survive a restore.22if psql -q "$scratch" -c "update releases set sha256 = repeat('0',64)" > /dev/null 2>&1 && [ "$n" -gt 0 ]; then echo "FAIL: immutability trigger missing after restore"; exit 1; fi23echo "dump=$(basename "$dump") live(releases/artifacts/users)=$live restored=$restored blobs_checked=$n mismatches=$bad"24[ "$bad" -eq 0 ] && [ "$restored" != "" ] && echo "restore drill OK"25