Files
resolutionflow/backend/app/core/config.py
Michael Chihlas 20c4c40a1f Add invite code registration system for beta
Backend:
- Add InviteCode model with single-use codes
- Add invite API endpoints (create, list, revoke, validate)
- Modify registration to require invite code when enabled
- Add REQUIRE_INVITE_CODE config toggle (default: true)
- Add Alembic migration for invite_codes table

Frontend:
- Add invite code field to registration page
- Validate invite code on blur with visual feedback
- Pass invite code to registration API

Admins can generate invite codes via /api/docs (Swagger UI).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 00:08:06 -05:00

62 lines
2.1 KiB
Python

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"
DATABASE_URL_SYNC: str = "postgresql://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
@field_validator("DATABASE_URL_SYNC", mode="before")
@classmethod
def ensure_sync_url(cls, v: str) -> str:
"""Ensure sync URL uses standard postgresql prefix."""
if v.startswith("postgresql+asyncpg://"):
return v.replace("postgresql+asyncpg://", "postgresql://", 1)
return v
# 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
settings = Settings()