From 726f5c06ade7bd2d79e05ea42b5a38870bf22dd6 Mon Sep 17 00:00:00 2001 From: Dotty Dotter Date: Wed, 1 Apr 2026 23:23:25 +0200 Subject: [PATCH] feat: Umsetzungsgrad in Ketten-Detail anzeigen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Backend: KI-Umsetzungsbewertung (Score, Bewertung, Begründung, Kernpunkt, Details) im Ketten-Detail-Response - Frontend: Umsetzungsgrad zwischen Ampel und Timeline im Explorer Panel 2 - Prozent-Kreis (grün/amber/rot) + Bewertungstext + Kernpunkt-Status - Begründung + Details als Fließtext --- backend/src/tracker/api/models.py | 1 + backend/src/tracker/api/routes/ketten.py | 28 ++++++++++++++++++++++ frontend/src/routes/explorer/+page.svelte | 29 +++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/backend/src/tracker/api/models.py b/backend/src/tracker/api/models.py index e11054e..086b674 100644 --- a/backend/src/tracker/api/models.py +++ b/backend/src/tracker/api/models.py @@ -123,6 +123,7 @@ class KetteDetail(BaseModel): graph: dict | None = None strang: str | None = None ampel: dict | None = None + umsetzung: dict | None = None class PaginatedVorlagen(BaseModel): diff --git a/backend/src/tracker/api/routes/ketten.py b/backend/src/tracker/api/routes/ketten.py index 3393c87..8817c6d 100644 --- a/backend/src/tracker/api/routes/ketten.py +++ b/backend/src/tracker/api/routes/ketten.py @@ -191,6 +191,33 @@ def get_kette(kette_id: int, conn=Depends(_db)): # Graph/Perlenschnur data graph = get_kette_graph(conn, kette_id) + # Umsetzungsbewertung (neueste KI-Bewertung für Ursprungsvorlage) + umsetzung = None + if row["ursprung_id"]: + ub_row = conn.execute( + """SELECT score, begruendung, anmerkungen, erstellt_at, prompt_version + FROM ki_bewertungen + WHERE vorlage_id = ? AND typ = 'umsetzung_match' + ORDER BY id DESC LIMIT 1""", + (row["ursprung_id"],), + ).fetchone() + if ub_row: + import json as _json + details = {} + if ub_row["anmerkungen"]: + try: + details = _json.loads(ub_row["anmerkungen"]) + except Exception: + pass + umsetzung = { + "score": ub_row["score"], + "bewertung": details.get("bewertung", ""), + "begruendung": ub_row["begruendung"], + "kernpunkt_erfuellt": details.get("kernpunkt_erfuellt"), + "details": details.get("details", ""), + "erstellt_at": ub_row["erstellt_at"], + } + strang = row["strang"] ampel_data = get_ampel(strang or "", row["status"] or "") @@ -216,4 +243,5 @@ def get_kette(kette_id: int, conn=Depends(_db)): graph=graph, strang=strang, ampel=ampel_data, + umsetzung=umsetzung, ) diff --git a/frontend/src/routes/explorer/+page.svelte b/frontend/src/routes/explorer/+page.svelte index 0a0166c..e6b2ec3 100644 --- a/frontend/src/routes/explorer/+page.svelte +++ b/frontend/src/routes/explorer/+page.svelte @@ -338,6 +338,35 @@ {/if} + + {#if selectedKette.umsetzung} + {@const u = selectedKette.umsetzung} +
+
+
+ {Math.round((u.score || 0) * 100)}% +
+
+
+ {u.bewertung || (u.score >= 0.7 ? 'Umgesetzt' : u.score >= 0.4 ? 'Teilweise' : 'Kaum umgesetzt')} +
+ {#if u.kernpunkt_erfuellt !== null && u.kernpunkt_erfuellt !== undefined} +
+ Kernpunkt: {u.kernpunkt_erfuellt ? '✅ erfüllt' : '❌ nicht erfüllt'} +
+ {/if} +
+
+ {#if u.begruendung} +

{u.begruendung}

+ {/if} + {#if u.details} +

{u.details}

+ {/if} +
+ {/if} +
Ketten-Glieder