godcrm/scripts/rollback/adr-0030-p4-down.sh
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

94 lines
3.5 KiB
Bash
Executable file

#!/usr/bin/env bash
# ADR-0030 Phase 4 — rollback script.
#
# Idempotent. Does the following:
# 1. Print operator instructions for reverting RUN_DISPATCHER_PHASE.
# 2. Flip any tickets currently in run_state='running' to 'failed' with
# run_terminal_reason='rolled_back_p4'.
# 3. Best-effort: prune any registered git worktrees under /root/workspaces/T-*.
# 4. Does NOT touch PM2 (per Phase 4 brief).
#
# Re-runnable safely — second run is a no-op once tickets are flipped.
#
# Connection: defaults to local godcrm@localhost / godcrm_prod (PROD on .205)
# but every value is overrideable via env. Refuses to run if any required
# env var is unset AND no PROD default is provided.
set -uo pipefail
PG_HOST="${POSTGRES_HOST:-localhost}"
PG_PORT="${POSTGRES_PORT:-5432}"
PG_USER="${POSTGRES_USER:-godcrm}"
PG_DB="${POSTGRES_DB:-godcrm_prod}"
PG_PASSWORD="${POSTGRES_PASSWORD:-godcrm_dev_2026}"
echo "============================================================"
echo "ADR-0030 Phase 4 rollback"
echo "============================================================"
echo
echo "Target: ${PG_USER}@${PG_HOST}:${PG_PORT}/${PG_DB}"
echo
echo "STEP 1 — Operator action required:"
echo " Set RUN_DISPATCHER_PHASE to 'workspace_only' (or 'dryrun') in the"
echo " PM2 environment, then *manually* restart the affected process."
echo " This script does NOT touch PM2 (per Phase 4 brief)."
echo
echo " Example (operator runs by hand):"
echo " pm2 set godcrm:RUN_DISPATCHER_PHASE workspace_only"
echo " pm2 restart godcrm --update-env"
echo
echo "STEP 2 — Flipping any in-flight 'running' tickets → failed (rolled_back_p4)"
PGPASSWORD="${PG_PASSWORD}" psql \
-h "${PG_HOST}" -p "${PG_PORT}" -U "${PG_USER}" -d "${PG_DB}" \
-v ON_ERROR_STOP=1 <<'SQL' || { echo "psql update failed"; exit 1; }
WITH affected AS (
UPDATE table_rows
SET data = data || jsonb_build_object(
'run_state', 'failed',
'run_terminal_reason', 'rolled_back_p4',
'run_finished_at', to_char(NOW() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"'),
'run_last_event_at', to_char(NOW() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')
),
updated_at = NOW()
WHERE table_id = 1708
AND data->>'run_state' = 'running'
RETURNING id
)
SELECT count(*) AS rolled_back FROM affected;
SQL
echo
echo "STEP 3 — Best-effort: cleaning up worktrees under /root/workspaces/"
WORKTREES_OUT="$(git -C /root/production/business-crm worktree list --porcelain 2>/dev/null || true)"
if [[ -z "${WORKTREES_OUT}" ]]; then
echo " no worktrees registered — skipping"
else
while IFS= read -r line; do
if [[ "${line}" =~ ^worktree[[:space:]](.+)$ ]]; then
wtpath="${BASH_REMATCH[1]}"
if [[ "${wtpath}" == /root/workspaces/T-* ]]; then
echo " removing ${wtpath}"
git -C /root/production/business-crm worktree remove --force "${wtpath}" 2>/dev/null || true
rm -rf "${wtpath}" 2>/dev/null || true
fi
fi
done <<< "${WORKTREES_OUT}"
git -C /root/production/business-crm worktree prune 2>/dev/null || true
echo " worktree prune complete"
fi
echo
echo "STEP 4 — Best-effort: nuking 'run/T-*' branches"
git -C /root/production/business-crm for-each-ref --format='%(refname:short)' refs/heads/run/ 2>/dev/null \
| while read -r br; do
if [[ -n "${br}" ]]; then
echo " deleting branch ${br}"
git -C /root/production/business-crm branch -D "${br}" 2>/dev/null || true
fi
done
echo
echo "Rollback complete. Reminder: PM2 restart is operator-driven."
exit 0