main.py (5146 lines, 106 routes) becomes an assembly only: one package per domain — core, files, settings, dashboards, conversations, diff, notifications, forms, runs, accounts, workers, models, cron, agents, projects, services, goals, memories, plans, templates — each exposing an APIRouter; the flat domain modules move into their package behind a barrel that keeps the old `import conversations` / `import projects` spellings. The shared singletons (store, meta_store, hub, indexer, …) are built once by core.state.build_state() and attached to app.state.ai; routes take them as the `deps: State` dependency and helpers as an explicit `deps: AppState`. conversations/pricing.py carries the per-model rates out of the parser. Verified: route table and OpenAPI byte-identical; 90 read endpoints golden-diffed against the monolith on a copy of the live data (identical); write routes smoke-tested; 66 backend tests pass. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
37 lines
1.2 KiB
Python
37 lines
1.2 KiB
Python
"""Services catalog routes."""
|
|
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from fastapi.responses import PlainTextResponse
|
|
|
|
import schemas
|
|
from core.http import _r
|
|
from services import catalog as svc_mod
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# ── services catalog (the repo's services/ dir — read-only, no Docker) ────────
|
|
@router.get("/api/services", responses=_r(schemas.ServicesResponse))
|
|
def services_list():
|
|
"""Card metadata for every service dir (containers/urls/auth, newest first)."""
|
|
return {"services": svc_mod.list_services()}
|
|
|
|
|
|
@router.get("/api/service", responses=_r(schemas.ServiceDetail))
|
|
def service_detail(slug: str):
|
|
"""Full parse of one service: containers, Traefik routers, env keys, tree."""
|
|
detail = svc_mod.service_detail(slug)
|
|
if detail is None:
|
|
raise HTTPException(404, "service not found")
|
|
return detail
|
|
|
|
|
|
@router.get("/api/service-file")
|
|
def service_file(slug: str, path: str):
|
|
"""A single whitelisted text file's contents from a service dir (512 KB cap)."""
|
|
txt = svc_mod.service_file(slug, path)
|
|
if txt is None:
|
|
raise HTTPException(404, "file not found or not previewable")
|
|
return PlainTextResponse(txt)
|