5.8 KiB
Phase 24 verification notes
Notes from getting scripts/run-phase24-verification.sh to pass against local Docker + dev central API (http://localhost:5270).
Automated verification
./scripts/run-phase24-verification.sh
Useful env overrides:
| Variable | Purpose |
|---|---|
SKIP_DOCKER=1 |
Stack already up; skip compose |
SKIP_PHASE_A=1 |
Skip central baseline replay |
SCENARIO_SPEED=0 |
Instant replay (default) |
KEEP_CENTRAL_DOWN=1 |
Leave central stopped after Phase B (debug) |
Companion script: scripts/mint-gateway-jwt.sh — dev JWT for gateway (issuer: vigilcare-gateway).
Fixes applied during verification
1. Gateway encounter missing after Phase A
Symptom: Phase B could not find encounter on gateway.
Cause: docker compose up -d without recreate did not re-run SyncOnceAsync after central had new encounters.
Fix: Script calls docker compose up -d --force-recreate ward-gateway-api in configure_gateway_sync so sync runs on a fresh gateway container.
2. Phase B observation POST returned 400
Symptom: Gateway rejected observation batches from simulator.
Cause: Central API accepts batch ingest; gateway expects a single observation per POST with observationCode (not central’s batch shape).
Fix: VigilCareApiClient.SendObservationBatchAsync — gateway path posts one observation at a time using gateway field names.
3. Phase B recordedAt rejected (future timestamp)
Symptom: 400 — timestamp more than ~5 minutes in the future.
Cause: --speed 0 uses scenario offsetMinutes as simulated future times; gateway validates recordedAt against wall clock.
Fix: ReplayEngine uses DateTimeOffset.UtcNow for observations when Target == Gateway.
Trade-off: Gateway replay does not preserve simulated timeline spacing at speed 0; acceptable for outage demo (alerts still fire on values).
4. No critical potassium alert at K+ 6.1
Symptom: Only warning-tier alert; Phase B ack step had nothing to match.
Cause: Seeded threshold CriticalHigh for potassium is 6.5 mEq/L; 6.1 is above warning (5.5) but below critical.
Fix: Scenario ward-outage-reconnect-01.json — critical observation value 6.1 → 6.8.
5. Alert ack / jq verification failed (alert type mismatch)
Symptom: TryAcknowledgeAlertAsync returned false; jq filters found no alert.
Cause: API stores/returns enum-style names (e.g. CriticalPotassiumMeqL); scenario uses CRITICAL_POTASSIUM_MEQ_L.
Fix: VigilCareApiClient.IsMatchingAlertType — flexible match (case, underscores, suffix).
Fix: Verification script uses jq filters that accept both naming styles.
6. acknowledgedBy was nurse.demo instead of RN-Wu
Symptom: After gateway ack, synced alert on central showed JWT subject, not scenario nurse.
Cause: Gateway AcknowledgeAlertRequest had no body field for clinician; controller used User.Identity.Name only. Stale Docker image also hid fixes until rebuild.
Fix: Optional clinicianId on gateway ack request; controller uses req.ClinicianId ?? User.Identity?.Name. Script rebuilds gateway image before run.
7. Phase C verify timeout
Symptom: Script gave up before central showed synced ack with RN-Wu.
Cause: Central restart + gateway sync can exceed 120s on a loaded machine.
Fix: Poll up to 180s for alert with syncedFromGateway and acknowledgedBy = RN-Wu.
8. Phase A central ack fails at --speed 0 (non-fatal in script)
Symptom: Phase A alert_ack against central sometimes failed before the poll fix.
Cause: Alert pipeline is async; at speed 0 the ack event could run before the critical alert row existed.
Fix: Central replay now polls for up to 30s before posting alert_ack (TryAcknowledgeAlertAsync with waitForAlert). The verification script still treats Phase A ack as non-fatal; Phase B (gateway outage path) remains the authoritative ack/sync test.
Code changes summary (already merged)
| Area | Files |
|---|---|
| Scenario + schema | ward-outage-reconnect-01.json, schema.json, ScenarioValidator.cs |
| Gateway replay | ReplayOptions.cs, ReplayCommand.cs, ReplayEngine.cs, VigilCareApiClient.cs |
| Gateway ack attribution | AcknowledgeAlertRequest.cs, AcknowledgeAlertRequestValidator.cs, AlertsController.cs |
| Tests | WardGatewayLocalPathTests.cs |
| Automation | run-phase24-verification.sh, mint-gateway-jwt.sh |
| Docs | simulator-guide.md §10, phase-24 plan footnote on gateway vs central ack |
Remaining doc / optional code follow-ups
| Item | Priority | Notes |
|---|---|---|
phase-24-plan.md embedded scenario snippet still showed K+ 6.1 |
Doc | Updated to 6.8 to match scenario + thresholds |
ext-climate-resilience-roadmap.md referenced verify-phase-24.ps1 |
Doc | Updated to run-phase24-verification.sh |
| Central async ack at speed 0 | Done | ReplayEngine polls up to 30s before central alert_ack |
Gateway has no /auth/login |
By design | Use --gateway-token / mint-gateway-jwt.sh |
CentralApiOptions default port 5080 vs dev 5270 |
OK | Docker compose overrides via host.docker.internal:5270 |
| README mention of Phase 24 script | Done | Ward outage section + verification script list |
| Gateway mode unit tests | Optional | No simulator tests for --gateway path yet |
Expected pass criteria (Phase C)
After central restarts:
- Buffered alert appears on central with
syncedFromGateway(or equivalent sync marker). acknowledgedBy= RN-Wu (not gateway JWT subject).- Gateway buffer depth returns to 0 (or heartbeat shows no pending acks).
Last successful run: ./scripts/run-phase24-verification.sh with SKIP_DOCKER=1 — all phases passed.