- projects: app profile columns + one app per org; project_external_git, deploy_targets, org_model_grants tables (migration a0f0e1d2c3b4) - ports + fakes: RepoWorkspace, DeliveryHooks, DeployTarget, Memory, ModelGrants, WorkforceBootstrap; AppProfile + AppProfileRepository - per-workstream wiring (container_org/engine/delivery), config blocks, empty routers, delivery worker, MCP/delivery service shells, web stubs - admin nav derives from ADMIN_ITEMS; plan docs updated for ext4 worktrees Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
97 lines
3.7 KiB
Python
97 lines
3.7 KiB
Python
"""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,
|
|
admin_domains,
|
|
admin_grants,
|
|
admin_users,
|
|
agy,
|
|
app_setup,
|
|
auth,
|
|
billing,
|
|
delivery,
|
|
health,
|
|
invites,
|
|
knowledge,
|
|
mcp_tokens,
|
|
memory,
|
|
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(admin_users.router, prefix="/api")
|
|
application.include_router(agy.router, prefix="/api")
|
|
# v2 routers (one workstream each; see docs/plan/PLAN-v2.md §6).
|
|
application.include_router(app_setup.router, prefix="/api")
|
|
application.include_router(memory.router, prefix="/api")
|
|
application.include_router(mcp_tokens.router, prefix="/api")
|
|
application.include_router(admin_grants.router, prefix="/api")
|
|
application.include_router(delivery.router, prefix="/api")
|
|
application.include_router(admin_domains.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
|