pediatric-ai-scribe-v3/docs/logic
Daniel b53aa34248 feat: ED multi-stage UX, extensions polish, docs viewer + application-logic docs
Three concurrent themes from this session:

═══════════════════════════════════════════════════════════════════
ED ENCOUNTERS — per-stage cards + consolidate→MDM finalize
═══════════════════════════════════════════════════════════════════

UX redesign per Daniel's feedback ("every stage note should be shown,
if AI is told to modify that particular note then the modified version
is used in final mdm"):

- Each generated stage stays on screen as its own editable card with
  its own embedded "Don't Miss" panel. No more single rolling note
  element that gets replaced on each generation.
- gatherCurrentNotes() reads contenteditable text from each stage card
  before any operation (advance, finalize, persist) so inline edits
  flow into the next AI call and the final consolidate.
- Stage badge is now state-accurate. "Stage N (recording)" with yellow
  background after Add-more before generation; "Stage N" with gray
  after generation. Fixes the bug where the badge flipped to Stage 2
  the moment Add-more was clicked.
- Save & Done now runs TWO server-side AI calls in /finalize:
  1. edConsolidate (new prompt) → polished single final note that
     integrates every stage chronologically (HPI / ROS / PE / ED Course /
     A&P with disposition).
  2. edFinalize (rewritten with full inline 2023 AMA E/M element
     rubric — problems / data / risk definitions, level mapping with
     concrete examples) → MDM JSON.
- Two new cards render after finalize: blue-bordered Final Consolidated
  Note + green-bordered MDM. Stage cards become read-only.
- partial_data on the saved row now stores {stages, finalNote, mdm,
  finalized} so resume re-renders the full state.

Why two-call finalize: a single combined prompt makes the model cut
corners on one task. Two focused calls cost ~2× latency at the very end
of an encounter — acceptable since finalize is a one-time terminal
action, not a per-stage hot path.

Files: public/components/ed-encounter.html, public/js/ed-encounters.js,
src/routes/edEncounters.js, src/utils/prompts.js (edConsolidate added,
edFinalize rewritten).

═══════════════════════════════════════════════════════════════════
EXTENSIONS / PAGERS — visual polish
═══════════════════════════════════════════════════════════════════

Multiple iterations based on Daniel's feedback:

- Layout: align-items:flex-start so action buttons stay pinned top-right
  when long numbers wrap (was align-items:center → buttons drifted into
  the text area, causing visible overlap).
- Number: word-break:break-all + min-width:0 + font-feature-settings:tnum
  so long numbers wrap within their column instead of pushing under the
  buttons. Click-to-copy with a 0.55s green flash + ✓ copied badge.
- Phone/pager Font Awesome icon next to the number in the type color —
  at-a-glance type signal (replacing an earlier 3px left stripe that
  Daniel found visually bulky).
- Name: font-weight 700, font-size 14.5px, color g900, letter-spacing
  -0.012em — scan-target headline typography for long lists.
- Alternating subtle backgrounds by index (white vs #fafbfc) so a long
  list reads as distinct rows.
- Hover: card lifts 1px with a soft shadow; action buttons fade from
  55% to 100% opacity. Cubic-bezier transition on transform.
- Entrance: staggered fade-up animation per card (35ms × index, capped
  at 12). prefers-reduced-motion media query disables motion.
- Empty state: 48px FA icon + heading instead of plain gray text.

Files: public/js/extensions.js, public/css/styles.css.

═══════════════════════════════════════════════════════════════════
DOCS REORGANIZATION + APPLICATION-LOGIC DOCS + ADMIN VIEWER
═══════════════════════════════════════════════════════════════════

Document moves (preserving git history via git mv):
  BROWSER_WHISPER_SETUP.md          → docs/browser-whisper-setup.md
  BROWSER_WHISPER_TROUBLESHOOTING.md → docs/browser-whisper-troubleshooting.md
  DEVELOPER_GUIDE.md                → docs/developer-guide-extended.md
  EMBEDDINGS_SETUP.md               → docs/embeddings-setup.md
  FEATURES_EXPLAINED.md             → docs/features-explained.md
  IMPROVEMENTS.md                   → docs/improvements.md
  OPENID_SETUP.md                   → docs/openid-setup.md
  TRANSCRIPTION_OPTIONS.md          → docs/transcription-options.md
README.md updated with the new paths + a Documentation section that
links to docs/logic/ at the top.

New application-logic doc series (~8,300 lines total) at docs/logic/.
Built with 5 parallel doc-writing agents per Daniel's "use multiple
agents" directive. Each doc explains how a part of the app actually
works — application logic, data flow, design decisions, sacred zones,
how-to-extend recipes — at a depth that lets a new dev (or an AI
assistant) modify the code confidently.

  docs/logic/README.md                — index + recommended reading order
  docs/logic/architecture.md (2166 L) — frontend IIFE pattern, lazy tab
                                         load, backend route convention,
                                         schema, encryption, deployment
  docs/logic/clinical-notes.md (1546L) — every note tab + helper trio
  docs/logic/bedside-and-calculators.md (1373L) — bedside ES module
                                         pocket + calculators + PE Guide
                                         + suture selector
  docs/logic/auth-admin-learning.md (1281L) — auth (local+OIDC+2FA) +
                                         admin panel + Learning Hub
                                         (Quiz engine logic at sub-detail
                                         only — TODO follow-up)
  docs/logic/ai-and-voice.md (1128 L) — callAI 5-provider routing,
                                         prompts, voice/STT, helper trio
  docs/logic/ed-encounters.md (821 L) — multi-stage ED + MDM (this
                                         session's worked example)

Admin-only docs viewer:
- New route /api/admin/docs/{tree,file}: recursively walks docs/, returns
  the tree as JSON; /file?path=X validates path stays inside docs/ and
  renders markdown via marked. Both gated by req.user.role==='admin'.
- New tab "Docs" (book icon) in the sidebar, hidden by default and
  revealed in auth.js when user.role==='admin' (same pattern as the
  existing Admin and CMS tabs).
- New component public/components/admin-docs.html: split-pane layout
  with a tree sidebar + filter input + a markdown reader pane.
- New module public/js/admin-docs.js: lazy-loads the tree on first tab
  activation, renders collapsible folders, persists expanded state and
  last-opened path via UIState. Server-rendered HTML so no client
  markdown parser needed.
- CSS for the viewer (responsive split-pane, code-block styling, table
  scrolling, etc.).
- Mounted at /api/admin/docs (NOT /api) — important: mounting a router
  with router.use(authMiddleware) at /api accidentally 401s every other
  /api/* path (caught and fixed during testing — /api/health was 401'ing).

Files: docs/* (moved + new), README.md, public/components/admin-docs.html
(new), public/js/admin-docs.js (new), src/routes/adminDocs.js (new),
public/index.html (tab + section + script), public/js/auth.js (admin
gate + logout cleanup), public/css/styles.css (viewer styles), server.js
(mount).

═══════════════════════════════════════════════════════════════════
KNOWN GAPS (TODO follow-ups)
═══════════════════════════════════════════════════════════════════

- Learning Hub quiz engine (MCQ / multi-select / T-F scoring + attempt
  tracking + progress dashboard) is covered at the architectural level
  in docs/logic/auth-admin-learning.md but not drilled into the quiz
  data model and scoring flow. Worth a focused follow-up doc.
- ED finalize: if MDM step JSON parse fails, server returns 502 with
  the consolidated finalNote in the error payload, but client doesn't
  surface the partial result. Add a "MDM failed, retry" affordance.
- No e2e Playwright coverage for ED encounters or the new docs viewer.
2026-04-28 03:09:38 +02:00
..
ai-and-voice.md feat: ED multi-stage UX, extensions polish, docs viewer + application-logic docs 2026-04-28 03:09:38 +02:00
architecture.md feat: ED multi-stage UX, extensions polish, docs viewer + application-logic docs 2026-04-28 03:09:38 +02:00
auth-admin-learning.md feat: ED multi-stage UX, extensions polish, docs viewer + application-logic docs 2026-04-28 03:09:38 +02:00
bedside-and-calculators.md feat: ED multi-stage UX, extensions polish, docs viewer + application-logic docs 2026-04-28 03:09:38 +02:00
clinical-notes.md feat: ED multi-stage UX, extensions polish, docs viewer + application-logic docs 2026-04-28 03:09:38 +02:00
ed-encounters.md feat: ED multi-stage UX, extensions polish, docs viewer + application-logic docs 2026-04-28 03:09:38 +02:00
README.md feat: ED multi-stage UX, extensions polish, docs viewer + application-logic docs 2026-04-28 03:09:38 +02:00

Application Logic — index

Deep, dev-friendly documentation of how each part of the ped-ai app actually works. Written so a human developer can understand the codebase without spelunking, and so an AI assistant can confidently modify code without breaking sacred zones.

These docs explain application logic — what the user does, what the system does in response, what the data flow is, and why the design looks the way it does. They are not API reference (see ../api-reference.md) and not deployment recipes (see ../deployment.md).

Read in this order

For someone brand new to the codebase:

  1. architecture.md — Start here. The big picture: IIFE frontend pattern, lazy tab loading, backend route convention, PostgreSQL schema, encryption at rest, Dockerfile + compose layout, sacred zones. (~2,000 lines, the longest doc — but the foundation.)

  2. clinical-notes.md — How every clinical note tab works. The shared "record → transcribe → generate → save" lifecycle, then per-tab deep dives for Encounter HPI, Dictation HPI, Sick Visit, Well Visit, SOAP, Hospital Course, Chart Review, and Personal Notes. Includes the helper trio (refine / billing-codes / don't-miss).

  3. ed-encounters.md — The ED encounter feature (multi-stage notes, per-stage don't-miss, consolidate→MDM finalize). Newest, most explicit explanation of how a clinical workflow gets composed in this codebase. Read this for a worked example.

  4. bedside-and-calculators.md — Bedside emergencies module (the one ES-module pocket of the frontend), the pediatric calculators (BP percentile, Fenton growth, bilirubin nomograms, etc.), the PE Guide, vax schedule, milestones. Includes the suture selector. Important: lists every clinical formula that must NOT be modified without test vectors.

  5. ai-and-voice.md — The 5-provider AI routing (callAI), the centralized PROMPTS object with DB overrides, the wrapUserText + INJECTION_GUARD safety pattern, server-side STT routing (Whisper / AWS Transcribe / Vertex / LiteLLM), browser Whisper, the AudioRecorder. Voice/STT plumbing is sacred — the doc describes it without proposing changes.

  6. auth-admin-learning.md — Authentication (local + OIDC SSO + 2FA), session management, OpenBao secret loading at container start, the Admin panel (model allowlist, prompt overrides, milestone editor), and the Learning Hub (AI-authored quizzes / outlines / Marp presentations).

What's NOT here

  • Reference data details. Every clinical formula's math lives in the source files; this doc series points to the formula and explains what it does but doesn't reproduce the lookup tables.
  • API endpoint signatures. See ../api-reference.md.
  • Operational runbooks. See ../deployment.md, ../configuration.md.
  • Recent change history. See git log + the rollback tags (pre-ts-migration-2026-04-26, pre-ed-encounters-2026-04-26, etc.).

Voice + conventions

Each doc follows the same structure:

  • Overview — what this part is and why it exists
  • User flow — what the physician does and sees
  • Data flow — what HTTP calls happen, what the server does
  • File map — which files do what
  • Key design decisionswhy it works the way it does
  • Sacred zones — what NOT to refactor without explicit approval
  • How to extend — concrete recipes for adding a new X

When a doc mentions a sacred zone, it means there's a project-memory rule that this code must not be refactored without per-change approval from Daniel. The full sacred-zone roster:

Zone Why
public/js/encounters.js save/load/idempotency Save/version/idempotency logic has been carefully tuned; refactors keep silently breaking it.
Voice/STT plumbing (audioBackup.js, speechRecognition.js, browserWhisper.js, voicePreferences.js, transcriptionSettings.js, recorder paths in each clinical tab) Recording UX has been hardened against many edge cases; refactor only with smallest-diff bug fixes.
Validated clinical formulas (BP percentile LMS, Fenton 2013, bilirubin AAP 2022, Bhutani, APLS / Best-Guess weight, PE Guide SCALES) Validated against peditools / AAP tables; modifying without test vectors risks miscoding patient care.
Auth + crypto (crypto.js, passwords.js, sessions.js, auth.js, oidc.js) Security; changes without security review are unsafe.
MDM rubric in PROMPTS.edFinalize Load-bearing for billing accuracy; trim only with explicit AMA/coding source citation.

Total size

~8,300 lines of new application-logic documentation across 6 files. If that feels like a lot, remember: the codebase is ~33,000 lines of frontend JS + ~14,000 lines of backend JS. The docs are dense by design — "200% detailed" was the explicit ask. Search them like a reference; don't try to read end to end.

Cross-cutting topics

A few topics span multiple docs. Use these as your jump-off points:

Topic Where to look
The IIFE pattern + window.x = y cross-file globals architecture.md §2-3
Lazy tab loading (loadComponent, tabChanged event) architecture.md §3-4
getUserMemoryContext → templates feeding into AI prompts clinical-notes.md §6, ed-encounters.md §9
The helper trio: refineDocument, suggestBillingCodes, suggestDontMiss ai-and-voice.md §12, clinical-notes.md §5
wrapUserText + INJECTION_GUARD prompt-injection defense ai-and-voice.md §5
saveEncounter API + optimistic locking + idempotency keys architecture.md §13, clinical-notes.md §4, ed-encounters.md §5
cryptoUtil.encryptString / encryptBuffer "enc1:" format architecture.md §12
5-provider AI routing (callAI) ai-and-voice.md §2-3
2023 AMA E/M MDM rubric ed-encounters.md §6
User templates (user_memories table, template_* categories) clinical-notes.md §6, ed-encounters.md §9

How to keep these docs current

Each doc has a date implicit in the most recent feature it describes. When you add a feature, update the relevant doc in the same commit. When you remove a feature (e.g., the Dragon-style AI corrections removal in late April 2026), remove its section + leave a one-line historical note in the relevant doc.

When you write a new doc, follow the same structure as these (Overview / User flow / Data flow / File map / Design decisions / Sacred zones / How to extend) and add it to this index.