pediatric-ai-scribe-v3/docs/configuration.md
Daniel 2f6e5a7d8f feat: neonatal calculator, DOCX/PPTX/ODT/EPUB support, gateway-agnostic URL helper, TTS/STT fixes
- Add neonatal assessment calculator: GA classification (extremely preterm through
  post term), weight-for-GA percentile (AGA/SGA/LGA) using Fenton 2013 LMS data,
  birth weight category (ELBW/VLBW/LBW/normal/macrosomia)
- Add DOCX support via mammoth, PPTX/ODT/EPUB via jszip in Learning Hub content
  generator file upload
- Add gatewayUrl() helper for consistent API URL construction — handles
  LITELLM_API_BASE with or without /v1 suffix, works with any OpenAI-compatible
  gateway (LiteLLM, Bifrost, etc.)
- Fix TTS model/voice separation: discovery now tags items as MODEL or VOICE,
  auto-detects provider from voice name (Vertex, ElevenLabs, OpenAI)
- Fix STT discovery to include ElevenLabs Scribe and Chirp models
- Fix TTS discovery to include ElevenLabs and Vertex voices alongside models
- Fix admin model test to bypass allowlist check (skipAllowlistCheck) so
  discovered models can be tested before adding
- Fix Nextcloud token decryption in learningAI.js WebDAV browse and file import
- Fix admin embedding test to show DB model name instead of hardcoded default
- Fix admin STT test to use correct endpoint for Whisper models
- Add AI gateway migration guide to configuration docs
- Add Grafana dashboard JSON for Loki log visualization
2026-04-19 02:17:06 +02:00

8.3 KiB

Configuration

Runtime configuration sources, in override order (later wins for overlapping keys):

  1. .env file / container environment variables (startup only)
  2. app_settings table (live, editable from Admin Panel with 2-minute cache)

Environment variables

Core (production-required)

Variable Purpose
APP_URL Public base URL. Enables production mode — fail-closed CORS, HSTS, secure cookies.
JWT_SECRET HMAC key for JWT signing and OIDC state. Server refuses to start without it in production.
DATA_ENCRYPTION_KEY AES-256-GCM key for PHI at rest (Nextcloud tokens, audio backups). 64 hex chars (openssl rand -hex 32). Refuses to start without it in production.
DB_PASSWORD / DATABASE_URL Postgres password or full connection string.
PORT HTTP listen port (default 3000).
NODE_ENV production forces prod-only guards on even without APP_URL.

CORS

Variable Purpose
CORS_ORIGINS Comma-separated additional allowed origins beyond APP_URL.

AI provider

Variable Purpose
AI_PROVIDER openrouter / bedrock / azure / vertex / litellm. Auto-detected by credential presence if unset.
OPENROUTER_API_KEY OpenRouter key (not HIPAA-eligible).
AWS_BEDROCK_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY Bedrock / Transcribe / Transcribe-Medical.
AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY, AZURE_DEPLOYMENT_NAME, AZURE_OPENAI_API_VERSION Azure OpenAI.
GOOGLE_VERTEX_PROJECT, GOOGLE_VERTEX_LOCATION, GOOGLE_APPLICATION_CREDENTIALS Vertex AI + Gemini (STT/TTS).
LITELLM_API_BASE, LITELLM_API_KEY OpenAI-compatible AI gateway (Bifrost, LiteLLM, or similar).

Speech-to-text

Variable Purpose
TRANSCRIBE_PROVIDER google, aws, local, openai, litellm. Auto-detects if unset.
OPENAI_API_KEY OpenAI Whisper.
GOOGLE_STT_MODEL Gemini model used as STT (default gemini-2.0-flash).
AWS_TRANSCRIBE_MEDICAL true enables Transcribe Medical.
AWS_TRANSCRIBE_SPECIALTY PRIMARYCARE / CARDIOLOGY / NEUROLOGY / ONCOLOGY / RADIOLOGY / UROLOGY.
WHISPER_BINARY, WHISPER_MODEL_SIZE, WHISPER_MODEL_PATH, WHISPER_LANGUAGE, WHISPER_THREADS Local whisper.cpp / faster-whisper.
LITELLM_STT_MODEL Model name for LiteLLM-routed STT.

Text-to-speech

Variable Purpose
GOOGLE_TTS_VOICE Google Cloud TTS voice (e.g. en-US-Journey-F).
ELEVENLABS_API_KEY ElevenLabs (not HIPAA-compliant).
LITELLM_TTS_MODEL, LITELLM_TTS_VOICE LiteLLM-routed TTS.

Embeddings

Variable Purpose
EMBEDDING_MODEL Embedding model name (default text-embedding-005, Vertex).
EMBEDDING_DIMENSIONS Vector dimensions (default 768).

Email (SMTP)

Variable Purpose
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM SMTP config for verification + password reset emails. Overridable per-instance via app_settings.

Security / external

Variable Purpose
TURNSTILE_SITE_KEY, TURNSTILE_SECRET_KEY Cloudflare Turnstile. Turnstile check is no-op when secret is unset.
LOKI_URL Optional Loki ingest URL for shipping audit/api/access logs.
NTFY_URL, NTFY_TOPIC Optional ntfy push for new-login / password-change notifications.

Integrations

Variable Purpose
NEXTCLOUD_URL Nextcloud base URL (per-user credentials entered in app).
S3_BUCKET, S3_REGION, S3_PREFIX, S3_ENDPOINT, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_FORCE_PATH_STYLE Document object storage. S3_FORCE_PATH_STYLE=true for MinIO, Backblaze B2, most non-AWS providers.

app_settings — live runtime configuration

Key-value rows in the app_settings table. Read via config.get(key, default) with 2-minute in-memory cache. Writes invalidate the cache immediately.

Registration & site

Key Purpose
registration_enabled true/false. Gate new signups.
site.name Display name.
site.auto_delete_days Days before encounters auto-expire (default 7).

Announcements

Key Purpose
announcement.text Banner text. Empty = banner hidden.
announcement.type info / warning / error / success.

SMTP overrides (override env)

smtp.host, smtp.port, smtp.user, smtp.pass, smtp.from.

Email templates

email.{flow}.subject, email.{flow}.body where {flow} is verify / reset / new_login / password_changed.

OIDC / SSO

Key Purpose
oidc.enabled Toggle SSO.
oidc.issuer OIDC issuer URL.
oidc.client_id, oidc.client_secret OAuth client credentials.
oidc.button_label Login-page button text (default "Sign in with SSO").
oidc.disable_local_auth Hide local login form when SSO is enabled.
oidc.allowed_ips CIDR whitelist for SSO (optional).

AI / models / prompts

Key Purpose
models.default Default model ID.
models.disabled JSON array of disabled model IDs.
models.custom JSON array of admin-added models.
ai.allow_model_fallback Enable silent fallback to secondary model on primary failure. Default false — fallback could spill to a non-BAA provider.
stt.model, tts.model, tts.voice System-wide STT/TTS defaults (users can override per-account).
prompt.{name} Prompt overrides. Any template in src/utils/prompts.js can be replaced live.
embeddings.model, embeddings.dimensions Override embedding config.

Feature flags

feature.* — any key matching this prefix can be consulted via config.get('feature.foo').

Internal migration flags

Key Purpose
migration.text_indexes_c Set to 'true' once lookup-critical text indexes have been converted to COLLATE "C". Prevents re-running.

Admin panel

The Admin Panel (/admin route, admin-only) exposes everything above plus:

  • User list: verify, disable, delete, promote to admin/moderator.
  • Session viewer: active sessions per user, admin-revoke.
  • Logs: audit / api / access tables with filtering.
  • Detailed health: /api/health/detailed reports configured providers (admin-only; the public /api/health returns only {ok: true} to avoid leaking stack info).
  • Model management: enable/disable, add custom, set default, discover from provider.
  • Prompt editor: live-edit any PROMPTS.* key.
  • Test SMTP / test STT / test TTS.

Switching AI gateways

The LITELLM_API_BASE and LITELLM_API_KEY variables work with any OpenAI-compatible gateway — LiteLLM, Bifrost, or other proxies.

Migration steps

  1. Set the base URLLITELLM_API_BASE should include /v1 if the gateway serves on that path (e.g., https://gateway.example.com/v1). The application normalizes double /v1 paths internally for TTS, STT, and embedding endpoints.

  2. Set the API keyLITELLM_API_KEY accepts any key format the gateway issues (virtual keys, bearer tokens, etc.).

  3. Update model names — Different gateways use different naming conventions. Bifrost requires provider/model format (e.g., openrouter/vendor-model-sonnet-4.6), while LiteLLM uses aliases (e.g., openrouter-vendor-model-sonnet-4.6). Update model names in:

    • Admin Panel → Models (chat models)
    • Admin Panel → Settings → stt.model (speech-to-text)
    • Admin Panel → Settings → tts.model (text-to-speech)
    • LITELLM_TTS_MODEL env var (if set)
  4. Embedding model — Set via Admin Panel → Settings → embeddings.model. The embedding vector column is VECTOR(768), so any model producing 768 dimensions works without re-embedding (e.g., vertex/text-embedding-005). Switching to a model with different dimensions requires altering the column and re-embedding all content.

  5. Restart the containerdocker compose up -d --force-recreate to pick up .env changes (a plain restart does not re-read .env).

Verified gateways

Gateway Model format Notes
Bifrost provider/model Virtual keys, semantic caching, MCP gateway
LiteLLM Custom aliases Requires PostgreSQL + Redis
Any OpenAI-compatible Varies Must serve /v1/chat/completions, /v1/audio/speech, /v1/audio/transcriptions, /v1/embeddings