Clinician App — /visit/
The desktop / iPad-class clinician surface. 12 navigable views, 11 chart tabs, two AI-scribe state machines, persistent AI assistant panel, universal ⌘K command palette.
Top navigation
Logo · Today · Patients · Calendar · Inbox⁹ · Documents · Prescriptions² · Billing · Reports · Marketing · ⌘K search · YP avatar
showView(name) swaps .view divs (no router) and toggles the matching .topbar .nav a.active pill.
View list
| View | ID | Purpose |
|---|---|---|
| Today | view-today | Greeting + work queue + AI-marked priorities |
| Patients | view-list | 18 patients grouped by family with subscription divider rows |
| Calendar | view-calendar | Mon–Fri week, color-coded by visit type, home visit dashed |
| Patient chart | view-chart | 3-column shell + 11 working tabs (Sofia Martinez) |
| Newborn home visit | view-home | Mai Nguyen (1d) — birth-history grid + tap-chip measurements |
| Documents | view-docs | Inbound / outbound with 79% Claude auto-routing |
| Post-visit | view-postvisit | Split-screen: Yogini's chart + parent app summary on iPhone mock |
| Inbox | view-inbox | 9 unread, AI-drafted reply preview per message |
| Prescriptions | view-rx | Refill queue + DoseSpot routing + CII handling |
| Billing | view-billing | Atlas-parity 7 widgets + Family-billing rollup (NEW) |
| Reports | view-reports | Clinical-quality + ops + custom queries |
| Marketing | view-marketing | Lead → revenue funnel + active-leads pipeline |
Chart tabs (11)
The patient chart is the prototype's centerpiece. Three columns:
- Left rail (180px): tabs as
.rail-tab[data-chart-tab]. - Center: hero (avatar + name + age + family + pharmacy) then current tab pane.
- Right clinical sidebar (~280px): Critical allergy · Active conditions · Active Rx · AI risk panel · Family billing rollup.
- Sticky bottom action bar: Send Rx · Message · ⚡ Start visit · AI scribe (gold).
Tabs and their default counts:
| Tab | Count | Notes |
|---|---|---|
| Summary | (default) | 3 quick-fact cards + recent activity preview + vitals snapshot. Hero metadata is fully clickable (parent · sibling · pharmacy). |
| Timeline | — | Reverse-chronological feed with badge color per type (sms/appt/note/rx/imm). Click → detail drawer. |
| Notes | 14 | Filters: All · Signed (12) · Drafts (2) · ⚡ AI-drafted (8) · Mine (14). |
| Messages | 26 | All · SMS (24) · Email (2). |
| Tasks | 2/8 | Open / Done. |
| Appointments | 8 | All / Upcoming (1) / Past (7). |
| Documents | 4 | Inbound / Outbound. |
| Diagnoses | 5 active · 3 hist | ICD-10 codes are clickable → drawer with code description + cross-references. |
| Rx | 2 active · 12 all | Epi-pen Jr 0.15mg + Cetirizine 5mg. |
| Labs | — | All / Abnormal. |
| Vitals | — | Trend lines, growth charts, BMI %ile. |
AI Scribe state machine
Two parallel state machines drive the recording experience.
Office scribe — setState(n) 1 → 5
| State | Caption (verbatim from STATE_CAPTIONS) |
|---|---|
| 1 | Step 1 of 5 Sofia just arrived. Yogini reviews her chart — last visit, allergies, what's overdue. |
| 2 | Step 2 of 5 Yogini taps record. Whisper transcribes the conversation in real time. |
| 3 | Step 3 of 5 Recording stopped. Claude drafted a SOAP note in 18 seconds. Yogini reviews + edits. |
| 4 | Step 4 of 5 Note signed. Action plan fires: Rx routes via DoseSpot, follow-up task auto-creates, billing event logs. |
| 5 | Step 5 of 5 Lisa's phone buzzes. Plain-language summary in the parent app — what we did, what to do at home, when to call. |
State 2 plays 6 ElevenLabs audio clips (aud0–aud5) sequenced via playLine(i) to make the demo speak the visit conversation aloud. The transcript reveals progressively in sync.
Newborn home scribe — setStateHome(n) 1 → 3
Same recording banner, but state 2 swaps in #newbornQuick — tap-chip measurement entry for weight, jaundice (Kramer scale), cord status. Stop button routes to home flow (state 3) instead of office state 3.
Routing rule baked in:
const HOME_VISIT_PATIENTS = new Set(['mai']);
function openPatient(id) {
if (HOME_VISIT_PATIENTS.has(id)) showView('home');
else { showView('chart'); setChartTab('summary'); }
}
Detail drawer (8 hidden modals)
Opened by openDetail(id). Slide-in from the right. Closed via Escape or closeDetail(). Not surfaced via navigation — only via clickable rows.
| ID | Subject |
|---|---|
sms | Lisa Martinez text thread — "Sofia coughing 4 days" |
appt | Today 10:30 AM sick visit · 30 min |
note | Signed well-child note · 6/12/2025 |
rx-epi | Epi-pen Jr 0.15 mg · 1 refill · H-E-B Pharmacy |
imm | 4 immunizations from 6y well-child (DTaP #5 / IPV #4 / MMR #2 / Varicella #2) |
icd-J069 | J06.9 Acute upper respiratory infection |
icd-R059 | R05.9 Cough |
icd-Z00121 | Z00.121 Routine well-child exam |
Note editor overlay
Full-screen overlay (#noteEditorOverlay). Driven by the NOTE_DATA literal (see Hardcoded Data Models).
Each section is tagged with provenance:
- ⚡ AI drafted — Claude SOAP output, with
conf: high|med|low - ⚙ Auto-pulled — vitals from device intake or chart lookup
- ✍ Yogini — typed by hand
Per-section actions on draft notes: View AI original · ↻ Regenerate. Edited content gets wrapped in <span class="ne-edited"> (mint highlight) for diff display. Autosave heartbeat increments "Auto-saved · Ns ago" every 5s.
signNote() fires a toast: ✓ Note signed · added to chart timeline · audio purged · parent summary firing in 30s and (for the today's-sick draft) advances to setState(5) → post-visit view.
Persistent AI assistant (Ask AI)
- Floating ⚡ FAB bottom-right toggles
#aiPanel. - Keyboard shortcut: ⌘J / Ctrl+J.
- Context-aware:
updateAiContext()runs on every view change, populating an "I see X" pill — see Hardcoded Data Models — AI panel context. - 6 canned responses keyed by question (substring fallback) — see Hardcoded Data Models — AI responses.
- Simulated typing delay 800–1400ms before rendering response.
- Responses include
<span class="ai-action">deep-links back into the app (open patient, switch view, approve Rx).
Command palette (⌘K)
CMD_ITEMS is a 22-entry array — top-level views, per-patient deep-links (Sofia · Mai · Eli · Mateo · Camila · Jaden), and AI-prefixed commands. Typing > switches the input to AI mode. Arrow-key + Enter navigation. The full list lives in Hardcoded Data Models.
Pressing ? shows a toast hint: ⌘K = command palette · g+t = today · g+p = patients · g+c = calendar · ESC = close.
Toast system
toast(msg, kind?) replaces alert() everywhere. Variants: default, success, error. Auto-dismiss after 3 s.
Backend / API surface implied
These calls aren't implemented in the prototype but are clearly required by the UI:
GET /api/today— provider's day: schedule + AI-flagged tasks + billing snapshot.GET /api/patients?providerId=&groupBy=family— roster grouped by family entity.GET /api/calendar?provider&start&end&view=week— appointments with type + location (office / home).GET /api/patients/{id}/chart?include=...— full chart shell.GET /api/patients/{id}/timeline?from=&to=— feed.GET /api/patients/{id}/notes·POST /api/notes·POST /api/notes/{id}/sign.POST /api/scribe/start·/transcribe(Whisper streaming) ·/draft(Claude SOAP) ·/parent-summary(2nd Claude pass).POST /api/messages/triage·/draft-reply·/{id}/send(Twilio + email OAuth ingest).POST /api/docs/intake(fax + email + portal upload, Claude name+DOB extractor at 79% threshold).- DoseSpot integration for eRx + EPCS for CII.
- Stripe Billing for subscriptions + Setup Intents + invoices + disputes.
- WebSocket / SSE for live transcription captions and "Up next" countdown.
Post-sign worker queue
After signNote() completes, four downstream effects fire (visualized in the post-visit split-screen):
- Note added — chart timeline updated.
- Parent summary — 2nd Claude pass; Expo Push to parent app within 60 s (SLA target).
- Rx routed — DoseSpot.
- Follow-up task — auto-created in Tasks tab.
Parent-summary prompt rules (extracted from copy):
- Second-person voice.
- No ICD-10 codes.
- No vitals dump.
- Numbered lists for actions.
- Yogini's voice (warm, brief).
Sections: WHAT WE DID · WHAT WE FOUND · WHAT TO DO AT HOME · PRESCRIPTIONS SENT · WHEN TO CALL ME · FOLLOW-UP.