from pydantic_settings import BaseSettings from pydantic import field_validator from typing import Optional class Settings(BaseSettings): # Application APP_NAME: str = "Patherly" DEBUG: bool = False API_V1_PREFIX: str = "/api/v1" # Database - Railway provides DATABASE_URL, we convert it for asyncpg DATABASE_URL: str = "postgresql+asyncpg://postgres:postgres@localhost:5432/patherly" @field_validator("DATABASE_URL", mode="before") @classmethod def convert_database_url(cls, v: str) -> str: """Convert standard postgres URL to asyncpg format.""" if v.startswith("postgresql://"): return v.replace("postgresql://", "postgresql+asyncpg://", 1) return v @property def DATABASE_URL_SYNC(self) -> str: """Get sync URL by removing asyncpg prefix from DATABASE_URL.""" return self.DATABASE_URL.replace("postgresql+asyncpg://", "postgresql://", 1) # JWT Settings SECRET_KEY: str = "your-secret-key-change-in-production-use-openssl-rand-hex-32" ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 15 REFRESH_TOKEN_EXPIRE_DAYS: int = 7 # Security BCRYPT_ROUNDS: int = 12 # Registration REQUIRE_INVITE_CODE: bool = True # Set to False to allow open registration # CORS - set FRONTEND_URL in production (e.g., https://patherly.up.railway.app) CORS_ORIGINS: list[str] = ["http://localhost:3000", "http://localhost:5173", "http://localhost:5174"] FRONTEND_URL: Optional[str] = None @property def allowed_origins(self) -> list[str]: """Get all allowed CORS origins including FRONTEND_URL if set.""" origins = self.CORS_ORIGINS.copy() if self.FRONTEND_URL and self.FRONTEND_URL not in origins: origins.append(self.FRONTEND_URL) return origins class Config: env_file = ".env" case_sensitive = True extra = "ignore" # Ignore extra env vars like DATABASE_URL_SYNC settings = Settings()