All documentation Download (Markdown) Technical

cd-assist · dashboard.pdhc.se

Technical manual


cd-assist — Technical Description

Purpose

cd-assist is the individual / point-of-care half of the old dashboard,
kept after the analyse-engine split (#533 / #543). It serves a treating
clinician a single-patient clinical-decision-assist surface: a patient
picker, a CDR1-backed per-patient charts view, and the nurse single-patient
views (summary / AGP / variable / events) federated across the regional CDRs.

It is a low-friction rename of dashboard.pdhc: it keeps the host
dashboard.pdhc.se, the port block 9026–9029, and the container names
dashboard_pdhc_app / dashboard_pdhc_db (compose project dashboard_pdhc).

The group / population features (researcher cohort engine, cohort export,
federated observation-search / stats / canonical / openEHR) were removed
(#543) and now live in the separate analyse.pdhc service. This service is
care-delivery only.

Access model (care-delivery, not analysis)

The clinical routes are gated on a care relationship, not the analysis
phase (app/auth.py):

Spärr (per-patient blocks)

Both the charts series read (app/routes/charts.py::series) and every nurse
read (app/routes/nurse.py::_apply_sparr) apply spärr identically per patient:

  1. Fetch the patient's active blocks from ips.pdhc (app/services/ips_client.py).
  2. Default (coarse) — drop every point whose org_guid is a blocked clinic.
  3. SPARR_LIFT_ENABLED (#471.4, DPO-approved #472) — apply the
    indispensable-care lift: a blocked point is exposed only if an active
    indispensable_care lift on its clinic covers its concept and its date;
    each exposure raises a sparr_lift_exposure audit event.

Every response carries has_blocked_sources so the UI can show the
metadata-only banner (PDL Ch 4 §4).

Architecture

                       ┌── CDR1 (cdr.pdhc.se) ── charts + picker (care-delivery reads)
browser ──SSO──▶ cd-assist ─┤
 (dashboard.pdhc.se)   └── CDR2..CDR5 fan-out ── nurse summary/AGP/variable/events
                            │
                   ips.pdhc (spärr blocks)   Postgres 9026 / Flask(gunicorn) 9027

Components

Data model (app/models/__init__.py)

Environment variables (.env)

Endpoints

Path Method Purpose
/healthz GET liveness + AUTH_MODE
/metadata GET FHIR R5 CapabilityStatement
/ GET /select (picker)
/select GET clinical patient picker (CDR1)
/patient/<guid> GET /patient/<guid>/charts
/patient/<guid>/charts GET per-patient charts page
/api/v1/patient/<guid>/parameters GET concept list for the dropdown
/api/v1/patient/<guid>/series GET series points (CDR1, spärr)
/api/nurse/patient/<guid> GET summary (demographics/conditions/regimen/latest)
/api/nurse/patient/<guid>/agp GET AGP bands + summary (?window=14d\|90d)
/api/nurse/patient/<guid>/variable/<canonical> GET single-variable series (downsampled)
/api/nurse/patient/<guid>/events GET encounter + hypo markers
/workspace, /nurse GET nurse workspace (nurse role/admin)
/api/v1/designs GET/POST/PUT/DELETE user-private saved designs
/admin/audit GET SU-only audit browse (#215)
/admin/audit/export.csv GET SU-only audit CSV export (#215)

Running locally

./start.sh

Containerised (#170 / Option C #157): app + DB both run as Docker containers
in compose project dashboard_pdhc (dashboard_pdhc_app / _db). Health path
is /healthz. The script kills only its own 9026–9029 block and never touches
the Colima DB port destructively.

Tests

app/.venv/bin/python -m pytest app/tests

Port Allocation

All ports bind to 127.0.0.1 (loopback only); external traffic arrives
via the reverse proxy.

Port Service
9027 Flask application (Gunicorn)
9026 PostgreSQL database
9028–9029 Reserved