docs: document server-side rendering pipeline, response timing middleware, and Telegram pairing API

- Add comprehensive documentation for backend content rendering in AGENTS.md, detailing the new `render_content` and `render_title` Jinja globals built on mistune with media processing, emoji shortcodes, and XSS protection
- Document the `X-Response-Time` header and bottom-left render time indicator in README.md
- Update bot token pricing documentation to clarify fallback vs gateway cost headers
- Add `email_accounts` to soft-delete tables and `idx_users_role` composite index in database schema
- Implement `telegram_pairings` and `telegram_links` table creation with column migration and indexes
- Add `/profile/{username}/telegram` endpoint to docs API with request/unpair actions
- Register `TelegramService` in main.py lifespan and add `response_timing` middleware emitting `X-Response-Time` header
- Introduce `TelegramPairForm` model and `guard_public_host_sync` synchronous host validation function
This commit is contained in:
2026-06-18 22:09:34 +00:00
parent 95dca73291
commit 6ceca3d0d4
146 changed files with 6079 additions and 392 deletions
+14
View File
@@ -38,6 +38,7 @@ DEFAULT_FETCH_TIMEOUT_SECONDS = 300.0
DEFAULT_FETCH_MAX_BYTES = 8_000_000
DEFAULT_RSEARCH_URL = "https://rsearch.app.molodetz.nl"
DEFAULT_RSEARCH_TIMEOUT_SECONDS = 300.0
DEFAULT_EMAIL_TIMEOUT_SECONDS = 30.0
@dataclass(frozen=True)
@@ -72,6 +73,8 @@ class Settings:
rsearch_enabled: bool
rsearch_url: str
rsearch_timeout_seconds: float
email_enabled: bool
email_timeout_seconds: float
daily_limit_usd: float
@@ -152,6 +155,11 @@ def load_settings() -> Settings:
rsearch_timeout_seconds=float(
os.environ.get("DEVII_RSEARCH_TIMEOUT", DEFAULT_RSEARCH_TIMEOUT_SECONDS)
),
email_enabled=os.environ.get("DEVII_EMAIL_ENABLED", "1").lower()
in ("1", "true", "yes", "on"),
email_timeout_seconds=float(
os.environ.get("DEVII_EMAIL_TIMEOUT", DEFAULT_EMAIL_TIMEOUT_SECONDS)
),
daily_limit_usd=0.0,
)
@@ -176,6 +184,8 @@ FIELD_FETCH_TIMEOUT = "devii_fetch_timeout"
FIELD_RSEARCH_ENABLED = "devii_rsearch_enabled"
FIELD_RSEARCH_URL = "devii_rsearch_url"
FIELD_RSEARCH_TIMEOUT = "devii_rsearch_timeout"
FIELD_EMAIL_ENABLED = "devii_email_enabled"
FIELD_EMAIL_TIMEOUT = "devii_email_timeout"
LESSONS_DB_PATH = os.environ.get("DEVII_LESSONS_DB", str(DEVII_LESSONS_DB))
@@ -234,5 +244,9 @@ def build_settings(
rsearch_timeout_seconds=float(
config.get(FIELD_RSEARCH_TIMEOUT) or DEFAULT_RSEARCH_TIMEOUT_SECONDS
),
email_enabled=bool(config.get(FIELD_EMAIL_ENABLED, True)),
email_timeout_seconds=float(
config.get(FIELD_EMAIL_TIMEOUT) or DEFAULT_EMAIL_TIMEOUT_SECONDS
),
daily_limit_usd=effective_daily_limit(config, owner_kind, is_admin),
)