#!/usr/bin/env bash set -euo pipefail API_BASE="${API_BASE:-http://127.0.0.1:5084}" ADMIN_SESSION_TOKEN="${ADMIN_SESSION_TOKEN:-}" fail() { printf 'smoke failed: %s\n' "$*" >&2 exit 1 } require_command() { command -v "$1" >/dev/null 2>&1 || fail "missing required command: $1" } http_json() { local url="$1" shift || true curl -fsS "$@" "$url" } json_value() { local expression="$1" node -e " let data = ''; process.stdin.on('data', chunk => data += chunk); process.stdin.on('end', () => { const root = JSON.parse(data); const value = (${expression})(root); if (typeof value === 'object') { console.log(JSON.stringify(value)); } else { console.log(value ?? ''); } }); " } require_command curl require_command node printf '== VTuber Awards local smoke ==\n' printf 'API: %s\n' "$API_BASE" printf '\n[1/6] health\n' http_json "$API_BASE/api/health" >/tmp/vtsa-smoke-health.json cat /tmp/vtsa-smoke-health.json printf '\n' printf '\n[2/6] database health\n' http_json "$API_BASE/api/health/database" >/tmp/vtsa-smoke-db.json cat /tmp/vtsa-smoke-db.json printf '\n' can_connect="$(json_value 'root => root.canConnect' /tmp/vtsa-smoke-overview.json year="$(json_value 'root => root.year' /tmp/vtsa-smoke-categories.json category_count="$(json_value 'root => root.categories?.length ?? 0' /tmp/vtsa-smoke-admin-seasons.json admin_season_count="$(json_value 'root => Array.isArray(root) ? root.length : (root.seasons?.length ?? 0)' /tmp/vtsa-smoke-admin-detail.json voting_groups="$(json_value 'root => root.votingWorkspace?.categories?.length ?? 0' /tmp/vtsa-smoke-admin-team.json permissions="$(json_value 'root => (root.permissions ?? []).map(p => p.key).sort().join(",")' item.key)); const required = ["dashboard","years","nominations","categories","candidates","clips","content","risk","audit","analytics","voting","winners","settings","team"]; const missing = required.filter(key => !keys.has(key)); if (missing.length) { console.error(`missing permission keys: ${missing.join(", ")}`); process.exit(1); } ' fi printf '\n[6/6] smoke complete\n'