"""Shared configuration — Pydantic Settings loaded from environment. All services import ``settings`` from here. Each service only uses a subset of the vars, but keeping one Settings class avoids fragmentation. """ from typing import Literal from pydantic import field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): # ── Database ───────────────────────────────────────────────────── DATABASE_URL: str = "postgresql+asyncpg://postgres:postgres@localhost:5432/adiuva" # ── JWT ──────────────────────────────────────────────────────── # RS256 public key (PEM). Used by any service that needs to verify # JWTs locally (optional — Traefik ForwardAuth handles this in prod). # The private key lives ONLY in the Auth Service config. JWT_PUBLIC_KEY: str = "" @field_validator("JWT_PUBLIC_KEY", mode="before") @classmethod def _expand_pem_newlines(cls, v: str) -> str: if isinstance(v, str) and r"\n" in v: return v.replace(r"\n", "\n") return v JWT_ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 JWT_REFRESH_TOKEN_EXPIRE_DAYS: int = 30 # ── Redis ──────────────────────────────────────────────────────── REDIS_URL: str = "redis://localhost:6379/0" # ── Stripe ─────────────────────────────────────────────────────── STRIPE_SECRET_KEY: str = "" STRIPE_WEBHOOK_SECRET: str = "" # ── S3 ─────────────────────────────────────────────────────────── S3_BUCKET: str = "" S3_REGION: str = "us-east-1" S3_ENDPOINT_URL: str = "" AWS_ACCESS_KEY_ID: str = "" AWS_SECRET_ACCESS_KEY: str = "" # ── Vector stores ──────────────────────────────────────────────── PINECONE_API_KEY: str = "" PINECONE_INDEX: str = "adiuva" QDRANT_URL: str = "" QDRANT_API_KEY: str = "" # ── LLM providers ──────────────────────────────────────────────── OPENAI_API_KEY: str = "" ANTHROPIC_API_KEY: str = "" GOOGLE_API_KEY: str = "" CEREBRAS_API_KEY: str = "" LLM_MODEL: str = "gpt-4o" LLM_ROUTER_MODEL: str = "gpt-4o-mini" LLM_EMBED_MODEL: str = "text-embedding-3-small" GITHUB_COPILOT_TOKEN_DIR: str = "" # ── OAuth (integrations) ───────────────────────────────────────── GMAIL_CLIENT_ID: str = "" GMAIL_CLIENT_SECRET: str = "" MS_CLIENT_ID: str = "" MS_CLIENT_SECRET: str = "" MS_TENANT_ID: str = "common" OAUTH_ENCRYPTION_KEY: str = "" # ── CORS ───────────────────────────────────────────────────────── CORS_ORIGINS: list[str] = ["app://.", "http://localhost:3000", "http://localhost:5173"] # ── Environment ────────────────────────────────────────────────── ENV: Literal["dev", "prod"] = "dev" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", extra="ignore" ) settings = Settings()