# Architecture This document is the current high-level map for Ped-AI. It is intentionally shorter and more operational than the older deep-dive files under `docs/logic/`. ## System Shape Ped-AI is a self-hosted Express application with a browser frontend, PostgreSQL storage, Redis operational state, LiteLLM model routing, and optional MCP-backed clinical retrieval. | Area | Owner | Notes | |---|---|---| | Web app | Ped-AI | Auth, UI, clinical workflows, admin settings, notes, Learning Hub, bedside tools | | Database | PostgreSQL | Users, sessions, settings, saved app data, audit/API/access logs | | Operational cache | Redis | Prompt suggestions, lightweight state, queue groundwork; not clinical answer caching | | Model gateway | LiteLLM | Text, speech, image, embedding model discovery and routing | | Clinical retrieval | MCP service | Nextcloud access, indexing, search, rerank, source metadata | | Reverse proxy | Caddy or equivalent | TLS and public routing | ## Request Flow Normal app request: ```txt browser -> reverse proxy -> Express middleware -> auth/session check when protected -> route handler -> PostgreSQL/Redis/provider calls as needed -> JSON or HTML fragment response ``` Clinical Assistant request: ```txt browser -> Ped-AI clinical assistant route -> MCP semantic search for indexed clinical sources -> Ped-AI builds grounded answer prompt -> LiteLLM chat model -> Ped-AI returns answer plus source metadata -> browser renders markdown, citations, and source cards ``` Ped-AI owns the user workflow and rendering. MCP owns retrieval and indexed source metadata. LiteLLM owns model routing. ## Runtime Boundaries | Boundary | Main Risk | Current Direction | |---|---|---| | Browser to Ped-AI | XSS, stale shell, session handling | Sanitized rendering, httpOnly cookie for web, cache busting | | Ped-AI to PostgreSQL | schema drift, slow queries | migrations, maintenance checks, indexes where needed | | Ped-AI to Redis | unavailable operational state | Redis is useful but should not hold required clinical answers | | Ped-AI to LiteLLM | provider downtime, wrong model mode | metadata-based model discovery and timeouts | | Ped-AI to MCP | retrieval latency/failure | explicit MCP client layer and graceful fallback messages | | MCP to Nextcloud | stale indexed metadata | scanner/indexer updates source metadata over time | ## Source Of Truth | Data | Source Of Truth | |---|---| | User accounts and sessions | Ped-AI PostgreSQL | | Admin app settings | Ped-AI PostgreSQL `app_settings` | | Clinical source documents | Nextcloud and MCP index | | Clinical source title/path shown to users | MCP result metadata, especially indexed `file_path` | | Clinical answer text | Generated per request; intentionally not cached | | Model availability | LiteLLM metadata and configured fallbacks | ## Deployment Shape Production usually runs: ```txt Caddy/TLS -> pediatric-ai-scribe container -> pedscribe-db container -> ped-ai-redis container -> LiteLLM endpoint -> MCP endpoint ``` The app should stay private behind the reverse proxy. Do not expose PostgreSQL, Redis, MCP internals, or provider keys publicly. ## Design Principles - Keep Ped-AI stateless enough to run more than one app container. - Keep clinical answer generation live and source-grounded; do not cache final clinical answers. - Prefer model capability metadata over model-name regexes. - Prefer indexed file names and paths over embedded PDF metadata for source titles. - Keep renderer fixes narrow and tested because LLM markdown is messy. - Keep old frontend globals working until the affected feature is intentionally converted to ESM.