#!/bin/bash set -euo pipefail BASE="http://localhost:8000" FRONT="http://localhost" POSTGREST="http://localhost:3000" echo "=== EMS Platform Smoke Test ===" # 1. Health echo -n "Health endpoint... " curl -sf "$BASE/api/v1/health" | python3 -c " import sys,json; d=json.load(sys.stdin) assert d['status']=='ok', f'status={d[\"status\"]}' assert d['db']=='ok', f'db={d[\"db\"]}' print('OK') " # 2. Sites + první site_id (seed nemusí být vždy id=1) echo -n "Sites endpoint... " SITE_ID=$(curl -sf "$BASE/api/v1/sites" | python3 -c " import sys,json; d=json.load(sys.stdin) assert len(d)>0, 'no sites' print(d[0]['id']) ") echo "OK (site_id=$SITE_ID)" # 3. Prices (dnes) echo -n "Prices endpoint... " STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/api/v1/sites/${SITE_ID}/prices") [ "$STATUS" = "200" ] && echo "OK" || echo "WARN (HTTP $STATUS – ceny možná nejsou importovány)" # 4. Plan current (může být 404 – bez plánu) echo -n "Plan current... " STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/api/v1/sites/${SITE_ID}/plan/current") [ "$STATUS" = "200" ] && echo "OK (plán existuje)" || echo "OK (HTTP $STATUS – zatím žádný plán)" # 5. Import cen OTE (zítra) echo -n "OTE price import... " RESULT=$(curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/prices/import" \ -H "Content-Type: application/json" 2>/dev/null) || RESULT="" PRICES_EXPECTED=$(python3 -c " from zoneinfo import ZoneInfo from datetime import datetime n = datetime.now(ZoneInfo('Europe/Prague')) print(1 if (n.hour, n.minute) >= (14, 30) else 0) ") if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); assert d.get('slots_imported',0)>0" 2>/dev/null; then echo "OK ($(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['slots_imported'])") slotů)" elif [ "$PRICES_EXPECTED" = "1" ]; then echo "WARN – OTE API možná nemá data pro zítřek nebo je nedostupné (po 14:30 Europe/Prague)" else echo "OK (před 14:30 Europe/Prague – D+1 ceny typicky ještě nejsou; import přeskočen bez WARN)" fi # 6. PV forecast echo -n "PV forecast... " RESULT=$(curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/forecast/run" 2>/dev/null) || RESULT="" if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); assert d.get('intervals_saved',0)>0" 2>/dev/null; then echo "OK" else echo "WARN – forecast selhal (zkontroluj GPS souřadnice v seed datech)" fi # 7. Spustit plán (potřebuje ceny + forecast) echo -n "Planning run... " RESULT=$(curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/plan/run?type=daily" 2>/dev/null) || RESULT="" if echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); assert d.get('run_id') is not None" 2>/dev/null; then echo "OK (run_id=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['run_id'])"))" else echo "WARN – planning selhal: $RESULT" fi # 8. Přepnutí režimu a zpět (API + ověření přes PostgREST) echo -n "Operating mode switch... " curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/mode" \ -H "Content-Type: application/json" \ -d '{"mode":"PRESERVE","notes":"smoke test","valid_until":null}' >/dev/null || true RESULT=$(curl -sf "${POSTGREST}/vw_site_status?site_id=eq.${SITE_ID}" 2>/dev/null) || RESULT="" MODE=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['active_mode'])" 2>/dev/null) || MODE="" if [ "$MODE" = "PRESERVE" ]; then echo "OK" else echo "WARN (mode=$MODE)" fi curl -sf -X POST "$BASE/api/v1/sites/${SITE_ID}/mode" \ -H "Content-Type: application/json" \ -d '{"mode":"AUTO","notes":"smoke test restore","valid_until":null}' >/dev/null || true # 9. EV sessions endpoint echo -n "EV sessions endpoint... " STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ "$BASE/api/v1/sites/${SITE_ID}/ev/sessions/active") [ "$STATUS" = "200" ] && echo "OK (HTTP 200)" || echo "FAIL (HTTP $STATUS)" # 10. Frontend dostupný echo -n "Frontend (nginx)... " STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$FRONT/") [ "$STATUS" = "200" ] && echo "OK" || echo "FAIL (HTTP $STATUS)" # 11. PostgREST přes nginx echo -n "PostgREST přes nginx... " if curl -sf "$FRONT/rest/vw_site_status?limit=1" | python3 -c " import sys,json; d=json.load(sys.stdin); print(f'OK ({len(d)} rows)') " 2>/dev/null; then : else echo "WARN – PostgREST možná potřebuje anon roli" fi echo "" echo "=== Smoke test dokončen ==="