"""Application configuration. SPEC §14: the complete env list is read exactly once here (pydantic-settings). No ``os.environ`` access is permitted anywhere else in the codebase. """ from __future__ import annotations from functools import lru_cache from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """All runtime configuration, sourced from the environment (SPEC §14).""" model_config = SettingsConfigDict(env_file=None, extra="ignore") app_domain: str = Field(alias="APP_DOMAIN") database_url: str = Field(alias="DATABASE_URL") redis_url: str = Field(alias="REDIS_URL") master_key: str = Field(alias="MASTER_KEY") # 32 bytes, base64 blob_root: str = Field(default="./var/blobs", alias="BLOB_ROOT") search_backend: str = Field(default="pg", alias="SEARCH_BACKEND") meili_url: str = Field(default="http://127.0.0.1:7700", alias="MEILI_URL") meili_key: str = Field(default="", alias="MEILI_KEY") undo_seconds: int = Field(default=10, alias="UNDO_SECONDS") poll_interval: int = Field(default=120, alias="POLL_INTERVAL") session_ttl_days: int = Field(default=30, alias="SESSION_TTL_DAYS") max_attachment_mb: int = Field(default=25, alias="MAX_ATTACHMENT_MB") log_level: str = Field(default="INFO", alias="LOG_LEVEL") oauth_google_client_id: str = Field(default="", alias="OAUTH_GOOGLE_CLIENT_ID") oauth_google_client_secret: str = Field(default="", alias="OAUTH_GOOGLE_CLIENT_SECRET") oauth_ms_client_id: str = Field(default="", alias="OAUTH_MS_CLIENT_ID") oauth_ms_client_secret: str = Field(default="", alias="OAUTH_MS_CLIENT_SECRET") @lru_cache(maxsize=1) def get_settings() -> Settings: """Return the process-wide settings singleton.""" return Settings() # values are sourced from the environment