"""Application configuration using Pydantic Settings.""" from functools import lru_cache from typing import Optional from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Application settings loaded from environment variables.""" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, ) # Database (port 5434 to avoid conflict with Hub Postgres and other services) DATABASE_URL: str = "postgresql+asyncpg://orchestrator:orchestrator@localhost:5434/orchestrator" # Application DEBUG: bool = False APP_NAME: str = "LetsBe Orchestrator" APP_VERSION: str = "0.1.0" # Connection pool settings DB_POOL_SIZE: int = 5 DB_MAX_OVERFLOW: int = 10 DB_POOL_TIMEOUT: int = 30 DB_POOL_RECYCLE: int = 1800 # Authentication # Admin API key for protected endpoints (registration token management) # MUST be set via ADMIN_API_KEY environment variable ADMIN_API_KEY: str = Field( description="API key for admin endpoints. MUST be set via ADMIN_API_KEY env var.", ) # ============================================================ # LOCAL MODE SETTINGS # When LOCAL_MODE=true, orchestrator runs in single-tenant mode # with automatic tenant bootstrap on startup. # When LOCAL_MODE=false (default), multi-tenant behavior is unchanged. # ============================================================ LOCAL_MODE: bool = Field( default=False, description="Enable single-tenant local mode. When true, auto-creates tenant on startup.", ) # Instance identification (from Hub activation) INSTANCE_ID: Optional[str] = Field( default=None, description="Unique instance identifier from Hub activation. Required in LOCAL_MODE.", ) # Hub integration for telemetry (optional) HUB_URL: Optional[str] = Field( default=None, description="Hub API URL for telemetry. Optional even in LOCAL_MODE.", ) HUB_API_KEY: Optional[str] = Field( default=None, description="Hub API key for telemetry authentication. Required if HUB_URL is set.", ) HUB_TELEMETRY_ENABLED: bool = Field( default=False, description="Whether to send telemetry to Hub. Requires HUB_URL and HUB_API_KEY.", ) HUB_TELEMETRY_INTERVAL_SECONDS: int = Field( default=60, ge=10, le=600, description="Interval between telemetry submissions in seconds.", ) # Local tenant settings (used when LOCAL_MODE=true) LOCAL_TENANT_DOMAIN: str = Field( default="local.letsbe.cloud", description="Domain for auto-created local tenant.", ) # CORS CORS_ALLOWED_ORIGINS: str = Field( default="", description="Comma-separated list of allowed CORS origins. Empty disables CORS.", ) # Dedicated key for local agent registration (Phase 2) # More restrictive than ADMIN_API_KEY - can ONLY register the local agent LOCAL_AGENT_KEY: Optional[str] = Field( default=None, description="Key for local agent registration. Required when LOCAL_MODE=true.", ) @lru_cache def get_settings() -> Settings: """Get cached settings instance.""" return Settings() # For backward compatibility settings = get_settings()