#!/usr/bin/env bash # Refresh the test database from production. Runs daily via cron on pms1. # # pelagia_test is a throwaway mirror of prod (pelagia) so the autofix Claude can # run integration tests / a dev server against realistic data WITHOUT touching # production. The test DB is owned by pelagia_user (created once as superuser); # this refresh runs purely as pelagia_user using the prod connection string. set -uo pipefail ENV_FILE="${1:-/home/shad0w/pms/App/.env}" PROD_DB="pelagia" TEST_DB="pelagia_test" log() { echo "$(date '+%F %T') $*"; } PROD_URL=$(grep -E '^DATABASE_URL' "$ENV_FILE" | sed -E 's/^DATABASE_URL=//; s/^"//; s/"$//') [ -n "$PROD_URL" ] || { log "ERROR: no DATABASE_URL in $ENV_FILE"; exit 1; } # Derive the test URL by swapping ONLY the database-name path segment (anchored on # @host/ so the 'pelagia' inside the username is never touched). TEST_URL=$(printf '%s' "$PROD_URL" | sed -E "s#(@[^/]+/)$PROD_DB([?]|\$)#\1$TEST_DB\2#") if [ "$TEST_URL" = "$PROD_URL" ]; then log "ERROR: failed to derive test URL (db name not found in connection string)"; exit 1 fi log "Refreshing $TEST_DB from $PROD_DB ..." # --clean --if-exists drops+recreates each object in place (first run on an empty # DB is a no-op for the DROPs). --no-owner/--no-privileges keep it portable. errfile=$(mktemp) pg_dump --clean --if-exists --no-owner --no-privileges "$PROD_URL" \ | psql "$TEST_URL" >/dev/null 2>"$errfile" prod_tables=$(psql -tAc "SELECT count(*) FROM information_schema.tables WHERE table_schema='public';" "$PROD_URL") test_tables=$(psql -tAc "SELECT count(*) FROM information_schema.tables WHERE table_schema='public';" "$TEST_URL") if [ "$test_tables" = "$prod_tables" ] && [ "$test_tables" -gt 0 ]; then log "Done. $TEST_DB has $test_tables public tables (prod has $prod_tables)." rm -f "$errfile" else log "WARNING: table counts differ (test=$test_tables prod=$prod_tables). Recent errors:" tail -8 "$errfile" rm -f "$errfile" exit 1 fi