diff --git a/backend/src/tracker/api/models.py b/backend/src/tracker/api/models.py index 550a76f..e11054e 100644 --- a/backend/src/tracker/api/models.py +++ b/backend/src/tracker/api/models.py @@ -85,6 +85,7 @@ class VorlageDetail(BaseModel): kette_id: int | None = None umsetzungsbewertungen: list[UmsetzungsBewertung] = [] ampel: dict | None = None + ki_versionen: list[dict] | None = None class KettenGliedOut(BaseModel): diff --git a/backend/src/tracker/api/routes/bewertung.py b/backend/src/tracker/api/routes/bewertung.py index 4504722..8948747 100644 --- a/backend/src/tracker/api/routes/bewertung.py +++ b/backend/src/tracker/api/routes/bewertung.py @@ -162,12 +162,12 @@ def _run_zusammenfassung(vorlage_id: int, anmerkung: str, job_id: str): _jobs[job_id] = {"status": "error", "error": str(result)} return - # Delete old, insert new - conn.execute("DELETE FROM ki_bewertungen WHERE vorlage_id = ? AND typ = 'zusammenfassung'", (vorlage_id,)) + # Keep old versions, insert new conn.execute( - """INSERT INTO ki_bewertungen (vorlage_id, typ, begruendung, anmerkungen, modell, prompt_version) - VALUES (?, 'zusammenfassung', ?, ?, 'qwen-plus-latest', 'v2-reeval')""", - (vorlage_id, result.get("zusammenfassung"), json.dumps(result, ensure_ascii=False)), + """INSERT INTO ki_bewertungen (vorlage_id, typ, begruendung, anmerkungen, modell, prompt_version, erstellt_at) + VALUES (?, 'zusammenfassung', ?, ?, 'qwen-plus-latest', 'v2-reeval', ?)""", + (vorlage_id, result.get("zusammenfassung"), json.dumps(result, ensure_ascii=False), + datetime.now().isoformat()), ) if result.get("kernforderung"): conn.execute("UPDATE vorlagen SET thema_kurz = ? WHERE id = ?", (result["kernforderung"][:200], vorlage_id)) @@ -249,19 +249,16 @@ def _run_ketten_bewertung(kette_id: int, anmerkung: str, job_id: str): _jobs[job_id] = {"status": "error", "error": str(result)} return - # Delete old umsetzung_match, insert new + # Keep old versions, insert new conn.execute( - "DELETE FROM ki_bewertungen WHERE vorlage_id = ? AND typ = 'umsetzung_match'", - (kette["ursprung_id"],), - ) - conn.execute( - """INSERT INTO ki_bewertungen (vorlage_id, typ, score, begruendung, anmerkungen, modell, prompt_version) - VALUES (?, 'umsetzung_match', ?, ?, ?, 'qwen-plus-latest', 'v2-reeval')""", + """INSERT INTO ki_bewertungen (vorlage_id, typ, score, begruendung, anmerkungen, modell, prompt_version, erstellt_at) + VALUES (?, 'umsetzung_match', ?, ?, ?, 'qwen-plus-latest', 'v2-reeval', ?)""", ( kette["ursprung_id"], result.get("score"), result.get("begruendung"), json.dumps(result, ensure_ascii=False), + datetime.now().isoformat(), ), ) diff --git a/backend/src/tracker/api/routes/vorlagen.py b/backend/src/tracker/api/routes/vorlagen.py index 092e598..3a3fa07 100644 --- a/backend/src/tracker/api/routes/vorlagen.py +++ b/backend/src/tracker/api/routes/vorlagen.py @@ -297,18 +297,30 @@ def get_vorlage(vorlage_id: int, conn=Depends(_db)): if kette_info and kette_info["strang"]: kette_ampel = get_ampel(kette_info["strang"], kette_info["status"] or "") - # KI-Zusammenfassung - ki_row = conn.execute( - "SELECT anmerkungen FROM ki_bewertungen WHERE vorlage_id = ? AND typ = 'zusammenfassung' LIMIT 1", + # KI-Zusammenfassung (alle Versionen, neueste zuerst) + ki_rows = conn.execute( + "SELECT anmerkungen, erstellt_at, prompt_version FROM ki_bewertungen WHERE vorlage_id = ? AND typ = 'zusammenfassung' ORDER BY id DESC", (vorlage_id,), - ).fetchone() + ).fetchall() ki_zusammenfassung = None - if ki_row and ki_row["anmerkungen"]: - try: - ki_data = json.loads(ki_row["anmerkungen"]) - ki_zusammenfassung = KiZusammenfassung(**ki_data) - except (json.JSONDecodeError, TypeError): - pass + ki_versionen = [] + for i, ki_row in enumerate(ki_rows): + if ki_row["anmerkungen"]: + try: + ki_data = json.loads(ki_row["anmerkungen"]) + if i == 0: + ki_zusammenfassung = KiZusammenfassung(**ki_data) + else: + ki_versionen.append({ + "zusammenfassung": ki_data.get("zusammenfassung", ""), + "kernforderung": ki_data.get("kernforderung", ""), + "begruendung": ki_data.get("begruendung", ""), + "thema": ki_data.get("thema", ""), + "erstellt_at": ki_row["erstellt_at"], + "prompt_version": ki_row["prompt_version"], + }) + except (json.JSONDecodeError, TypeError): + pass # Umsetzungsbewertungen from tracker.api.models import UmsetzungsBewertung @@ -351,4 +363,5 @@ def get_vorlage(vorlage_id: int, conn=Depends(_db)): ki_zusammenfassung=ki_zusammenfassung, umsetzungsbewertungen=umsetzungsbewertungen, ampel=kette_ampel, + ki_versionen=ki_versionen if ki_versionen else None, ) diff --git a/frontend/src/routes/explorer/+page.svelte b/frontend/src/routes/explorer/+page.svelte index f854f50..f84c3f6 100644 --- a/frontend/src/routes/explorer/+page.svelte +++ b/frontend/src/routes/explorer/+page.svelte @@ -30,6 +30,7 @@ // Mobile tab let mobileTab = $state<'liste' | 'kette' | 'detail'>('liste'); let showVolltext = $state(false); + let showVersionen = $state(false); const STRANG_TABS = [ { value: '', label: 'Alle' }, @@ -438,6 +439,33 @@ {/if} + + {#if selectedVorlage.ki_versionen?.length} +
{v.zusammenfassung}
+ {#if v.kernforderung} +Kernforderung: {v.kernforderung}
+ {/if} +{v.zusammenfassung}
+ {#if v.kernforderung} +Kernforderung: {v.kernforderung}
+ {/if} +