"""Internal, never-socket-bound FastAPI app that holds every HTTP handler. The public app (``app.main.create_app``) exposes only ``/health`` and the ``/api/ws`` WebSocket. All request/response logic lives here and is reached in exactly one of two ways: * from the WS-RPC proxy (``app.interfaces.realtime.router``), which dispatches client RPCs into this app over an in-process ASGI transport, and * from the test-suite's ``AsyncClient``/``TestClient``. It is intentionally never bound to a socket, so including the routers here adds no public REST surface — the only public routes are the ones ``create_app`` registers. Keeping the handlers in one FastAPI app also means they run through the real middleware, dependencies, validation and error handling, unchanged. """ from __future__ import annotations from fastapi import FastAPI from app.core.config import settings from app.interfaces.http.errors import register_exception_handlers from app.interfaces.http.request_context import RequestContextMiddleware from app.interfaces.http.routers import ( admin, agy, auth, billing, health, invites, knowledge, organizations, projects, sandbox, workforce, ) from app.interfaces.realtime.router import router as realtime_router from app.main import lifespan # shared lifespan installs the realtime bus #: Module-level singleton so the RPC proxy and the tests share one app instance. _rpc_app: FastAPI | None = None def build_rpc_app() -> FastAPI: """Construct the full handler app. Called once per process.""" application = FastAPI( title=settings.app_name, version="0.1.0", description="AI Workforce Platform — internal RPC dispatch surface.", lifespan=lifespan, # This app is reached in-process, never over the network, so the # interactive docs would only be a liability. docs_url=None, openapi_url=None, ) application.add_middleware(RequestContextMiddleware) register_exception_handlers(application) # Same mounting as the old public app: health at the root, everything else # under /api, and the live socket alongside the RPC surface. application.include_router(health.router) application.include_router(auth.router, prefix="/api") application.include_router(invites.router, prefix="/api") application.include_router(organizations.router, prefix="/api") application.include_router(projects.router, prefix="/api") application.include_router(workforce.router, prefix="/api") application.include_router(billing.router, prefix="/api") application.include_router(knowledge.router, prefix="/api") application.include_router(sandbox.router, prefix="/api") application.include_router(admin.router, prefix="/api") application.include_router(agy.router, prefix="/api") application.include_router(realtime_router, prefix="/api") return application def get_rpc_app() -> FastAPI: """Return the process-wide internal app, building it on first use.""" global _rpc_app if _rpc_app is None: _rpc_app = build_rpc_app() return _rpc_app