"""Public app metadata (display name + version) for the frontend brand layer, the phase-59 docs-push flag (the "Save as doc" gating), and the phase-62 UI customization strings (composer placeholder, footer line). Phase 91 (task 01): the three UI strings are now the EFFECTIVE values — the ``ui_settings`` row (admin Theme tab) over the env values (B1: DB wins when set, env is the fallback), resolved by the SAME :func:`app.core.theming.effective_settings` resolver the ``/api/ui-settings`` API uses, so the brand layer and the tab can never disagree. The route opens a short-lived session (the sync-endpoint house pattern — the route is sync, matching the middleware world). Phase 91 (task 03): the retired CSS-file theming's ``theme`` key is deleted with the mechanism — the five keys below are the entire contract (the colors never rode this endpoint; the server injects them pre-paint, :mod:`app.core.theming`). """ from __future__ import annotations from fastapi import APIRouter, Depends from app.config import Settings, get_settings from app.core import theming from app.db import SessionLocal router = APIRouter(tags=["config"]) @router.get("/config") def app_config(settings: Settings = Depends(get_settings)) -> dict[str, str | bool]: # noqa: B008 """Public app metadata for the frontend brand layer (phase 39) + the phase-59 ``docs_repo_configured`` flag + the phase-62 UI customization keys (``input_placeholder``, ``footer_text``) — all display strings, the SAME boot fetch (no new network surface) and the same public posture as ``app_name`` (no secrets). Phase 91: ``app_name`` / ``input_placeholder`` / ``footer_text`` are the EFFECTIVE values (the admin Theme tab's ``ui_settings`` row over the env values — DB-over-env, B1); the frontend brand layer treats an empty string as "keep the template default" (the unset => byte-identical contract). Phase 91 (task 03): the retired CSS-file theming's ``theme`` key is gone — the five keys are the entire response.""" db = SessionLocal() try: effective = theming.effective_settings(db, settings) finally: db.close() return { "app_name": effective["app_name"], "version": settings.app_version, "docs_repo_configured": settings.docs_configured, "input_placeholder": effective["input_placeholder"], "footer_text": effective["footer_text"], }