6d5b09a592
Das Auftragsbuch-Gegenstueck fuer Lucy (Abloesungs-Paket S3, PC-Annahme-Weg): - backend/services/auftragsbuch.py: Multi-Repo (mc2 + lucy via ~/lucy-Clone). Karten tragen repo-Feld; Status-Schluessel fuer Lucy = 'lucy:<branch>'; fehlt ~/lucy, werden Lucy-Karten still weggelassen. Runner je Repo. - deploy/lucy-annahme.sh: detached Annahme-Runner fuer Lucy-Karten. Vorpruefung am PC VOR dem Merge (Executor erreichbar, Arbeitskopie main+clean, laeuft Lucy?), dann Merge im isolierten Worktree von ~/lucy -> Push main -> PC zieht ff-only und baut detached (deploy/lucy-annahme.ps1 im Lucy-Repo), Box pollt .lucy-annahme.json und spiegelt Fortschritt auf die Karte. Rot = Merge automatisch revertiert, laufende Lucy bleibt die alte. Executor-Zugang (URL+Token) kommt aus ~/.hermes/config.yaml — kein zweiter Ablageort. Neustart nur, wenn Lucy vorher lief (User-Entscheid). - Router/UI: repo-Parameter (rueckwaertskompatibel, Default mc2), rosa Lucy-Badge, eigener Annahme-Confirm-Text, Diff/Ablehnen je Repo. - werkstatt-SOUL: Lucy-Auftraege ebenfalls propose-only, bauen macht der PC bei der Annahme. - Doku: docs/AUFTRAGSBUCH.md (Lucy-Annahme-Kapitel), docs/wissen/OFFENE-FAEDEN (S2 erledigt, S3-Stand). Geprueft: py_compile gruen, bash -n gruen, tsc+vite build gruen (dist dabei).
64 lines
1.8 KiB
Python
64 lines
1.8 KiB
Python
"""Auftragsbuch-Endpoints (Vorschlags-Inbox) — dünner REST-Layer über services/auftragsbuch.py.
|
|
LAN-only wie alle MC2-Endpoints; das Gate ist der Klick des Commanders."""
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from pydantic import BaseModel
|
|
|
|
from services import auftragsbuch
|
|
|
|
router = APIRouter(prefix="/api")
|
|
|
|
|
|
class BranchIn(BaseModel):
|
|
branch: str
|
|
repo: str = "mc2" # "mc2" (Box-Stack) oder "lucy" (Desktop-App, Annahme baut am PC)
|
|
|
|
|
|
class KandidatIn(BaseModel):
|
|
file: str
|
|
|
|
|
|
@router.get("/auftragsbuch")
|
|
def list_proposals() -> dict:
|
|
return auftragsbuch.list_proposals()
|
|
|
|
|
|
@router.get("/auftragsbuch/diff")
|
|
def diff(branch: str, repo: str = "mc2") -> dict:
|
|
res = auftragsbuch.diff_of(branch, repo)
|
|
if not res.get("ok"):
|
|
raise HTTPException(400, res.get("error", "Diff nicht verfügbar."))
|
|
return res
|
|
|
|
|
|
@router.post("/auftragsbuch/annehmen")
|
|
def accept(body: BranchIn) -> dict:
|
|
res = auftragsbuch.accept(body.branch, body.repo)
|
|
if not res.get("ok"):
|
|
raise HTTPException(400, res.get("error", "Annehmen fehlgeschlagen."))
|
|
return res
|
|
|
|
|
|
@router.post("/auftragsbuch/ablehnen")
|
|
def reject(body: BranchIn) -> dict:
|
|
res = auftragsbuch.reject(body.branch, body.repo)
|
|
if not res.get("ok"):
|
|
raise HTTPException(400, res.get("error", "Ablehnen fehlgeschlagen."))
|
|
return res
|
|
|
|
|
|
@router.post("/auftragsbuch/skill/annehmen")
|
|
def skill_accept(body: KandidatIn) -> dict:
|
|
res = auftragsbuch.skill_accept(body.file)
|
|
if not res.get("ok"):
|
|
raise HTTPException(400, res.get("error", "Beauftragen fehlgeschlagen."))
|
|
return res
|
|
|
|
|
|
@router.post("/auftragsbuch/skill/ablehnen")
|
|
def skill_reject(body: KandidatIn) -> dict:
|
|
res = auftragsbuch.skill_reject(body.file)
|
|
if not res.get("ok"):
|
|
raise HTTPException(400, res.get("error", "Verwerfen fehlgeschlagen."))
|
|
return res
|