"""Endpoints de sante et de configuration publique. Aucune limitation de debit n'est posee ici : le healthcheck du conteneur doit rester fiable meme quand une instance subit un afflux de requetes. """ from __future__ import annotations import logging from fastapi import APIRouter from fastapi.responses import JSONResponse from sqlalchemy import text from app.api.deps import AppSettings, DbSession logger = logging.getLogger(__name__) router = APIRouter(tags=["system"]) # Durees proposees dans l'interface. `None` = permanent. SHARE_EXPIRY_OPTIONS: list[int | None] = [1, 7, 30, 90, None] @router.get("/health", summary="Etat du service") def health() -> dict[str, str]: return {"status": "ok"} @router.get("/ready", summary="Le service peut-il repondre : base de donnees joignable") def ready(session: DbSession): # type: ignore[no-untyped-def] """Complete /health : verifie que SQLite repond reellement. Utile derriere un orchestrateur qui doit distinguer "processus vivant" de "capable de servir", par exemple quand le volume de donnees est absent ou en lecture seule. """ try: session.execute(text("SELECT 1")) except Exception: logger.exception("Base de donnees injoignable") return JSONResponse(status_code=503, content={"status": "unavailable"}) return {"status": "ready"} @router.get("/config", summary="Configuration publique exposee au frontend") def public_config(settings: AppSettings) -> dict[str, object]: """Aucun secret ici : uniquement ce dont l'interface a besoin.""" return { "appName": settings.app_name, "maxNodes": settings.max_nodes, "maxMapSizeMb": settings.max_map_size_mb, "maxShareSizeMb": settings.max_share_size_mb_effective, "sharingEnabled": settings.sharing_enabled, "allowPermanentShares": settings.allow_permanent_shares, "defaultShareExpiryDays": settings.default_share_expiry_days, "shareExpiryOptions": SHARE_EXPIRY_OPTIONS, }