"""Application configuration using Pydantic BaseSettings. All secrets and environment-dependent values are loaded from environment variables or a local .env file. No hardcoded secrets in code. """ from functools import lru_cache from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Central application settings loaded from env vars or .env file.""" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) DATABASE_URL: str = ( "postgresql+asyncpg://erp_test_user:testpass@localhost:5432/erp_test" ) REDIS_URL: str = "redis://localhost:6379/0" JWT_SECRET: str = "change-me-to-a-secure-random-string" JWT_ALGORITHM: str = "HS256" JWT_ACCESS_TTL_MINUTES: int = 15 JWT_REFRESH_TTL_DAYS: int = 7 CORS_ORIGINS: str = "http://localhost:3000,http://localhost:3001" UPLOAD_DIR: str = "/tmp/uploads" APP_NAME: str = "ERP Nutzfahrzeuge" APP_ENV: str = "development" @property def cors_origins_list(self) -> list[str]: """Parse CORS_ORIGINS comma-separated string into a list.""" return [o.strip() for o in self.CORS_ORIGINS.split(",") if o.strip()] @property def access_token_ttl_seconds(self) -> int: return self.JWT_ACCESS_TTL_MINUTES * 60 @property def refresh_token_ttl_seconds(self) -> int: return self.JWT_REFRESH_TTL_DAYS * 86400 @lru_cache def get_settings() -> Settings: """Cached settings singleton.""" return Settings() settings = get_settings()