Files
vigilcare-clinical/docs/resilience/phase-24-verification-notes.md
T
2026-06-24 03:01:00 +08:00

5.8 KiB
Raw Blame History

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 centrals 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:

  1. Buffered alert appears on central with syncedFromGateway (or equivalent sync marker).
  2. acknowledgedBy = RN-Wu (not gateway JWT subject).
  3. 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.