Files
service_manager/backend/app/core/config.py

144 lines
4.6 KiB
Python

"""
Core Configuration - ServiceManagerWeb
Configuración centralizada usando Pydantic Settings v2
"""
from functools import lru_cache
from typing import List, Optional
from pydantic_settings import BaseSettings
from pydantic import field_validator, Field
import os
class Settings(BaseSettings):
"""Configuración de la aplicación."""
model_config = {
"env_file": ".env",
"env_file_encoding": "utf-8",
"case_sensitive": False
}
# ===================================
# GENERAL
# ===================================
ENVIRONMENT: str = Field(default="development")
TESTING: bool = Field(default=False)
DEBUG: bool = Field(default=False)
SECRET_KEY: str = Field(...)
API_VERSION: str = Field(default="v1")
APP_VERSION: str = Field(default="1.9.0")
# ===================================
# DATABASE
# ===================================
DATABASE_URL: str = Field(...)
# ===================================
# REDIS
# ===================================
REDIS_URL: str = Field(...)
# ===================================
# JWT AUTHENTICATION
# ===================================
JWT_SECRET_KEY: str = Field(...)
JWT_ALGORITHM: str = Field(default="HS256")
ACCESS_TOKEN_EXPIRE_MINUTES: int = Field(default=60)
REFRESH_TOKEN_EXPIRE_DAYS: int = Field(default=7)
# ===================================
# CORS
# ===================================
CORS_ORIGINS: str = Field(
default="http://localhost:3000,http://localhost:3001"
)
# ===================================
# EMAIL
# ===================================
SMTP_HOST: str = Field(default="localhost")
SMTP_PORT: int = Field(default=587)
SMTP_USER: Optional[str] = Field(default=None)
SMTP_PASSWORD: Optional[str] = Field(default=None)
SMTP_USE_TLS: bool = Field(default=True)
SMTP_USE_SSL: bool = Field(default=False)
DEFAULT_FROM_EMAIL: str = Field(default="noreply@servicemanager.local")
DEFAULT_FROM_NAME: str = Field(default="ServiceManager")
# ===================================
# FILE UPLOADS
# ===================================
MAX_UPLOAD_SIZE_MB: int = Field(default=10)
ALLOWED_FILE_EXTENSIONS_STR: str = Field(
default="pdf,jpg,jpeg,png,doc,docx,xls,xlsx,txt",
alias="ALLOWED_FILE_EXTENSIONS"
)
UPLOAD_PATH: str = Field(default="/app/uploads")
@property
def ALLOWED_FILE_EXTENSIONS(self) -> List[str]:
"""Parse the comma-separated file extensions."""
return [ext.strip().lower() for ext in self.ALLOWED_FILE_EXTENSIONS_STR.split(",")]
# ===================================
# SECURITY
# ===================================
RATE_LIMIT_ENABLED: bool = Field(default=True)
LOGIN_RATE_LIMIT_WINDOW_SECONDS: int = Field(default=300)
LOGIN_RATE_LIMIT_IP_MAX_ATTEMPTS: int = Field(default=30)
LOGIN_RATE_LIMIT_ID_MAX_ATTEMPTS: int = Field(default=10)
PASSWORD_MIN_LENGTH: int = Field(default=8)
# Argon2 settings
ARGON2_TIME_COST: int = Field(default=3)
ARGON2_MEMORY_COST: int = Field(default=65536)
ARGON2_PARALLELISM: int = Field(default=4)
# ===================================
# LOGGING
# ===================================
LOG_LEVEL: str = Field(default="INFO")
LOG_FORMAT: str = Field(default="json")
LOG_FILE: Optional[str] = Field(default=None)
# ===================================
# FRONTEND URLS
# ===================================
CLIENT_FRONTEND_URL: str = Field(default="http://localhost:3000")
INTERNAL_FRONTEND_URL: str = Field(default="http://localhost:3001")
# ===================================
# HEALTH CHECKS
# ===================================
HEALTH_CHECK_TIMEOUT: int = Field(default=30)
# ===================================
# CELERY
# ===================================
CELERY_BROKER_URL: str = Field(...)
CELERY_RESULT_BACKEND: str = Field(...)
def is_production(self) -> bool:
"""Check if environment is production."""
return self.ENVIRONMENT.lower() == "production"
def is_development(self) -> bool:
"""Check if environment is development."""
return self.ENVIRONMENT.lower() == "development"
def is_testing(self) -> bool:
"""Check if environment is testing."""
return self.ENVIRONMENT.lower() == "testing"
@lru_cache()
def get_settings() -> Settings:
"""
Get cached settings instance.
Using lru_cache to create a singleton pattern for settings.
"""
return Settings()