← back to Sister Parish Onboarding

scripts/preflight.sh

83 lines

#!/usr/bin/env bash
# One-shot pre-flight read of SP push state.
# Prints:
#   - DW Shopify store + SP vendor count (current ground truth)
#   - launchd plist install status + next-fire estimate
#   - Dry-run "would create" count (should be 73)
# Exit code: 0 if push is healthy + scheduled, non-zero if something's off.
#
# Bash-portable so YOLO ticks can invoke as `bash ./preflight.sh` or directly.

set -uo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
PLIST="$HOME/Library/LaunchAgents/com.steve.sister-parish-push.plist"
ENV_FILE="$HOME/Projects/dw-collections-viewer/.env"

# ANSI color (no-op if stdout isn't a tty)
if [[ -t 1 ]]; then
  G=$'\033[32m'; Y=$'\033[33m'; R=$'\033[31m'; C=$'\033[36m'; N=$'\033[0m'
else
  G=; Y=; R=; C=; N=
fi
ok()   { printf '%s✓%s %s\n' "$G" "$N" "$1"; }
warn() { printf '%s⚠%s %s\n' "$Y" "$N" "$1"; }
fail() { printf '%s✗%s %s\n' "$R" "$N" "$1"; }

[[ -f "$ENV_FILE" ]] || { fail "missing $ENV_FILE"; exit 2; }
set -a; source "$ENV_FILE"; set +a

if [[ -z "${SHOPIFY_STORE:-}" || -z "${SHOPIFY_ADMIN_TOKEN:-}" ]]; then
  fail "SHOPIFY_STORE / SHOPIFY_ADMIN_TOKEN not set in $ENV_FILE"; exit 2
fi

printf '%s=== SP push pre-flight · %s ===%s\n' "$C" "$(date '+%F %T %Z')" "$N"
printf 'store: %s\n' "$SHOPIFY_STORE"

# 1) Live SP count — sum across active/draft/archived (status=any silently returns 0 in API 2026-01)
sp_count_for_status() {
  local st="$1"
  curl -s "https://${SHOPIFY_STORE}/admin/api/2026-01/products/count.json?vendor=Sister+Parish&status=${st}" \
    -H "X-Shopify-Access-Token: $SHOPIFY_ADMIN_TOKEN" \
    | /usr/bin/python3 -c "import json,sys; print(json.load(sys.stdin).get('count',0))" 2>/dev/null || echo 0
}
ACTIVE=$(sp_count_for_status active)
DRAFT=$(sp_count_for_status draft)
ARCH=$(sp_count_for_status archived)
COUNT=$((ACTIVE + DRAFT + ARCH))
printf 'live SP count (active+draft+archived): %s  [active=%s draft=%s archived=%s]\n' "$COUNT" "$ACTIVE" "$DRAFT" "$ARCH"

# 2) launchd plist
if [[ -f "$PLIST" ]]; then
  ok "launchd plist installed: $PLIST"
  if /bin/launchctl list 2>/dev/null | grep -q "com.steve.sister-parish-push"; then
    ok "loaded in launchctl"
  else
    warn "plist exists but NOT loaded — run: launchctl load $PLIST"
  fi
else
  warn "plist absent (already self-unloaded? expected after a successful 73-product push)"
fi

# 3) Dry-run count
NODE_BIN="/opt/homebrew/bin/node"
[[ -x "$NODE_BIN" ]] || NODE_BIN="/opt/homebrew/bin/node"
[[ -x "$NODE_BIN" ]] || NODE_BIN="$(/usr/bin/which node 2>/dev/null || true)"
[[ -x "$NODE_BIN" ]] || { fail "no node binary found"; exit 2; }
printf 'running dry-run via %s…\n' "$NODE_BIN"
DRY=$(cd "$ROOT" && SHOPIFY_STORE="$SHOPIFY_STORE" SHOPIFY_ADMIN_TOKEN="$SHOPIFY_ADMIN_TOKEN" \
  "$NODE_BIN" scripts/push_shopify.js --dry-run 2>&1 | grep -c "would create" || true)
printf 'dry-run would-create: %s\n' "$DRY"

# 4) Verdict
if [[ "$COUNT" == "0" && "$DRY" == "73" && -f "$PLIST" ]]; then
  ok "GREEN: push is armed for next Wednesday 02:00 PT"
  exit 0
elif [[ "$COUNT" =~ ^[0-9]+$ && "$COUNT" -ge 73 ]]; then
  ok "DONE: $COUNT/73 already in Shopify — plist should self-unload on next run"
  exit 0
else
  warn "MIXED: count=$COUNT  dry=$DRY  plist=$([[ -f "$PLIST" ]] && echo present || echo absent)"
  exit 1
fi