#!/usr/bin/env bash set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" cd "$ROOT" GW="${GATEWAY_URL:-http://localhost:5081}" CENTRAL="${CENTRAL_URL:-http://localhost:5270}" SITE_ID="${SITE_ID:-11111111-1111-1111-1111-111111111111}" GW_ID="${GATEWAY_ID:-22222222-2222-2222-2222-222222222222}" ADMIN_JWT="${ADMIN_JWT:?Set ADMIN_JWT (central admin JWT)}" GATEWAY_JWT="${GATEWAY_JWT:?Set GATEWAY_JWT (JWT signed with gateway Jwt:SigningKey)}" echo "==> Start ward-gateway stack" docker compose --profile ward-gateway up -d echo "==> Ensure central API is reachable before partition test" if ! curl -sf "$CENTRAL/health/ready" >/dev/null; then echo "Central API must be running at $CENTRAL (dotnet run VigilCareClinicalAPI)" >&2 exit 1 fi echo "==> Wait for gateway ready" for i in $(seq 1 30); do if curl -sf "$GW/health/ready" >/dev/null; then echo "Gateway ready after ${i} attempt(s)" break fi if [[ "$i" -eq 30 ]]; then echo "Gateway not ready after 60s — is ward-gateway profile up?" >&2 exit 1 fi sleep 2 done echo "==> Stop central API to simulate partition" pkill -f "VigilCareClinicalAPI" 2>/dev/null || true for i in $(seq 1 15); do curl -sf "$CENTRAL/health/ready" >/dev/null || break sleep 2 done echo "==> Wait for gateway to detect central unreachable" sleep 35 echo "==> List active encounters from local replica" ENCOUNTER_ID=$(curl -sf "$GW/api/v1/encounters?status=ACTIVE&department=ICU" \ -H "Authorization: Bearer $GATEWAY_JWT" | jq -r '.data.items[0].encounterId') if [[ -z "$ENCOUNTER_ID" || "$ENCOUNTER_ID" == "null" ]]; then echo "No ACTIVE ICU encounter on gateway — seed replica or set GATEWAY_SYNC_JWT for sync" >&2 exit 1 fi echo "Using encounter $ENCOUNTER_ID" echo "==> Post critical observation while central is down" RECORDED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)" IDEM_KEY="phase21-verify-$(date +%s)" curl -sf -X POST "$GW/api/v1/encounters/$ENCOUNTER_ID/observations" \ -H "Authorization: Bearer $GATEWAY_JWT" \ -H "Content-Type: application/json" \ -d "{\"observationCode\":\"HEART_RATE\",\"value\":160,\"unit\":\"bpm\",\"source\":\"DEVICE\",\"recordedAt\":\"$RECORDED_AT\",\"idempotencyKey\":\"$IDEM_KEY\"}" echo "==> Verify alert exists locally" curl -sf "$GW/api/v1/encounters/$ENCOUNTER_ID/alerts" \ -H "Authorization: Bearer $GATEWAY_JWT" | jq -e '.data.items | length > 0' echo "==> Verify buffered sync items pending upload" BUFFER_DEPTH=$(docker exec "$(docker ps -qf name=ward-gateway-db)" psql -U postgres -d vigilcare_ward -tAc \ "SELECT COUNT(*) FROM buffered_sync_items WHERE NOT synced;") echo "Buffered items: $BUFFER_DEPTH" [[ "$BUFFER_DEPTH" -gt 0 ]] || { echo "Expected buffered sync items" >&2; exit 1; } echo "==> Restart central API" echo " Start manually: dotnet run --project VigilCareClinicalAPI" for i in $(seq 1 45); do curl -sf "$CENTRAL/health/ready" >/dev/null && break sleep 2 done if ! curl -sf "$CENTRAL/health/ready" >/dev/null; then echo "Central API did not come back — restart VigilCareClinicalAPI and re-run from sync step" >&2 exit 1 fi echo "==> Wait for gateway heartbeat/sync (up to 90s)" sleep 90 echo "==> Verify gateway reported ONLINE or buffer drained via central registry" curl -sf "$CENTRAL/api/v1/gateways/$GW_ID" \ -H "Authorization: Bearer $ADMIN_JWT" | jq -e '.data.status == "ONLINE" or .data.reportedBufferDepth == 0' echo "Phase 21 verification passed."