from __future__ import annotations import os from dataclasses import dataclass from datetime import timedelta from functools import lru_cache from services.security import JWTSettings @dataclass(frozen=True, slots=True) class Settings: """Application configuration sourced from environment variables.""" jwt_secret_key: str = "change-me" jwt_algorithm: str = "HS256" jwt_access_token_minutes: int = 15 jwt_refresh_token_days: int = 7 @classmethod def from_environment(cls) -> "Settings": """Construct settings from environment variables.""" return cls( jwt_secret_key=os.getenv("CALMINER_JWT_SECRET", "change-me"), jwt_algorithm=os.getenv("CALMINER_JWT_ALGORITHM", "HS256"), jwt_access_token_minutes=cls._int_from_env( "CALMINER_JWT_ACCESS_MINUTES", 15 ), jwt_refresh_token_days=cls._int_from_env( "CALMINER_JWT_REFRESH_DAYS", 7 ), ) @staticmethod def _int_from_env(name: str, default: int) -> int: raw_value = os.getenv(name) if raw_value is None: return default try: return int(raw_value) except ValueError: return default def jwt_settings(self) -> JWTSettings: """Build runtime JWT settings compatible with token helpers.""" return JWTSettings( secret_key=self.jwt_secret_key, algorithm=self.jwt_algorithm, access_token_ttl=timedelta(minutes=self.jwt_access_token_minutes), refresh_token_ttl=timedelta(days=self.jwt_refresh_token_days), ) @lru_cache(maxsize=1) def get_settings() -> Settings: """Return cached application settings.""" return Settings.from_environment()