implementation demo — part 2 of 2

Building the Person-Centered Analytics Demo

The working build log for the T1D vs. T2D longitudinal pilot described in the companion concept article (Part 1) — seven steps, each a self-contained HTML/JS page, with the actual outputs and open issues from building them.

Scope note

This page documents an idea and demo concept, not a validated or deployable system. See Part 1 for the full concept article, audience, and clinical scope limitations. Everything below is a working, in-browser HTML/JS demo built to test whether the Part 1 architecture (person-centered graph, atemporal/temporal toggle, pivot lenses, comparator filter) actually generalizes across two structurally different diseases — it is not itself a clinical tool.

09

Step-by-step: building the DM T1 & T2 demo app

A concrete, ordered build plan for the longitudinal pilot (Section 7b). Written so each step can be handed to Claude as a standalone prompt — run them in order in a fresh Claude session (Claude Code or a project with file-creation enabled).

Stack constraint: the entire demo is built with HTML, JSON, and JavaScript only — no Python, no Node/build step, no server. Every step below runs client-side, directly in the browser, and hands its output forward as a downloadable JSON file (or files) that the next step's HTML page loads. Section 8’s original “FHIR-to-graph ingestion script (Python + NetworkX/Neo4j)” note and Step 2’s original wording are superseded by this constraint.

Step 1 — Generate the synthetic patient corpus

Ask Claude to create a small synthetic dataset before any graph or UI work starts. This avoids any real PHI and gives every later step something concrete to run against.

Outcome (done): step1_corpus_generator.html is a self-contained, in-browser generator (no Python) that produces dm_corpus.json — 9 synthetic T1D + 9 synthetic T2D patients (seeded, reproducible), each a FHIR-flavored bundle (Patient, Condition, Observation, MedicationRequest, Encounter) plus the tags block from Section 7’s schema (facility_tier, resource_status, and, per-disease, presentation_delay_hours/spike_event_count for T1D or time_to_insulin_initiation_years/comorbidity_count for T2D). All data is explicitly marked synthetic (meta.description, synthetic-demo-data resource tags) — no real PHI. This JSON file is the fixed input every later step reads.

Step 2 — Build the FHIR-to-graph ingestion page

Have Claude build an in-browser (HTML + JS, no Python) ingestion tool that reads the JSON corpus and instantiates the graph from Section 3.1:

Outcome (done): step2_graph_builder.html loads dm_corpus.json and builds the graph entirely client-side — explicitly labeled “runs entirely in-browser, no Python/Node required.” It instantiates the five node types and the patient-anchor edges (HAS_OBSERVATION, HAS_DIAGNOSIS, RECEIVES_PLAN, RESULTS_IN) plus the relational edges (SUGGESTS, INDICATES_PLAN, PRODUCED_OUTCOME, MODULATES, CONSTRAINS), merges per-patient graphs into one cohort graph, and renders a node/edge table in the page. It offers five downloads, all generated in-browser: cohort_graph.json (node-link format), cohort_graph.graphml, neo4j_nodes.csv / neo4j_edges.csv (Neo4j-ready, per the original Section 8 note, but produced without touching Neo4j or Python), and graph_summary.json. This satisfies Step 2 under the HTML/JSON/JS-only constraint — the “script” is a browser page, not a Python script.

Step 3 — The two dashboard modes, as built

Built as a single self-contained page (step3_dashboard.html) with no external libraries. It takes a manual file-load of cohort_graph.json (the Step 2 output) via a plain file input, then renders that same graph two ways behind one toggle:

Step 4 — The pivot lens selector, as built

Built as its own self-contained page (step4_pivot_lens.html), loading the same cohort_graph.json from Step 2/3 with no re-ingestion or schema change. A lens toggle re-indexes the identical node/edge set around a chosen anchor instead of a chosen patient:

Step 5 — The comparator filter, as built

Built as its own page (step5_comparator_filter.html), loading the same cohort_graph.json from Steps 2–4 with no re-ingestion. Three independent filter layers sit over the cohort, and each one only constrains the population it applies to — patients it doesn’t apply to pass through unfiltered, so mixed T1D+T2D views stay meaningful:

Step 6 — The clinically-readable output view, as built

Built as its own page (step6_clinical_output_view.html), loading the same cohort_graph.json from Steps 2–5 with no re-ingestion or new derivations — it re-presents what Steps 3–5 already established rather than re-analyzing anything:

Step 7 — The generalization sanity check, as written

Delivered as its own written report (step7_generalization_check.html) rather than an interactive tool, since Section 7b asked for a confirmation in writing. It audits the actual source of Steps 2–6 for every place condition_type, "T1D", or "T2D" appears, and classifies each occurrence as either generic (used only to filter, count, or label) or special-cased (the rendering/filtering logic itself branches by disease). Verdict: mostly confirmed, with two flagged exceptions rather than none.

Prompt block to paste into Claude

Copy this into a new Claude conversation (ideally with code execution / file creation enabled) to kick off Step 1. Steps 2–7 can each be pasted in turn as the prior step's output is reviewed.

Build a small demo app for the "Person-Centered Clinical Analytics" concept,
scoped to the Type 1 vs. Type 2 diabetes longitudinal pilot.

Stack constraint: HTML, JSON, and JavaScript only. No Python, no Node/build
step, no server/database. Every stage is a standalone HTML page that runs
in-browser and hands its output to the next stage as a downloadable JSON file.

Step 1: Generate a synthetic patient corpus.
- 8-10 synthetic T1D patients, 8-10 synthetic T2D patients (clearly synthetic,
  no real PHI).
- Each as a FHIR-flavored JSON bundle: Patient, Observation, Condition,
  MedicationRequest, Encounter.
- T1D cases: include irregular acute-spike events (DKA admission,
  hypoglycemic event, pump/CGM failure) with timestamps.
- T2D cases: include a long, slow-branching regimen (lifestyle -> oral
  agent -> combination -> insulin) with comorbidity onset dates
  (hypertension, dyslipidemia, CKD, retinopathy).
- Tag every case with: facility_tier (primary/secondary/tertiary/quaternary),
  resource_status (plenty/constrained), and a relevant temporal delay field.

Once this is generated and I've reviewed it, I'll ask you to build the graph
ingestion script, then the dashboard (atemporal/temporal toggle, pivot lens,
comparator filter) on top of it.