Initial commit: webmail client (M0/M1)
Three-pane webmail client. - Backend: FastAPI + async SQLAlchemy + arq worker (Postgres/Redis), IMAP/SMTP sync, threading, search, drafts/outbox with undo, attachments, 2FA. - Frontend: React 18 + Vite + TypeScript + TanStack Query + Tailwind; three-pane UI with rich-text composer, light/dark themes, resizable panels. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
"""Application configuration.
|
||||
|
||||
SPEC §14: the complete env list is read exactly once here (pydantic-settings).
|
||||
No ``os.environ`` access is permitted anywhere else in the codebase.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import lru_cache
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""All runtime configuration, sourced from the environment (SPEC §14)."""
|
||||
|
||||
model_config = SettingsConfigDict(env_file=None, extra="ignore")
|
||||
|
||||
app_domain: str = Field(alias="APP_DOMAIN")
|
||||
database_url: str = Field(alias="DATABASE_URL")
|
||||
redis_url: str = Field(alias="REDIS_URL")
|
||||
master_key: str = Field(alias="MASTER_KEY") # 32 bytes, base64
|
||||
|
||||
blob_root: str = Field(default="./var/blobs", alias="BLOB_ROOT")
|
||||
|
||||
search_backend: str = Field(default="pg", alias="SEARCH_BACKEND")
|
||||
meili_url: str = Field(default="http://127.0.0.1:7700", alias="MEILI_URL")
|
||||
meili_key: str = Field(default="", alias="MEILI_KEY")
|
||||
|
||||
undo_seconds: int = Field(default=10, alias="UNDO_SECONDS")
|
||||
poll_interval: int = Field(default=120, alias="POLL_INTERVAL")
|
||||
session_ttl_days: int = Field(default=30, alias="SESSION_TTL_DAYS")
|
||||
max_attachment_mb: int = Field(default=25, alias="MAX_ATTACHMENT_MB")
|
||||
log_level: str = Field(default="INFO", alias="LOG_LEVEL")
|
||||
|
||||
oauth_google_client_id: str = Field(default="", alias="OAUTH_GOOGLE_CLIENT_ID")
|
||||
oauth_google_client_secret: str = Field(default="", alias="OAUTH_GOOGLE_CLIENT_SECRET")
|
||||
oauth_ms_client_id: str = Field(default="", alias="OAUTH_MS_CLIENT_ID")
|
||||
oauth_ms_client_secret: str = Field(default="", alias="OAUTH_MS_CLIENT_SECRET")
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def get_settings() -> Settings:
|
||||
"""Return the process-wide settings singleton."""
|
||||
return Settings() # values are sourced from the environment
|
||||
Reference in New Issue
Block a user