Skip to content

feat(S5): Population Dashboard + drill-in (Director) - #6

Merged
manjula25 merged 7 commits into
feature/caresync-s4-agent-graph-cachefrom
feature/caresync-s5-population-dashboard
Jul 5, 2026
Merged

feat(S5): Population Dashboard + drill-in (Director)#6
manjula25 merged 7 commits into
feature/caresync-s4-agent-graph-cachefrom
feature/caresync-s5-population-dashboard

Conversation

@manjula25

Copy link
Copy Markdown
Collaborator

S5 — Population Dashboard + drill-in (Director)

Delivers the Director's entry narrative (W02), stacked on S4.

On login a Director now lands on a Population Dashboard: ~500 patients as a native-Canvas risk×urgency scatter, a critical-zone count, a projected cost-avoidance figure, and KPI tiles — all computed live from a population aggregate API over HAPI (no chart library per GD10; no precomputed store). Clicking a scatter quadrant drills to a filtered patient list → the existing patient detail view.

What's in it

  • A1 — Population cohort: deterministic (mulberry32) generator of 500 diabetes/CHF/depression patients with US Core race/ethnicity and a per-patient RiskAssessment from a documented heuristic. (User-approved procedural generator in place of real Synthea, for testability/reproducibility.) Also fixes a real import bug: the single ~2,500-entry $batch POST exceeded undici's headers timeout even though HAPI committed everything — now chunked at 250/request, idempotent.
  • A2 — Aggregate API: audited, Director-only GET /api/population/scatter + /summary. Paginated HAPI reads (_count=1000 + link[rel=next]), critical-zone count from real scores vs CRITICAL_RISK_THRESHOLD, cost-avoidance from a pure documented formula (fixture-tested). Director-only enforced via explicit role check + denial audit (since hasScope grants coordinators the same domains).
  • B1 — Director routing:roleHome director → /population, Director-only route guard.
  • B2 — W02 dashboard: native Canvas scatter (reuses S4 canvas seam), computed KPI tiles (not the mockup's static 23/$247,400), honest placeholders for S6+ panels. ~83% mockup fidelity, deviations documented in-file.
  • B3 — Drill-in: risk/urgency quadrant click → client-side filter → /population/patients list (reuses existing getPatient/PatientDetail, no new backend endpoint). pixelToQuadrant is a true mathematical inverse of the paint projection.

Acceptance criteria (issues.md S5) — all met

  • Director login routes to W02 (not the Coordinator panel)
  • Scatter renders ~500 patients from real HAPI-derived aggregates (native Canvas, no chart library)
  • Critical-zone count + cost-avoidance computed from data, not hardcoded
  • Drill-down: cluster → filtered list → patient detail
  • API-boundary tests over seeded data

Verification (local mock / packaged-UI strength)

  • apps/api: 23/23 suites, 106/106 tests (serial; parallel is pre-existing shared-HAPI flake)
  • apps/web: 12/12 files, 108/108 tests
  • Playwright E2E: 8/8 incl. the new Director flow, standalone + under parallel load
  • Live HAPI: 506 patients / 506 RiskAssessments

Full evidence in docs/plans/caresync-ai/verification.md; two-axis code-review (0 hard/blocking findings) in docs/plans/caresync-ai/review.md; changelog under docs/superpowers/specs/feature-caresync-s5-population-dashboard/.

Base

Stacked on feature/caresync-s4-agent-graph-cache — review that PR first; the diff here is S5-only (7 commits).

🤖 Generated with Claude Code

manjula25and others added 7 commits July 5, 2026 15:27
A1: deterministic ~500-patient cohort (diabetes/CHF/depression) with
per-patient RiskAssessment from a documented heuristic and US Core
race/ethnicity; wired into the existing $batch import (idempotent PUT).
B1: roleHome routes Director -> /population; Director-only /population
route via RoleGuard role prop. Placeholder Population page pending B2.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A2: audited population/ aggregate service over HAPI (RiskAssessment +
Encounter, paginated via _count + link[rel=next]) — getPopulationScatter
and getPopulationSummary, Director-only (explicit role check + denial
audit, since hasScope grants coordinator the same domains), cost-avoidance
from a pure documented formula over real risk counts. Also fixes
import-fhir.ts to chunk the $batch POST (250/request) so the ~2500-entry
cohort import no longer exceeds the client's headers timeout.
B2: W02 Population Dashboard — native Canvas risk x urgency scatter (no
chart library, GD10), KPI tiles computed from the summary API, mockup
fidelity ~83% against reference-materials/caresync-population.html with
deviations documented in Population.tsx/PopulationScatterChart.tsx
(Care Team/HEDIS/Activity as S6+ placeholders, no fabricated numbers).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Clicking a scatter point's risk/urgency quadrant (thresholds >=60/>=60,
reusing lib/patient.ts's amber-risk cutoff) filters the already-fetched
scatter array client-side and navigates to /population/patients with the
filtered ids in router state. pixelToQuadrant/unprojectPoint are exact
inverses of the existing paint projection, so hit-testing can't drift from
what's drawn. The new list page reuses the existing GET /api/patients/:id
per id (useQueries, isolated failures) and links into the unmodified
PatientDetail route — no new backend endpoint. Also hoists the shared
risk-dot Tailwind class map (previously duplicated in PatientPanel) into
lib/patient.ts as RISK_DOT_CLASS.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Login -> W02 dashboard (asserts computed KPI values, not the mockup's
hardcoded 23/$247,400/847) -> click the critical risk/urgency quadrant on
the native Canvas scatter -> filtered "Critical -- Act Now" list ->
PatientDetail. Drives the click via the same padding/threshold constants
the scatter paints with, so the test can't drift from the real projection.
Passes standalone and under the full 5-worker parallel suite (bumped the
KPI-tile assertion timeout to 15s -- the population aggregate bulk-reads
~500 patients from HAPI and is the suite's slowest fetch).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rotates the prior slice's verification.md/review.md to verification-s4.md/
review-s4.md (this repo's established per-slice naming convention) and adds
a fresh verification.md documenting S5's evidence: apps/api 23/23 suites
(106/106 tests, serial) against the live-imported ~500-patient cohort,
apps/web 12/12 files (108/108 tests), and the full Playwright E2E suite
(8/8, including the new Director population flow) both standalone and
under parallel load. Also flips the stale S5 checkboxes in issues.md and
implementation-plan.md now that every acceptance bullet is independently
confirmed against the code and this session's live evidence.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both axes reviewed as parallel sub-agents over 9e2f01c...HEAD. Standards:
0 hard violations, 4 non-blocking Fowler-smell judgement calls. Spec: 0
missing/wrong acceptance-bullet requirements, 2 low-severity already-
disclosed deviations (procedural cohort vs literal "Synthea"; team KPIs
deferred to S6/S7). No blocking findings — none require a code change
before shipping S5.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@manjula25
manjula25 merged commit 7f189f3 into feature/caresync-s4-agent-graph-cacheJul 5, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@manjula25