pediatric-ai-scribe-v3/.env.example
Daniel 8e4c70aaa8 docs: recording, 24-hour retention, and the STT picker
- docs/speech.md: a new Recording section (wake lock and why it is re-taken
  on visibility, idempotent start, what happens when a recording ends by
  itself, what signing out does), the retention rules, and step-by-step
  instructions for moving audio backups to MinIO.
- Records that the model for a transcription is the user's choice first,
  which is why the picker must only ever offer models the gateway has, and
  that LITELLM_STT_MODELS is a fallback rather than a list known to work.
- api-reference: /api/transcribe takes `module` and returns `backupId`, and
  the Audio Backups group is no longer failure-only.
- configuration.md and .env.example document AUDIO_BACKUPS_S3_*, preferring
  the _FILE credential variants.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
2026-09-10 16:44:17 +02:00

199 lines
8.3 KiB
Text

# ============================================================
# OPENBAO (optional — recommended for production)
# ============================================================
# When these three are set, the container fetches everything else below
# from OpenBao at kv/ped-ai/prod and ignores the equivalent .env values.
# Leave them unset (or blank) to fall back to .env-only (local dev, e2e).
#
# OPENBAO_ADDR=https://app.danvics.com
# OPENBAO_ROLE_ID=<from: bao read auth/approle/role/ped-ai/role-id>
# OPENBAO_SECRET_ID=<from: bao write -f auth/approle/role/ped-ai/secret-id>
# OPENBAO_KV_PATH=kv/ped-ai/prod # override path if needed
# ============================================================
# Everything below is sourced from OpenBao when OPENBAO_ADDR is set.
# Only fill these in for local dev / e2e / when running without vault.
# ============================================================
# ============================================================
# AI PROVIDER (choose one)
# ============================================================
# Option 1: OpenRouter (default, cheapest, NOT HIPAA)
AI_PROVIDER=openrouter
OPENROUTER_API_KEY=sk-or-v1-your-key
# Option 2: AWS Bedrock (HIPAA compliant with BAA)
# AI_PROVIDER=bedrock
# AWS_BEDROCK_REGION=us-east-1
# AWS_ACCESS_KEY_ID=AKIA...
# AWS_SECRET_ACCESS_KEY=...
# (Or use IAM role — no keys needed if running on EC2/ECS)
# Option 3: Azure OpenAI (HIPAA compliant with BAA)
# AI_PROVIDER=azure
# AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
# AZURE_OPENAI_API_KEY=your-key
# AZURE_DEPLOYMENT_NAME=gpt-4o-mini
# AZURE_OPENAI_API_VERSION=2024-02-01
# Option 4: Google Vertex AI (HIPAA compliant with BAA)
# AI_PROVIDER=vertex
# GOOGLE_VERTEX_PROJECT=your-gcp-project-id
# GOOGLE_VERTEX_LOCATION=us-central1
# GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
# (Or use default credentials if running on GCE/GKE/Cloud Run)
#
# Google STT — Gemini inline audio (auto-detected when GOOGLE_VERTEX_PROJECT set)
# TRANSCRIBE_PROVIDER=google
# GOOGLE_STT_MODEL=gemini-2.0-flash # or gemini-2.5-flash for better accuracy
#
# Google TTS — Google Cloud Text-to-Speech (auto-detected when GOOGLE_VERTEX_PROJECT set)
# TTS_PROVIDER=google
# GOOGLE_TTS_VOICE=en-US-Journey-F # female | en-US-Journey-D = male
# Other options: en-US-Studio-O, en-US-Neural2-C, en-US-Neural2-J
# Option 5: LiteLLM Proxy (self-hosted, routes to any provider)
# AI_PROVIDER=litellm
# LITELLM_API_BASE=http://localhost:4000
# LITELLM_API_KEY=sk-litellm-your-key
# Admin can discover available models via the admin panel
#
# LiteLLM Speech-to-Text
# TRANSCRIBE_PROVIDER=litellm
# LITELLM_STT_MODEL=whisper-1 # Use the model name from your LiteLLM model_list
# If your LiteLLM config uses full paths as model names, use the full path:
# LITELLM_STT_MODEL=openai/whisper-1
# NOTE: vertex_ai/chirp does NOT work via LiteLLM audio proxy.
# For Vertex AI speech, use TRANSCRIBE_PROVIDER=google (Gemini inline audio).
#
# LiteLLM TTS
# TTS_PROVIDER=litellm (auto-detected when LITELLM_API_BASE set)
# LITELLM_TTS_MODEL=tts-1 # Use model name from your LiteLLM model_list
# If your config uses full paths: LITELLM_TTS_MODEL=vertex_ai/google-tts
# LITELLM_TTS_VOICE=en-US-Journey-F # Google Cloud voice name (or alloy/nova for OpenAI)
# ============================================================
# TRANSCRIPTION (speech-to-text)
# ============================================================
# Option A: OpenAI Whisper (default if no AWS configured)
OPENAI_API_KEY=sk-your-openai-key
# Option B: Amazon Transcribe (HIPAA eligible, no S3 needed)
# Uses same AWS credentials as Bedrock above.
# Set TRANSCRIBE_PROVIDER=aws to force AWS even if OPENAI_API_KEY is set.
# Leave unset to auto-detect (uses AWS when AWS_BEDROCK_REGION is configured).
# TRANSCRIBE_PROVIDER=aws
# Option C: Local Whisper (privacy-first, no cloud API needed)
# Requires whisper.cpp or faster-whisper installed on the server.
# TRANSCRIBE_PROVIDER=local
# WHISPER_MODEL_SIZE=small # tiny, base, small, medium, large
# WHISPER_BINARY=whisper-cpp # or: whisper, faster-whisper
# WHISPER_MODEL_PATH= # custom path to .bin model file
# WHISPER_LANGUAGE=en
# WHISPER_THREADS=4 # defaults to CPU count - 1
# Amazon Transcribe Medical — better accuracy for clinical dictation
# Knows drug names, diagnoses, procedures, SOAP terminology
# HIPAA eligible (ensure your AWS account has a BAA)
# AWS_TRANSCRIBE_MEDICAL=true
# AWS_TRANSCRIBE_SPECIALTY=PRIMARYCARE
# Other options: CARDIOLOGY, NEUROLOGY, ONCOLOGY, RADIOLOGY, UROLOGY
# Optional
ELEVENLABS_API_KEY=
# Push Notifications (ntfy — self-hosted, optional)
# NTFY_URL=https://ntfy.yourdomain.com
# NTFY_TOKEN=tk_your_token_here
# App
PORT=3000
APP_URL=https://your-domain.com
# Cloudflare Turnstile (anti-bot on registration, optional)
# TURNSTILE_SITE_KEY=your-site-key
# TURNSTILE_SECRET_KEY=your-secret-key
JWT_SECRET=generate-a-random-64-char-string-here
# Application-layer encryption key for PHI at rest (Nextcloud tokens, audio backups)
# Generate with: openssl rand -hex 32
# REQUIRED in production. Rotating invalidates existing encrypted data.
DATA_ENCRYPTION_KEY=generate-with-openssl-rand-hex-32
# Email (for verification & password reset)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM=noreply@yourdomain.com
# Nextcloud (optional)
NEXTCLOUD_URL=https://cloud.yourdomain.com
# S3 Document Storage (optional — works with AWS S3, Backblaze B2, MinIO)
# S3_BUCKET=your-bucket-name
# S3_REGION=us-east-1
# S3_PREFIX=documents/
#
# For AWS S3: uses same AWS credentials as Bedrock above, or set S3-specific keys:
# S3_ACCESS_KEY_ID=...
# S3_SECRET_ACCESS_KEY=...
#
# For Backblaze B2:
# S3_ENDPOINT=https://s3.us-west-004.backblazeb2.com
# S3_REGION=us-west-004
# S3_ACCESS_KEY_ID=your-b2-application-key-id
# S3_SECRET_ACCESS_KEY=your-b2-application-key
#
# For MinIO (self-hosted):
# S3_ENDPOINT=http://minio:9000
# S3_REGION=us-east-1
# S3_ACCESS_KEY_ID=minio-access-key
# S3_SECRET_ACCESS_KEY=minio-secret-key
# S3_FORCE_PATH_STYLE=true
# ============================================================
# EMBEDDINGS (for Learning Hub semantic search)
# ============================================================
# Enables vector-based semantic search in Learning Hub
# Requires pgvector extension: apt-get install postgresql-16-pgvector
# Default model (Vertex AI text-embedding-005, 768 dims, English + code optimized)
EMBEDDING_MODEL=vertex_ai/text-embedding-005
EMBEDDING_DIMENSIONS=768
# Other Vertex AI embedding models:
# - vertex_ai/text-embedding-005 → 768 dims, English + code (recommended)
# - vertex_ai/gemini-embedding-001 → up to 3072 dims, multilingual + code
# - vertex_ai/text-multilingual-embedding-002 → 768 dims, multilingual focus
#
# LiteLLM usage (if using LiteLLM proxy):
# EMBEDDING_MODEL=text-embedding-005 # LiteLLM will route to configured provider
#
# OpenAI fallback (NOT HIPAA-eligible):
# Uses text-embedding-3-small if OPENAI_API_KEY is set and no Vertex/LiteLLM configured
# ============================================================
# DATABASE
# ============================================================
DATABASE_URL=postgresql://pedscribe:<password>@postgres:5432/pedscribe
DB_PASSWORD=pedscribe_secret_change_me
# ── Audio backups (optional) ────────────────────────────────────────────────
# Every recording is kept for 24 hours, whether its transcription succeeded or
# not. Unset, the audio lives in the audio_backups table; set, it goes to a
# bucket instead and only metadata stays in Postgres. The generated-images key
# is scoped to that bucket and cannot be reused here — create a bucket and a
# user of its own, and give the bucket a 24h expiry rule as a backstop.
# Audio is gzipped and AES-256-GCM encrypted before it is stored, either way.
# AUDIO_BACKUPS_S3_ENDPOINT=http://assets:9000
# AUDIO_BACKUPS_S3_BUCKET=audio-backups
# AUDIO_BACKUPS_S3_REGION=us-east-1
# Prefer the _FILE variants: credentials then stay out of the process environment.
# AUDIO_BACKUPS_S3_ACCESS_KEY_FILE=/run/secrets/audio-backups-access-key
# AUDIO_BACKUPS_S3_SECRET_KEY_FILE=/run/secrets/audio-backups-secret-key
# AUDIO_BACKUPS_S3_ACCESS_KEY=
# AUDIO_BACKUPS_S3_SECRET_KEY=