Files
mission-control-v2/backend/routers/ideen.py
T
Hitonabi 3cdd5cdd10 Auftragsbuch: Konzepte sichtbar, Modi unterscheidbar, Ideen weiterfuehrbar
Drei Luecken, die die neue Idee-Bahn unbrauchbar machten (User-Fund 21.07.):

1. Konzept unsichtbar. Der projektstart-Worker folgte dem Ende des
   konzept-fliessband-Skills (Kopie nach ~/konzepte + Telegram) statt seiner
   SOUL (Repo + KONZEPT.md) und schloss die Karte ab. Die Konzept-Ansicht sucht
   nur in Gitea -> "noch kein Repo hinterlegt", obwohl das Konzept fertig war
   (zweimal passiert: arm-ui, pomodoro-timer). konzept_of() faellt jetzt auf
   ~/konzepte/*.md zurueck (Pfad aus der Abschlussmeldung, sonst ueber den Titel
   geraten; streng auf dieses Verzeichnis begrenzt) und nennt die Quelle.
   Zusaetzlich sagen SOUL und Skill jetzt ausdruecklich, dass die Skill-Ablage
   fuer Kanban-Worker NICHT das Ende ist.

2. Modus nicht erkennbar. Idee und IDE-Projekt trugen dasselbe "IDE"-Abzeichen,
   Box-Karten gar keins. list_queue() liefert jetzt `art` (aus dem Body-Marker
   AUFTRAGS-ART: IDEE PRUEFEN), die UI zeigt BOX / IDEE / IDE mit Erklaerung —
   plus eine immer sichtbare Zeile, wann man welchen Modus nimmt.

3. Idee war eine Sackgasse. Neu: POST /api/ideen/weiterfuehren legt aus einer
   fertig durchdachten Idee eine IDE-Projekt-Karte an — verkettet an die Idee,
   mit dem fertigen Konzept als Vorlage ("denk es NICHT neu"), Titel aus der
   Konzept-Ueberschrift statt aus dem Rohtext. Liegt das Konzept schon in einem
   Repo, wird genau dieses weitergenutzt statt ein zweites anzulegen.
   In der UI sitzt der Knopf unter dem gelesenen Konzept (Ziel + Aufwand).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 08:40:16 +02:00

117 lines
3.3 KiB
Python

"""Ideen-Queue-Endpoints — dünner REST-Layer über services/ideen.py (natives Hermes-Kanban).
LAN-only wie alle MC2-Endpoints; das Mensch-Gate bleibt die Karte im Auftragsbuch."""
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from services import ideen
router = APIRouter(prefix="/api")
class IdeeIn(BaseModel):
titel: str
notiz: str = ""
welt: str = "box" # "box" = Werkstatt baut · "ide" = vorbereiten für Zed
tiefe: str = "" # nur ide: "simpel" | "gruendlich" (leer = Box schätzt selbst)
ziel: str = "" # nur ide-Projekt: "lxc" | "docker" (leer = Box entscheidet)
art: str = "projekt" # nur ide: "projekt" (Repo+Roadmap+Bau) | "idee" (nur durchdenken)
class TaskIn(BaseModel):
id: str
class AntwortIn(BaseModel):
id: str
antwort: str
@router.get("/ideen")
def list_queue() -> dict:
return ideen.list_queue()
@router.post("/ideen")
def add_idea(body: IdeeIn) -> dict:
res = ideen.add_idea(body.titel, body.notiz, welt=body.welt, tiefe=body.tiefe,
ziel=body.ziel, art=body.art)
if not res.get("ok"):
raise HTTPException(400, res.get("error", "Idee konnte nicht angelegt werden."))
return res
@router.post("/ideen/antwort")
def answer(body: AntwortIn) -> dict:
res = ideen.answer_task(body.id, body.antwort)
if not res.get("ok"):
raise HTTPException(400, res.get("error", "Antwort konnte nicht gesendet werden."))
return res
class PrioIn(BaseModel):
id: str
richtung: str # hoch | runter
@router.post("/ideen/stopp")
def stop(body: TaskIn) -> dict:
res = ideen.stop_task(body.id)
if not res.get("ok"):
raise HTTPException(400, res.get("error", "Stoppen fehlgeschlagen."))
return res
@router.post("/ideen/retry")
def retry(body: TaskIn) -> dict:
res = ideen.retry_task(body.id)
if not res.get("ok"):
raise HTTPException(400, res.get("error", "Neuer Versuch fehlgeschlagen."))
return res
@router.post("/ideen/prio")
def prio(body: PrioIn) -> dict:
res = ideen.prio_task(body.id, body.richtung)
if not res.get("ok"):
raise HTTPException(400, res.get("error", "Prio-Änderung fehlgeschlagen."))
return res
class WeiterIn(BaseModel):
id: str
ziel: str = "" # "lxc" | "docker" (leer = Box entscheidet)
tiefe: str = "" # "simpel" | "gruendlich" (leer = Box schätzt selbst)
@router.post("/ideen/weiterfuehren")
def weiterfuehren(body: WeiterIn) -> dict:
"""„Konzept gefällt mir" → IDE-Projekt-Karte mit dem fertigen Konzept als Vorlage."""
res = ideen.projekt_aus_idee(body.id, ziel=body.ziel, tiefe=body.tiefe)
if not res.get("ok"):
raise HTTPException(400, res.get("error", "Projekt konnte nicht angelegt werden."))
return res
@router.post("/ideen/archivieren")
def archive(body: TaskIn) -> dict:
res = ideen.archive_task(body.id)
if not res.get("ok"):
raise HTTPException(400, res.get("error", "Archivieren fehlgeschlagen."))
return res
@router.get("/ideen/{id}/log")
def get_log(id: str) -> dict:
return ideen.log_of(id)
@router.get("/ideen/{id}/ergebnis")
def get_ergebnis(id: str) -> dict:
return ideen.ergebnis_of(id)
@router.get("/ideen/{id}/konzept")
def get_konzept(id: str) -> dict:
return ideen.konzept_of(id)