refactor: Umsetzungsbewertung hängt an Kette statt Vorlage
- Neues Feld kette_id in ki_bewertungen für umsetzung_match - 3.757 bestehende Bewertungen migriert - API: Neueste Version + ältere Versionen getrennt im Response - Explorer: Umsetzungsgrad in Panel 2 (Kette), nicht mehr in Panel 3 (Vorlage) - 'Vorherige Bewertungen' Button aufklappbar mit Score + Begründung + Zeitstempel
This commit is contained in:
parent
c5939a6873
commit
e35dab8f7d
@ -124,6 +124,7 @@ class KetteDetail(BaseModel):
|
||||
strang: str | None = None
|
||||
ampel: dict | None = None
|
||||
umsetzung: dict | None = None
|
||||
umsetzung_versionen: list[dict] | None = None
|
||||
|
||||
|
||||
class PaginatedVorlagen(BaseModel):
|
||||
|
||||
@ -273,12 +273,13 @@ def _run_ketten_bewertung(kette_id: int, anmerkung: str, job_id: str):
|
||||
_jobs[job_id] = {"status": "error", "error": str(result)}
|
||||
return
|
||||
|
||||
# Keep old versions, insert new
|
||||
# Keep old versions, insert new (linked to kette, not vorlage)
|
||||
conn.execute(
|
||||
"""INSERT INTO ki_bewertungen (vorlage_id, typ, score, begruendung, anmerkungen, modell, prompt_version, erstellt_at)
|
||||
VALUES (?, 'umsetzung_match', ?, ?, ?, 'qwen-plus-latest', 'v2-reeval', ?)""",
|
||||
"""INSERT INTO ki_bewertungen (vorlage_id, kette_id, typ, score, begruendung, anmerkungen, modell, prompt_version, erstellt_at)
|
||||
VALUES (?, ?, 'umsetzung_match', ?, ?, ?, 'qwen-plus-latest', 'v2-reeval', ?)""",
|
||||
(
|
||||
kette["ursprung_id"],
|
||||
kette_id,
|
||||
result.get("score"),
|
||||
result.get("begruendung"),
|
||||
json.dumps(result, ensure_ascii=False),
|
||||
|
||||
@ -191,32 +191,37 @@ 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)
|
||||
# Umsetzungsbewertung (alle Versionen für diese Kette, neueste zuerst)
|
||||
umsetzung = None
|
||||
if row["ursprung_id"]:
|
||||
ub_row = conn.execute(
|
||||
umsetzung_versionen = []
|
||||
import json as _json
|
||||
ub_rows = 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
|
||||
WHERE kette_id = ? AND typ = 'umsetzung_match'
|
||||
ORDER BY id DESC""",
|
||||
(kette_id,),
|
||||
).fetchall()
|
||||
for i, ub_row in enumerate(ub_rows):
|
||||
details = {}
|
||||
if ub_row["anmerkungen"]:
|
||||
try:
|
||||
details = _json.loads(ub_row["anmerkungen"])
|
||||
except Exception:
|
||||
pass
|
||||
umsetzung = {
|
||||
entry = {
|
||||
"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"],
|
||||
"prompt_version": ub_row["prompt_version"],
|
||||
}
|
||||
if i == 0:
|
||||
umsetzung = entry
|
||||
else:
|
||||
umsetzung_versionen.append(entry)
|
||||
|
||||
strang = row["strang"]
|
||||
ampel_data = get_ampel(strang or "", row["status"] or "")
|
||||
@ -244,4 +249,5 @@ def get_kette(kette_id: int, conn=Depends(_db)):
|
||||
strang=strang,
|
||||
ampel=ampel_data,
|
||||
umsetzung=umsetzung,
|
||||
umsetzung_versionen=umsetzung_versionen if umsetzung_versionen else None,
|
||||
)
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
let mobileTab = $state<'liste' | 'kette' | 'detail'>('liste');
|
||||
let showVolltext = $state(false);
|
||||
let showVersionen = $state(false);
|
||||
let showUmsetzungVersionen = $state(false);
|
||||
let showReeval = $state(false);
|
||||
let reevalAnmerkung = $state('');
|
||||
let reevalStatus = $state<'idle' | 'running' | 'done' | 'error'>('idle');
|
||||
@ -364,6 +365,28 @@
|
||||
{#if u.details}
|
||||
<p class="text-[10px] text-gray-500 mt-1 leading-snug">{u.details}</p>
|
||||
{/if}
|
||||
{#if selectedKette.umsetzung_versionen?.length}
|
||||
<button onclick={() => showUmsetzungVersionen = !showUmsetzungVersionen}
|
||||
class="text-[10px] text-gray-400 hover:text-gray-600 mt-2 flex items-center gap-1">
|
||||
<span>{showUmsetzungVersionen ? '▼' : '▶'}</span>
|
||||
{selectedKette.umsetzung_versionen.length} vorherige Bewertung{selectedKette.umsetzung_versionen.length > 1 ? 'en' : ''}
|
||||
</button>
|
||||
{#if showUmsetzungVersionen}
|
||||
<div class="mt-2 space-y-2">
|
||||
{#each selectedKette.umsetzung_versionen as v}
|
||||
<div class="rounded border border-gray-200 bg-gray-50 p-2">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<span class="text-[10px] font-bold {v.score >= 0.7 ? 'text-green-700' : v.score >= 0.4 ? 'text-amber-700' : 'text-red-700'}">
|
||||
{Math.round((v.score || 0) * 100)}%
|
||||
</span>
|
||||
<span class="text-[10px] text-gray-400">{v.erstellt_at || ''}</span>
|
||||
</div>
|
||||
<p class="text-[10px] text-gray-500">{v.begruendung}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@ -529,28 +552,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Umsetzungsbewertung -->
|
||||
{#if selectedVorlage.umsetzungsbewertungen?.length}
|
||||
<div class="rounded-xl border border-gray-200 p-5">
|
||||
<h3 class="text-sm font-semibold text-gray-900 mb-3">📊 Umsetzungsbewertung</h3>
|
||||
{#each selectedVorlage.umsetzungsbewertungen as ub}
|
||||
<div class="p-3 rounded-lg border {ub.score >= 0.7 ? 'border-green-200 bg-green-50' : ub.score >= 0.4 ? 'border-amber-200 bg-amber-50' : 'border-red-200 bg-red-50'}">
|
||||
<div class="flex items-center gap-3 mb-1.5">
|
||||
<div class="w-10 h-10 rounded-full flex items-center justify-center text-sm font-bold
|
||||
{ub.score >= 0.7 ? 'bg-green-200 text-green-800' : ub.score >= 0.4 ? 'bg-amber-200 text-amber-800' : 'bg-red-200 text-red-800'}">
|
||||
{Math.round((ub.score || 0) * 100)}%
|
||||
</div>
|
||||
<span class="text-sm font-medium {ub.score >= 0.7 ? 'text-green-800' : ub.score >= 0.4 ? 'text-amber-800' : 'text-red-800'}">
|
||||
{ub.score >= 0.7 ? 'Weitgehend umgesetzt' : ub.score >= 0.4 ? 'Teilweise umgesetzt' : 'Kaum umgesetzt'}
|
||||
</span>
|
||||
</div>
|
||||
{#if ub.begruendung}
|
||||
<p class="text-xs text-gray-700">{ub.begruendung}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
<!-- Umsetzungsbewertung → jetzt in der Ketten-Ansicht (Panel 2) -->
|
||||
|
||||
<!-- Neu bewerten -->
|
||||
<div class="rounded-xl border border-gray-200 p-4">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user