Backend (replaces PHP api.php + auth.php): - FastAPI app with routers: jobs, auth, billing - Supabase JWT authentication in deps.py - Celery + Redis job queue (process_pdf_task) - MinIO S3-compatible storage service - PDF checker wrapper (delegates to enterprise_pdf_checker.py) - Stripe billing: checkout, portal, webhook handler Multi-tenancy (Phase 3): - Alembic migration 001: workspaces, workspace_members, jobs, usage_events - Row-Level Security on all tenant tables via app.workspace_id session var - Monthly quota enforcement per workspace (402 on exceeded) - Plan tiers: free(5) / pro(100) / business(unlimited) Config: - pydantic-settings based config.py (no hardcoded values) - docker-compose.yml rewritten: postgres, redis, minio, api, celery Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
61 lines
1.7 KiB
Python
61 lines
1.7 KiB
Python
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
from functools import lru_cache
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
# App
|
|
app_url: str = "http://localhost:3000"
|
|
environment: str = "development"
|
|
secret_key: str = "dev-secret-change-in-production"
|
|
|
|
# Database
|
|
db_host: str = "localhost"
|
|
db_port: int = 5432
|
|
db_name: str = "pdf_accessibility"
|
|
db_user: str = "pdf_accessibility"
|
|
db_password: str = "changeme"
|
|
|
|
@property
|
|
def database_url(self) -> str:
|
|
return f"postgresql+asyncpg://{self.db_user}:{self.db_password}@{self.db_host}:{self.db_port}/{self.db_name}"
|
|
|
|
@property
|
|
def sync_database_url(self) -> str:
|
|
return f"postgresql://{self.db_user}:{self.db_password}@{self.db_host}:{self.db_port}/{self.db_name}"
|
|
|
|
# Supabase Auth
|
|
supabase_url: str = ""
|
|
supabase_anon_key: str = ""
|
|
supabase_service_role_key: str = ""
|
|
supabase_jwt_secret: str = ""
|
|
|
|
# Redis / Celery
|
|
redis_url: str = "redis://localhost:6379/0"
|
|
|
|
# Storage (MinIO / S3)
|
|
storage_endpoint: str = "http://localhost:9000"
|
|
storage_access_key: str = "minioadmin"
|
|
storage_secret_key: str = "minioadmin"
|
|
storage_bucket: str = "pdf-pages"
|
|
|
|
# AI Providers
|
|
anthropic_api_key: str = ""
|
|
google_api_key: str = ""
|
|
google_application_credentials: str = ""
|
|
|
|
# Stripe
|
|
stripe_secret_key: str = ""
|
|
stripe_webhook_secret: str = ""
|
|
stripe_price_pro: str = ""
|
|
stripe_price_business: str = ""
|
|
|
|
# File retention
|
|
retention_hours: int = 24
|
|
results_retention_hours: int = 720
|
|
|
|
|
|
@lru_cache
|
|
def get_settings() -> Settings:
|
|
return Settings()
|