Files
ai-agent/backend/services/routes.py
Gabriel Vidal 0ff9e40242 refactor(backend): split main.py into domain packages with app.state injection
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>
2026-10-06 23:55:47 +02:00

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)