""" Configuración centralizada de la aplicación usando Pydantic Settings """ import os from typing import List from pydantic import field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Configuración de la aplicación""" # Application APP_NAME: str = "Anexo76" # La versión se obtiene de la variable de entorno APP_VERSION que se pasa desde Docker # Si no existe, usa un valor por defecto de desarrollo APP_VERSION: str = os.getenv("APP_VERSION", "dev-local") DEBUG: bool = True ENVIRONMENT: str = "development" # Database - Core (Shared) CORE_DB_HOST: str = "postgres-a76" CORE_DB_PORT: int = 5432 CORE_DB_NAME: str = "anexo76_core" CORE_DB_USER: str = "postgres" CORE_DB_PASSWORD: str = "postgres" # Keycloak KEYCLOAK_SERVER_URL: str = "http://localhost:8080/kcauth" KEYCLOAK_REALM: str = "master" KEYCLOAK_CLIENT_ID: str = "anexo76-backend" KEYCLOAK_CLIENT_SECRET: str = "" KEYCLOAK_ADMIN_USERNAME: str = "admin" KEYCLOAK_ADMIN_PASSWORD: str = "admin" # Security SECRET_KEY: str = "change-this-secret-key-in-production" ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 # Synchronization SYNC_SECRET_TOKEN: str = "change-this-sync-token-in-production" CENTRAL_SERVER_URL: str = "http://localhost:8000/api/v1/core/help-center/sync/" SPOKE_URLS: str = "" # Comma separated list of Spoke URLs for Broadcast (Hub only) CLIENT_UUID: str = "" # Unique identifier for this Client instance (Spoke only) # CORS CORS_ORIGINS: str = "http://localhost:5173,http://localhost:3000" # License LICENSE_CHECK_ENABLED: bool = True # External APIs SITAR_API_URL: str = "api.sitar.aduanasoft.com:880" SITAR_API_USER: str = "" SITAR_API_PASSWORD: str = "" model_config = SettingsConfigDict( env_file=[".env", "../.env"], case_sensitive=True, extra="ignore", env_file_encoding="utf-8", ) @field_validator("CENTRAL_SERVER_URL", "SPOKE_URLS", mode="before") @classmethod def strip_quotes(cls, v: str) -> str: if v: return v.strip().strip('"').strip("'") return v @property def core_database_url(self) -> str: """URL de conexión a la base de datos core""" return f"postgresql://{self.CORE_DB_USER}:{self.CORE_DB_PASSWORD}@{self.CORE_DB_HOST}:{self.CORE_DB_PORT}/{self.CORE_DB_NAME}" @property def async_core_database_url(self) -> str: """URL de conexión asíncrona a la base de datos core""" return f"postgresql+asyncpg://{self.CORE_DB_USER}:{self.CORE_DB_PASSWORD}@{self.CORE_DB_HOST}:{self.CORE_DB_PORT}/{self.CORE_DB_NAME}" @property def cors_origins_list(self) -> List[str]: """Lista de orígenes CORS permitidos""" return [origin.strip() for origin in self.CORS_ORIGINS.split(",")] # Instancia global de configuración settings = Settings()