Files
vigilcare-clinical/docs/dashboard-guide.md
T
2026-06-20 14:41:11 +08:00

15 KiB
Raw Blame History

VigilCare Dashboard — User Guide

The VigilCare Dashboard (vigilcare-dashboard/) is a Vue 3 single-page application that gives clinicians a live view of the virtual ward: who is on the floor, which patients are deteriorating, what alerts need action, and — on the patient detail screen — vital sign trends, NEWS2 history, and plain-language alert reasoning.

It reads from the VigilCare Clinical API over HTTP. It does not connect to Kafka, RabbitMQ, or PostgreSQL directly. Polling keeps the UI fresh while the API and background consumers do the clinical work.


Table of Contents

  1. What the dashboard does
  2. Prerequisites
  3. Quick start
  4. Screens
  5. Patient detail — clinical review mode
  6. Working with the simulator
  7. Configuration
  8. Development
  9. Troubleshooting

1. What the dashboard does

In a real hospital, nurses and physicians need a ward board: acuity at a glance, drill-down into one patient, and a way to act on alerts. This frontend implements that workflow against the VigilCare API.

Capability Where in the app API backing
Ward overview — active patients sorted by NEWS2 risk Virtual Ward (/ward) GET /encounters?status=ACTIVE
Department filter Virtual Ward toolbar Same list endpoint with department
Patient drill-down Patient Detail (/patients/:encounterId) GET /encounters/{id}, observations, scores, orders
Latest vitals snapshot Patient Detail — Vitals panel GET /encounters/{id}/observations
NEWS2 current score Patient Detail — Scores panel GET /encounters/{id}/news2/current
Open alerts per patient Patient Detail — Active Alerts GET /encounters/{id}/alerts
Acknowledge / resolve alerts Patient Detail or Alert Center PATCH /alerts/{id}/acknowledge, /resolve
Sepsis bundle status Patient Detail — Sepsis Bundle panel GET /encounters/{id}/sepsis-bundle/current
Clinical orders Patient Detail — Orders panel GET /encounters/{id}/orders
Vital sign trend charts (HR, RR, BP, SpO₂, temp) Patient Detail — Clinical review section Observations (Chart.js)
NEWS2 score over time Patient Detail — NEWS2 history chart GET /encounters/{id}/news2/history
Alert reasoning (“why did this fire?”) Patient Detail — click an alert row Client-side rules + alert details
Medication context on alerts Alert reasoning panel GET /encounters/{id}/medications
Local replay controls Patient Detail — replay bar Scrubs fetched data (not live simulator control)
Global alert inbox Alert Center (/alerts) GET /alerts with status filter
Clinician feedback on alerts Alert Center, Patient Detail reasoning Pinia + localStorage (client-side)
Feedback summary & export Feedback Summary (/feedback) Aggregate stats; export JSON/CSV

What it is not: a full EHR, authentication server, or simulator remote control. Replay controls scrub through data already loaded from the API; they do not pause or speed up the .NET simulator process. Alert feedback is stored in the browser until exported — see clinical-testing-guide.md for the clinician workflow.


2. Prerequisites

  • Node.js 20+ and npm
  • VigilCare Clinical API running at http://localhost:5270 (see root README — Getting Started)
  • CORS: API Dashboard policy must allow the dev origin (http://localhost:5173 by default)

Optional but recommended for demo data:

  • VigilCare Simulator — replay a scenario so observations and alerts populate while you watch the dashboard update. See simulator-guide.md.

3. Quick start

From the repository root:

# Terminal 1 — infrastructure + API
docker compose up -d
dotnet run --project VigilCareClinicalAPI

# Terminal 2 — dashboard
cd vigilcare-dashboard
npm install
npm run dev

Open http://localhost:5173. The app redirects to Virtual Ward.

To populate live data, run a simulator scenario in a third terminal:

dotnet run --project VigilCare.Simulator -- replay \
  VigilCare.Simulator/Scenarios/List/uti-sepsis-elderly-01.json \
  --speed 60

Return to the dashboard, click a patient row, and watch vitals, charts, and alerts update every few seconds.


4. Screens

Virtual Ward (/ward)

The home screen lists active encounters as a responsive table (desktop) or card list (mobile).

  • Patients are sorted by NEWS2 score (highest risk first).
  • A badge shows how many patients have NEWS2 ≥ 7.
  • Filter by department: All, ICU, General Medicine, Surgery.
  • Click a row to open Patient Detail.

Data refreshes every 10 seconds via polling.

Alert Center (/alerts)

A hospital-wide alert inbox independent of any single patient.

  • Filter tabs: Open, Acknowledged, Resolved, Escalated.
  • Each card shows severity, alert type, details, and triggered time.
  • Ack opens a confirmation modal (uses clinician ID from settings — default DR-DEMO).
  • Resolve is available after acknowledge.

Use this when you need to triage alerts across the ward without opening each patient first.

Feedback Summary (/feedback)

Purpose: Research and evaluation view for structured clinician ratings on alerts.

  • Aggregate stats: total ratings, % useful/would act, % false positive, timing issues.
  • Breakdown by alert type (sepsis, NEWS2, heart rate warning, etc.).
  • Recent feedback entries with notes.
  • Export JSON / Export CSV for study analysis.

Ratings are collected via six buttons on each alert (see clinical-testing-guide.md for definitions aimed at doctors and nurses).

Patient Detail (/patients/:encounterId)

The clinical review screen. See §5 for the full breakdown.


5. Patient detail — clinical review mode

Layout top to bottom:

┌─────────────────────────────────────────────────────────┐
│  ← Ward    Patient Name                                 │
├─────────────────────────────────────────────────────────┤
│  Scores (NEWS2)  │  Latest Vitals  │  Active Alerts    │
├─────────────────────────────────────────────────────────┤
│  Alert reasoning panel (after clicking an alert)        │
├─────────────────────────────────────────────────────────┤
│  Orders              │  Sepsis Bundle (if present)        │
├─────────────────────────────────────────────────────────┤
│  Vital sign trend charts (5)                            │
│  NEWS2 score history chart                              │
│  Replay controls                                        │
└─────────────────────────────────────────────────────────┘

Scores panel

Shows the current NEWS2 total, risk level, and encounter metadata (room/bed, department). If no score has been computed yet, displays .

Vitals panel

Latest value per observation code (heart rate, respiratory rate, blood pressure, SpO₂, temperature, etc.), deduplicated to the most recent reading per code.

Active alerts

Open alerts for this encounter. Click a row to open the reasoning panel below the grid.

  • Ack / Resolve buttons use @click.stop so they do not trigger row selection.
  • Selected row is highlighted.

Alert reasoning

Explains why an alert fired in plain language:

Alert type Explanation shown
WarningHeartRate, WarningSystolicBp, WarningTempC Threshold range + extracted value from details
SepsisWarning SIRS criteria summary
QsofaWarning qSOFA criteria summary
News2Warning / News2Emergency NEWS2 risk tier
RapidDeterioration Trajectory / rate-of-change
Unknown types Falls back to raw details string

If medications were administered within 90 minutes before the alert, a Recent medications block appears (supports reviewing medication-false-alarm-01 and similar scenarios).

Orders and sepsis bundle

  • Orders — pending and resulted clinical orders for the encounter.
  • Sepsis bundle — only rendered when a bundle exists; shows compliance status, deadline, and four treatment elements.

Clinical review charts

Five vital sign trend line charts (Chart.js via vue-chartjs):

  • Heart rate, respiratory rate, systolic BP, SpO₂, temperature
  • Responsive grid: 1 column (mobile) → 2 (sm) → 3 (xl)
  • Respects prefers-reduced-motion (animations disabled when OS setting is on)

NEWS2 history chart plots totalScore over time with per-point fill colors for risk bands (low / medium / high).

Replay controls

Local playback UI for reviewing scenario timelines against data already loaded for this encounter:

  • Pause / resume — starts paused at the end of the timeline (all data visible). Resume rewinds to the start and plays forward.
  • Speed presets (1×, 60×, 360×, Instant) — advance the replay clock through observation and NEWS2 timestamps; Instant jumps to the end.
  • Progress bar and elapsed time — derived from the earliest to latest timestamp across observations, NEWS2 history, and alerts.
  • Chart scrubbing — vitals panel, vital trend charts, and NEWS2 history show only data at or before the replay clock.
  • Next Alert → — cycles open/escalated alerts chronologically, selects each for the reasoning panel, scrubs the replay clock to that alerts triggeredAt, scrolls the alert row into view, and scrolls to the chart section.

Selecting an alert row in Active Alerts also scrubs the replay clock to that alerts time.

Replay state is client-side only. It does not send commands to the simulator. Patient detail loads encounter-scoped alerts on every poll so the alert list and Next Alert → are not affected by a prior visit to Alert Center.

Patient detail data polls every 5 seconds.

Clinician feedback (on alerts)

Below each alert in Alert Center and below the reasoning panel on Patient Detail:

Rating Meaning
Useful Clinically appropriate alert
Would act Would change management based on this alert
Too early Right direction, wrong timing (too soon)
Too late Problem existed; alert came too late
False positive Should not have fired for this context
Missing context Valid concern but insufficient information

Tap + Note for optional free text. Ratings save automatically in the browser. Export from Feedback Summary when the session ends.


6. Working with the simulator

Typical demo flow:

  1. Start API + dashboard (§3).
  2. Replay a scenario at moderate speed (--speed 60).
  3. Open Virtual Ward — new or updated encounters appear as the simulator creates them.
  4. Click the patient — watch vitals and charts fill in as observations ingest.
  5. When alerts fire, click an alert row to read reasoning (replay scrubs to that time); try Next Alert → on the replay bar.
  6. Use Alert Center to acknowledge alerts globally.

Suggested scenarios:

Scenario file What to observe in the dashboard
uti-sepsis-elderly-01.json SIRS/qSOFA alerts, sepsis bundle panel, rising acuity
medication-false-alarm-01.json HR warnings with medication context in reasoning
news2-deterioration-01.json (if present) NEWS2 history chart and score panel

7. Configuration

Setting Location Default
API base URL vigilcare-dashboard/.envVITE_API_URL http://localhost:5270
Clinician ID (acknowledge) Pinia settings store / localStorage key clinicianId DR-DEMO
Dark mode Header toggle / localStorage key darkMode System preference
Ward poll interval usePolling in WardDashboard.vue 10 s
Patient detail poll usePolling in PatientDetail.vue 5 s

Example .env:

VITE_API_URL=http://localhost:5270

8. Development

cd vigilcare-dashboard
npm install
npm run dev      # http://localhost:5173
npm test         # Vitest — composables + component tests
npm run build    # production bundle
npm run preview  # preview production build

Stack: Vue 3 (<script setup>), Vue Router, Pinia, Tailwind CSS v4, Chart.js + vue-chartjs.

Key directories:

vigilcare-dashboard/src/
├── api/           # HTTP client + encounter/clinical/alert fetchers
├── components/
│   ├── charts/    # VitalChart, TrendsGrid, News2History
│   ├── replay/    # ReplayControls
│   ├── alerts/    # AlertReasoning, AlertCard, …
│   ├── patient/   # VitalsPanel, ScoresPanel, AlertsList, …
│   └── ward/      # WardTable, PatientRow, PatientCard
├── composables/   # useChartData, useReplayControls, usePolling, chartFormat
├── stores/        # ward, alerts, settings (Pinia)
└── views/         # WardDashboard, PatientDetail, AlertCenter

Implementation plans: docs/plans/phase-17-plan.md (ward shell + detail), docs/plans/phase-18-plan.md (charts, replay, reasoning), docs/plans/phase-19-plan.md (clinician feedback).

Clinician testing: clinical-testing-guide.md — step-by-step guide for doctors and nurses participating in evaluation sessions.


9. Troubleshooting

Symptom Likely cause Fix
Blank ward / network errors in console API not running or wrong URL Start API; check VITE_API_URL
CORS error in browser Dashboard origin not allowed Add origin to API DashboardOptions in appsettings.json
Charts crash on mount Chart data not unwrapped Ensure VitalTrendChart wrapper is used (see TrendsGrid.vue)
Replay bar stuck at 0:00 No timestamped data yet Wait for observations/alerts to load; bounds sync after first fetch
Next Alert shows wrong patient Stale global alert store Fixed in Patient Detail — encounter alerts reload on mount/poll
No patients listed No active encounters Run simulator or use seeded API data
NEWS2 chart empty Scores not computed yet Wait for Kafka news2-scoring consumer after observations ingest
Acknowledge fails 400 Invalid clinician ID Set clinicianId in localStorage or settings store

For API and infrastructure issues, see the root README and docker-compose-usage-and-troubleshooting.md.