init
This commit is contained in:
108
backend/routes.py
Normal file
108
backend/routes.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""API des Viewers (Phase 2). Lese-Routen über viewer.py, Lauf-Routen über scan_dienst."""
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
import agents
|
||||
import database as db
|
||||
import projekte
|
||||
import scan_dienst
|
||||
import viewer
|
||||
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
|
||||
def _wurzel(name: str) -> Path:
|
||||
wurzel = projekte.finde(name)
|
||||
if wurzel is None:
|
||||
raise HTTPException(404, f"Projekt '{name}' nicht in projekte.txt")
|
||||
return wurzel
|
||||
|
||||
|
||||
@router.get("/health")
|
||||
async def health():
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.get("/projekte")
|
||||
async def liste():
|
||||
out = []
|
||||
for p in projekte.lade():
|
||||
eintrag = dict(p)
|
||||
if "fehler" not in p:
|
||||
wurzel = Path(p["pfad"])
|
||||
eintrag["hat_planer"] = (wurzel / ".planer" / "kern.md").is_file()
|
||||
staende = {d: s for d, (s, _) in scan_dienst.einheiten_bestand(wurzel).items()}
|
||||
eintrag["drift"] = viewer.drift(wurzel, staende)["veraltet"]
|
||||
eintrag["letzter_scan_ts"] = await db.letzter_agent_ts(p["name"])
|
||||
lauf = scan_dienst.status(p["name"])
|
||||
eintrag["scan_laeuft"] = bool(lauf and lauf["laeuft"])
|
||||
out.append(eintrag)
|
||||
return out
|
||||
|
||||
|
||||
@router.get("/projekte/{name}")
|
||||
async def projekt(name: str):
|
||||
wurzel = _wurzel(name)
|
||||
daten = viewer.lade_projekt(wurzel)
|
||||
einheiten_kurz = {eid: {"beschreibung": e["beschreibung"]}
|
||||
for eid, e in daten["einheiten"].items()}
|
||||
return {
|
||||
"name": name,
|
||||
"kern": daten["kern"],
|
||||
"bereiche": daten["bereiche"],
|
||||
"architektur": daten["architektur"],
|
||||
"flows": daten["flows"],
|
||||
"pruefung": daten["pruefung"],
|
||||
"einheiten": einheiten_kurz,
|
||||
"doku_ordnung": viewer.doku_ordnung(daten),
|
||||
"drift": viewer.drift(wurzel, daten["staende"]),
|
||||
}
|
||||
|
||||
|
||||
@router.get("/projekte/{name}/einheit")
|
||||
async def einheit(name: str, id: str):
|
||||
wurzel = _wurzel(name)
|
||||
daten = viewer.lade_projekt(wurzel)
|
||||
e = daten["einheiten"].get(id)
|
||||
if e is None:
|
||||
raise HTTPException(404, f"Einheit '{id}' unbekannt")
|
||||
quelldatei = id.partition("::")[0]
|
||||
veraltet = quelldatei in viewer.drift(wurzel, daten["staende"])["veraltet"]
|
||||
code = viewer.code_extrahieren(wurzel, id)
|
||||
for anker in e["anker"]:
|
||||
zusatz = viewer.code_extrahieren(wurzel, anker)
|
||||
if zusatz and zusatz not in code:
|
||||
code += ("\n\n" if code else "") + zusatz
|
||||
return {**e, "code": code, "veraltet": veraltet}
|
||||
|
||||
|
||||
@router.post("/projekte/{name}/scan")
|
||||
async def scan_starten(name: str, body: dict):
|
||||
wurzel = _wurzel(name)
|
||||
art = body.get("art", "scan")
|
||||
if art not in ("scan", "rescan"):
|
||||
raise HTTPException(400, f"unbekannte Art '{art}'")
|
||||
try:
|
||||
status = scan_dienst.starte(name, wurzel, art)
|
||||
except scan_dienst.VorflugFehler as e:
|
||||
raise HTTPException(409, str(e))
|
||||
return {"status": status}
|
||||
|
||||
|
||||
@router.get("/projekte/{name}/scan-status")
|
||||
async def scan_status(name: str):
|
||||
_wurzel(name)
|
||||
lauf = scan_dienst.status(name)
|
||||
if lauf is None:
|
||||
return {"laeuft": False, "art": None, "ergebnis": None, "stufen": {}, "agenten": [], "dead": []}
|
||||
out = dict(lauf)
|
||||
if lauf["laeuft"]:
|
||||
out["stufen"] = (await db.kanban_stage_counts(name)).get("scan", {})
|
||||
out["agenten"] = agents.active_agents(f"scan-{name}-")
|
||||
out["dead"] = [c["card_id"] for c in await db.kanban_dead(name)]
|
||||
else:
|
||||
out["stufen"] = {}
|
||||
out["agenten"] = []
|
||||
out["dead"] = (lauf["ergebnis"] or {}).get("dead", [])
|
||||
return out
|
||||
Reference in New Issue
Block a user