"""Public process probes, separate from authenticated project diagnostics.""" import asyncio from fastapi import APIRouter, Request from fastapi.responses import JSONResponse from sqlalchemy import text from app.infra.db.metadb.database import engine router = APIRouter(include_in_schema=False) METADATA_TIMEOUT_SECONDS = 2 async def metadata_database_ready() -> bool: try: async with asyncio.timeout(METADATA_TIMEOUT_SECONDS): async with engine.connect() as connection: result = await connection.execute(text("SELECT 1")) return result.scalar_one() == 1 except Exception: # Public probes must not expose connection strings or driver errors. return False @router.get("/health") async def health() -> dict[str, str]: """Check HTTP liveness without project or database dependencies.""" return {"status": "ok"} @router.get("/ready") async def readiness(request: Request) -> JSONResponse: """Check startup, metadata connectivity and the enabled MCP lifecycle.""" started = getattr(request.app.state, "startup_complete", False) runtime = getattr(request.app.state, "mcp_runtime", None) mcp_ready = runtime is None or runtime.ready metadata_ready = await metadata_database_ready() if started else False ready = started and metadata_ready and mcp_ready return JSONResponse( status_code=200 if ready else 503, content={ "status": "ready" if ready else "not_ready", "checks": { "startup": "ready" if started else "not_ready", "metadata_database": ( "not_checked" if not started else "ready" if metadata_ready else "unavailable" ), "mcp_transport": ( "disabled" if runtime is None else "ready" if mcp_ready else "not_ready" ), }, }, headers={"Cache-Control": "no-store"}, )