← back to Butlr

scripts/predeploy-guard.sh

51 lines

#!/usr/bin/env bash
# Pre-deploy guard for Butlr: abort if any call is currently active.
# A pm2 reload kills the WSS Media Stream lane, which silently drops
# the PCM audio capture and any in-flight ffmpeg→MP3 finalize. Discovered
# 2026-05-13 when a mid-call deploy lost 5 recordings (3 calls completed
# but had no audio archived).
#
# Usage (called from .deploy.conf):
#   PREDEPLOY_HOOK="bash scripts/predeploy-guard.sh"
#
# Exits 0 if safe. Exits 2 with explanation if at least one call is
# in dialing / on_hold / connected. Override with FORCE_DEPLOY=1 if
# you've decided the deploy is worth dropping any active recordings.

set -euo pipefail

DEPLOY_HOST="${DEPLOY_HOST:-45.61.58.125}"
DEPLOY_PATH="${DEPLOY_PATH:-/root/public-projects/butlr}"

if [[ "${FORCE_DEPLOY:-}" == "1" ]]; then
  echo "  ⚠️  FORCE_DEPLOY=1 — skipping active-call guard"
  exit 0
fi

# Read prod calls.json over ssh. Statuses considered active:
#   dialing  — call is being placed
#   on_hold  — Twilio Stream is open, capturing audio
#   connected — Stream + AI loop running, audio still flowing
active=$(ssh -o ConnectTimeout=5 "root@${DEPLOY_HOST}" \
  "node -e 'const d=require(\"${DEPLOY_PATH}/lib/data\"); const a=d.listCallsUnscoped(); const live=a.filter(c=>[\"dialing\",\"on_hold\",\"connected\"].includes(c.status)); console.log(JSON.stringify(live.map(c=>({id:c.id,status:c.status,biz:c.business_name}))))'" \
  2>/dev/null || echo "[]")

count=$(node -e "process.stdout.write(String(JSON.parse(process.argv[1]).length))" "$active")

if [[ "$count" == "0" ]]; then
  echo "  ✓ no active calls — safe to deploy"
  exit 0
fi

echo
echo "  ✗ ABORTING DEPLOY — $count active call(s) on prod:"
node -e "
const a = JSON.parse(process.argv[1]);
for (const c of a) console.log('     ' + c.id.padEnd(10) + ' | ' + c.status.padEnd(10) + ' | ' + (c.biz || ''));
" "$active"
echo
echo "  Wait for calls to complete (pm2 logs butlr | grep status), or override:"
echo "    FORCE_DEPLOY=1 bash ~/Projects/_shared/scripts/deploy.sh"
echo
exit 2