|
Some checks failed
Build & release Android APK / Build signed APK (push) Has been cancelled
Build TWA APK / build-apk (push) Has been cancelled
Build & Push Docker Image / Build linux/amd64 (push) Has been cancelled
Build & Push Docker Image / Build linux/arm64 (push) Has been cancelled
Build & Push Docker Image / Merge manifests (push) Has been cancelled
|
||
|---|---|---|
| .github/workflows | ||
| android | ||
| docs | ||
| e2e | ||
| migrations | ||
| mobile | ||
| monitoring | ||
| public | ||
| scripts | ||
| src | ||
| test | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .gitmessage | ||
| .node-pg-migraterc.json | ||
| admin-cli.js | ||
| CONTRIBUTING.md | ||
| docker-compose.e2e.yml | ||
| docker-compose.local.yml | ||
| docker-compose.monitoring.yml | ||
| docker-compose.yml | ||
| docker-entrypoint.sh | ||
| Dockerfile | ||
| grafana-dashboard.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| server.js | ||
Pediatric AI Scribe v6
AI-powered clinical documentation platform for pediatric medicine. Generates HPIs, hospital courses, chart reviews, SOAP notes, well/sick visit notes, and developmental milestone assessments from voice recordings or dictation.
Features
Clinical Documentation
- Live Encounter — record doctor-patient conversations, AI generates structured OLDCARTS HPI
- Voice Dictation — dictate narrative, AI cleans and restructures
- Hospital Course — paste progress notes, generates prose, day-by-day, organ-system (ICU), or psych format
- Chart Review / Precharting — summarize outpatient, subspecialty, and ED notes
- SOAP Notes — full SOAP or subjective-only from dictation
- Well Visit — AAP 2025 Bright Futures periodicity with vaccines, screenings, billing codes, SSHADESS (12+), milestones
- Sick Visit — quick documentation with auto-suggested ROS and PE from chief complaint
- Developmental Milestones — AAP/Nelson tracker (birth-11y) with narrative/structured/summary output
AI & Speech
- 5 AI Providers — OpenRouter, AWS Bedrock, Azure OpenAI, Google Vertex AI, LiteLLM
- 5 STT Providers — Google Gemini, Amazon Transcribe (Medical), OpenAI Whisper, Local Whisper, LiteLLM
- 3 TTS Providers — Google Cloud TTS, LiteLLM (OpenAI), ElevenLabs
- Browser Whisper — fully offline in-browser transcription via WebAssembly (HIPAA-safe)
- Per-tab model selector — choose fast vs. smart vs. premium models per task
- Physician memory system — Dragon-like learning from your corrections
Learning Hub
- Content Management — articles, clinical pearls, quizzes, presentations
- AI Content Generation — generate from topics, uploaded PDFs, or Nextcloud files
- Marp Presentations — slide editor with preview and PPTX export
- Semantic Search — vector-based search via pgvector embeddings
- Quiz System — MCQ, multi-select, true/false with scoring and progress tracking
Platform
- Multi-user with roles — admin, moderator, user
- OIDC/SSO — Azure AD, Okta, Keycloak, PocketID, Google
- 2FA — TOTP-based two-factor authentication
- Cloudflare Turnstile — bot protection on login, register, password reset
- Email verification — with customizable templates
- Nextcloud integration — WebDAV export
- S3 Document Storage — AWS S3, Backblaze B2, MinIO
- PWA — installable, works on mobile
- Admin Panel — user management, settings, prompt editor, model configuration, logs
Quick Start
1. Configure
cp .env.example .env
Edit .env — at minimum set:
AI_PROVIDER=litellm # or openrouter, bedrock, azure, vertex
LITELLM_API_BASE=https://your-litellm.example.com
LITELLM_API_KEY=sk-...
OPENAI_API_KEY=sk-... # for Whisper transcription (if not using LiteLLM STT)
JWT_SECRET=<64-char random> # openssl rand -hex 32
DB_PASSWORD=<strong password>
APP_URL=https://your-domain.com
2. Start
docker compose up -d
App runs on port 3552. First user to register becomes admin.
3. Admin CLI
docker exec pediatric-ai-scribe node admin-cli.js list-users
docker exec pediatric-ai-scribe node admin-cli.js create-admin admin@example.com password123 "Dr. Admin"
docker exec pediatric-ai-scribe node admin-cli.js make-admin user@example.com
docker exec pediatric-ai-scribe node admin-cli.js reset-password user@example.com newpassword
docker exec pediatric-ai-scribe node admin-cli.js toggle-registration
docker exec pediatric-ai-scribe node admin-cli.js stats
AI Provider Configuration
Switch providers by setting AI_PROVIDER in .env. No code changes needed.
| Provider | HIPAA | Config |
|---|---|---|
| LiteLLM | Depends on backend | LITELLM_API_BASE, LITELLM_API_KEY |
| AWS Bedrock | Yes (with BAA) | AWS_BEDROCK_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY |
| Azure OpenAI | Yes (with BAA) | AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY, AZURE_DEPLOYMENT_NAME |
| Google Vertex AI | Yes (with BAA) | GOOGLE_VERTEX_PROJECT, GOOGLE_VERTEX_LOCATION |
| OpenRouter | No | OPENROUTER_API_KEY |
Transcription (Speech-to-Text)
Set TRANSCRIBE_PROVIDER or let the app auto-detect.
| Provider | HIPAA | Config |
|---|---|---|
| Google Gemini | Yes | GOOGLE_VERTEX_PROJECT, GOOGLE_STT_MODEL |
| Amazon Transcribe | Yes | AWS creds + TRANSCRIBE_PROVIDER=aws |
| Amazon Transcribe Medical | Yes | AWS_TRANSCRIBE_MEDICAL=true, AWS_TRANSCRIBE_SPECIALTY=PRIMARYCARE |
| Local Whisper | Yes (offline) | TRANSCRIBE_PROVIDER=local, WHISPER_BINARY, WHISPER_MODEL_SIZE |
| OpenAI Whisper | No | OPENAI_API_KEY |
| LiteLLM | Depends | TRANSCRIBE_PROVIDER=litellm, LITELLM_STT_MODEL |
| Browser Whisper | Yes (client-side) | No config needed — toggle in user settings |
Text-to-Speech
| Provider | HIPAA | Config |
|---|---|---|
| Google Cloud TTS | Yes | GOOGLE_VERTEX_PROJECT, GOOGLE_TTS_VOICE |
| LiteLLM | Depends | LITELLM_TTS_MODEL, LITELLM_TTS_VOICE |
| ElevenLabs | No | ELEVENLABS_API_KEY |
OpenID Connect / SSO
Supports Azure AD, Okta, Keycloak, PocketID, Google, and any OIDC-compliant provider.
- Register callback URL:
https://your-domain.com/api/auth/oidc/callback - Admin Panel > Settings > Configure OIDC (Issuer URL, Client ID, Client Secret)
- Users are auto-created and linked by email on first SSO login
See docs/openid-setup.md for provider-specific guides.
Cloudflare Turnstile (Bot Protection)
Optional CAPTCHA on login, registration, and password reset forms.
TURNSTILE_SITE_KEY=0x4AAA...
TURNSTILE_SECRET_KEY=0x4AAA...
Without SMTP, email verification is skipped and users are auto-verified.
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM=noreply@yourdomain.com
Maintenance CLI
After a Postgres image upgrade (major version bump or silent base-layer change), btree indexes on text columns can become inconsistent with the new ICU/glibc library. The app auto-detects this at startup and reindexes on drift, but you can also trigger it manually:
# Health check — no writes
docker exec pediatric-ai-scribe npm run maint:check
# Rebuild all indexes + refresh collation + ANALYZE
docker exec pediatric-ai-scribe npm run maint:reindex
Run maint:reindex any time after:
- Upgrading the Postgres image (major or minor)
- Restoring from a dump created on a different Linux distro
- Seeing "invalid credentials" on credentials you know are correct
- Seeing
0 rowsreturned from a lookup that should match
The reindex takes seconds on a small DB and a minute or two on larger ones. Safe to run while the app is serving traffic, though queries may slow briefly.
Docker Hub
docker pull danielonyejesi/pediatric-ai-scribe-v3:latest
Minimal compose without building:
services:
app:
image: danielonyejesi/pediatric-ai-scribe-v3:latest
ports:
- "3552:3000"
env_file: .env
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
postgres:
image: pgvector/pgvector:pg16
environment:
POSTGRES_DB: pedscribe
POSTGRES_USER: pedscribe
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U pedscribe"]
interval: 10s
retries: 5
volumes:
pgdata:
HIPAA Notice
This application processes data through third-party AI APIs.
- All connections use HTTPS/TLS
- Authentication required for all AI endpoints
- 2FA and SSO available
- Cloudflare Turnstile bot protection
- AWS Bedrock, Azure OpenAI, and Google Vertex AI offer BAAs
- OpenRouter and ElevenLabs do NOT offer BAAs
- Browser Whisper and Local Whisper keep audio fully private
Do not use real PHI without executed BAAs with all providers in your deployment.
Documentation
See docs/ for the full documentation set.
Application logic — start here if you're new to the codebase
docs/logic/ is a deep, dev-friendly walkthrough of how each part of the app actually works. ~8,300 lines of "how it works and why" — read the index first to know what's there:
- docs/logic/README.md — index + recommended reading order
- docs/logic/architecture.md — frontend IIFE pattern, lazy tab loading, backend route convention, schema, encryption, sacred zones
- docs/logic/clinical-notes.md — every note tab (HPI, dictation, sick, well, SOAP, hospital, chart, notes) with the shared record→generate→save lifecycle
- docs/logic/ed-encounters.md — multi-stage ED notes, per-stage don't-miss, consolidate→MDM finalize. Worked example of how a clinical workflow is composed in this codebase.
- docs/logic/bedside-and-calculators.md — Bedside emergencies module (ES-module pocket of the frontend), pediatric calculators, PE Guide, suture selector. Lists every clinical formula that must NOT be modified without test vectors.
- docs/logic/ai-and-voice.md —
callAI5-provider routing, prompt centralization with DB overrides,wrapUserText+INJECTION_GUARD, server STT routing, browser Whisper, the helper trio (refine/billing/don't-miss). - docs/logic/auth-admin-learning.md — local + OIDC auth, 2FA, sessions, OpenBao secret loading, Admin panel, Learning Hub.
Operational + reference
- Architecture Overview — high-level (the deep version is in docs/logic/architecture.md)
- API Reference
- Database Schema
- Authentication & Security
- AI Providers & Models
- Speech (STT/TTS)
- Learning Hub & CMS
- Configuration Reference
- Deployment Guide
- Developer Guide (short)
- Developer Guide (extended)
- Browser Whisper Setup · Troubleshooting
- Embeddings Setup
- OpenID Connect Setup
- Transcription Options
- Features Explained
- Improvement Roadmap
Development
npm install
cp .env.example .env # edit with your keys
# Requires PostgreSQL with pgvector
node server.js
Testing
Two layers, both zero-config after the initial setup.
Unit tests — pure dose math (Node built-in)
npm test
Runs node --test test/ against public/js/calc-math.js — pure functions for
APLS / Best Guess weight, Parkland, Holliday-Segar 4-2-1, PRAM, Westley,
epi (anaphylaxis vs arrest vs NRP, different concentrations), RSI drugs,
min SBP, ETT sizing, Lund-Browder TBSA. 36 assertions, no dependencies.
End-to-end tests — Playwright smoke suite
Runs a headless Chromium against the live app. 128 tests covering every calculator tab, every Bedside sub-pill + widget, auth-gated pages (encounter, well visit, charts, vaccines, catch-up, learning hub, dictation, settings, FAQ), at both desktop and mobile (Pixel 5) viewports.
# First-time setup: spin up the auth-less test container (port 3553)
docker compose -f docker-compose.yml -f docker-compose.e2e.yml up -d pediatric-scribe-e2e
# Then run the full suite (runs inside an official Playwright container)
npm run e2e
The runner script (scripts/e2e.sh) uses mcr.microsoft.com/playwright so you
don't need Node or browsers on the host.
Test environment:
pediatric-ai-scribe(port 3552) — your normal apppediatric-ai-scribe-e2e(port 3553) — identical image, but withTURNSTILE_SECRET_KEY=""andSMTP_HOST=""so Playwright can log in without a bot challenge. Shares the same Postgres + pgdata volume.- Test user:
e2e-user@ped-ai.test(auto-verified on first register) - Harness page:
public/e2e-harness.htmlloads the calculators component without the auth wall for smoke tests that don't need a logged-in session.
Viewing failures — Playwright writes e2e/test-results/<test-name>/
with:
test-failed-1.png— screenshot at the point of failuretrace.zip— full action trace (replay withnpx playwright show-trace)error-context.md— DOM snapshot and console logs
Everything but the specs and config is gitignored under e2e/.
Files:
e2e/tests/bedside-smoke.spec.js— 26 tests for the Bedside modulee2e/tests/top-calculators.spec.js— 27 tests for BP / BMI / Growth / Bili / Vitals / BSA / Dose / Resus / GCS / Equipmente2e/tests/auth-gated-smoke.spec.js— 11 tests for the auth-gated tabse2e/playwright.config.js— runs all the above under bothchromium(Desktop Chrome) andmobile-chrome(Pixel 5) projects
Writing a new test:
const { test, expect } = require('@playwright/test');
test('my new smoke test', async ({ page }) => {
await page.goto('/e2e-harness.html'); // bypasses auth for calculators
await page.waitForFunction(() => window.__harnessReady === true);
await page.click('button.calc-nav-pill[data-calc="bedside"]');
await expect(page.locator('#calc-bedside')).toBeVisible();
});
For auth-gated routes, use the login fixture in auth-gated-smoke.spec.js
as a template — it caches the token at module scope so you don't hit the
login rate-limit.