[object Object]

← back to Sister Parish Onboarding

fix: preflight count by 3-call status sum (status=any returns 0 in 2026-01)

8b0c30007b7d59e685294bab0afa61f0da3cabf7 · 2026-05-12 17:14:32 -0700 · SteveStudio2

Files touched

Diff

commit 8b0c30007b7d59e685294bab0afa61f0da3cabf7
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Tue May 12 17:14:32 2026 -0700

    fix: preflight count by 3-call status sum (status=any returns 0 in 2026-01)
---
 scripts/preflight.sh | 52 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/scripts/preflight.sh b/scripts/preflight.sh
index dbf51ec..4b112af 100755
--- a/scripts/preflight.sh
+++ b/scripts/preflight.sh
@@ -1,4 +1,4 @@
-#!/bin/zsh
+#!/usr/bin/env bash
 # One-shot pre-flight read of SP push state.
 # Prints:
 #   - DW Shopify store + SP vendor count (current ground truth)
@@ -6,8 +6,7 @@
 #   - Dry-run "would create" count (should be 73)
 # Exit code: 0 if push is healthy + scheduled, non-zero if something's off.
 #
-# Designed to be called by YOLO-loop ticks for an O(1) SP status read instead
-# of re-deriving it each time from raw curl + grep.
+# Bash-portable so YOLO ticks can invoke as `bash ./preflight.sh` or directly.
 
 set -uo pipefail
 
@@ -15,9 +14,15 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
 PLIST="$HOME/Library/LaunchAgents/com.steve.sister-parish-push.plist"
 ENV_FILE="$HOME/Projects/dw-collections-viewer/.env"
 
-ok()   { print -P "%F{green}✓%f $1"; }
-warn() { print -P "%F{yellow}⚠%f $1"; }
-fail() { print -P "%F{red}✗%f $1"; }
+# 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
@@ -26,19 +31,30 @@ if [[ -z "${SHOPIFY_STORE:-}" || -z "${SHOPIFY_ADMIN_TOKEN:-}" ]]; then
   fail "SHOPIFY_STORE / SHOPIFY_ADMIN_TOKEN not set in $ENV_FILE"; exit 2
 fi
 
-print -P "%F{cyan}=== SP push pre-flight · $(date '+%F %T %Z') ===%f"
-print "store: $SHOPIFY_STORE"
+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
-COUNT_JSON=$(curl -s "https://${SHOPIFY_STORE}/admin/api/2026-01/products/count.json?vendor=Sister+Parish&status=any" \
-  -H "X-Shopify-Access-Token: $SHOPIFY_ADMIN_TOKEN")
-COUNT=$(print "$COUNT_JSON" | /usr/bin/python3 -c "import json,sys; print(json.load(sys.stdin).get('count','?'))" 2>/dev/null)
-print "live SP count (vendor=Sister Parish, status=any): $COUNT"
+# 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"
-  /bin/launchctl list 2>/dev/null | grep -q "com.steve.sister-parish-push" && ok "loaded in launchctl" || warn "plist exists but NOT loaded — run: launchctl load $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
@@ -46,18 +62,18 @@ fi
 # 3) Dry-run count
 NODE_BIN="/opt/homebrew/bin/node"
 [[ -x "$NODE_BIN" ]] || NODE_BIN="/usr/local/bin/node"
-[[ -x "$NODE_BIN" ]] || NODE_BIN="$(/usr/bin/which node 2>/dev/null)"
+[[ -x "$NODE_BIN" ]] || NODE_BIN="$(/usr/bin/which node 2>/dev/null || true)"
 [[ -x "$NODE_BIN" ]] || { fail "no node binary found"; exit 2; }
-print "running dry-run via $NODE_BIN…"
+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)
-print "dry-run would-create: $DRY"
+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" -ge 73 ]]; then
+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

← 0a5d2b8 fix: drop status=any from /products.json list (invalid in AP  ·  back to Sister Parish Onboarding  ·  sp: activate_sp.js — flip all 50 draft Sister Parish product a28adca →