2026-06-14 06:44:12 +02:00
|
|
|
# Progressionsgraph — Slot-Editor (Phase B + F15)
|
2026-06-10 13:05:49 +02:00
|
|
|
|
2026-06-14 06:44:12 +02:00
|
|
|
**Stand:** 2026-05-22 · **Status:** Umgesetzt (F14 + F15 lokal nach 0.8.233)
|
2026-06-10 13:05:49 +02:00
|
|
|
|
|
|
|
|
## Ziel
|
|
|
|
|
|
|
|
|
|
Ein Progressionsgraph = **ein linearer Hauptpfad** (Roadmap = strukturgebend). Jeder **Major Step** ist ein **Slot** mit:
|
|
|
|
|
|
|
|
|
|
- **primary** — Hauptübung des Slots (Pfadknoten)
|
|
|
|
|
- **siblings** — 0..n Schwestern (gleiche Stufe, `edge_type: sibling`)
|
|
|
|
|
|
|
|
|
|
KI-Entwürfe und Bibliotheksübungen leben **im selben Slot-Modell**, ohne sofortige Übungsanlage.
|
|
|
|
|
|
|
|
|
|
## Slot-Zustände (`kind`)
|
|
|
|
|
|
|
|
|
|
| kind | Bedeutung |
|
|
|
|
|
|------|-----------|
|
|
|
|
|
| `empty` | Noch keine Übung |
|
|
|
|
|
| `library` | `exercise_id` (+ optional `variant_id`) |
|
|
|
|
|
| `proposal` | KI-Entwurf (`ai_suggestion`, kein `exercise_id`) |
|
|
|
|
|
|
|
|
|
|
## Kanten
|
|
|
|
|
|
|
|
|
|
- `primary(n) → primary(n+1)` — `next_exercise` (nur befüllte Primärkette, lückenlos verbunden)
|
|
|
|
|
- `primary ↔ sibling` — `sibling` (pro Slot)
|
|
|
|
|
|
|
|
|
|
Leere Slots in der Roadmap sind erlaubt; Kanten nur zwischen aufeinanderfolgenden befüllten Primär-Slots.
|
|
|
|
|
|
|
|
|
|
## Editor-Zustand (`ProgressionGraphDraft`)
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
{
|
|
|
|
|
goalQuery, startSituation, targetState, roadmapNotes, maxSteps,
|
|
|
|
|
majorSteps: MajorStep[],
|
|
|
|
|
slots: Slot[], // index = major_step_index
|
|
|
|
|
pathSkillExpectations?,
|
|
|
|
|
lastFindings?, // path_qa-Snapshot
|
2026-06-14 06:44:12 +02:00
|
|
|
findingsStale?: boolean, // Bewertung veraltet (↔ Artefakt findings_stale)
|
2026-06-10 13:05:49 +02:00
|
|
|
dirty: boolean,
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Hydration:** `planning_roadmap` + Kanten → Slots; `slot_contents[]` für Entwürfe; Primärkette aus `next_exercise`.
|
|
|
|
|
|
2026-06-14 06:44:12 +02:00
|
|
|
**Speichern:** Batch-Delete bestehender Pfad-/Schwester-Kanten → `edges/sequence` (Primärkette) → einzelne `sibling`-Kanten → `PUT`/`sequence` mit Artefakt inkl. `slot_contents`, `last_findings`, **`findings_stale`**.
|
2026-06-10 13:05:49 +02:00
|
|
|
|
|
|
|
|
## Findings-Panel
|
|
|
|
|
|
2026-06-14 06:44:12 +02:00
|
|
|
Nutzt `path_qa`:
|
|
|
|
|
|
|
|
|
|
| Feld | Bedeutung |
|
|
|
|
|
|------|-----------|
|
|
|
|
|
| `quality_score` | Gesamt = **min(`roadmap_qa`, `assignment_qa`)** |
|
|
|
|
|
| `roadmap_qa` | Stufen/Roadmap (LLM `topic_coverage`, …) |
|
|
|
|
|
| `assignment_qa` | Slot-Befüllung (`empty_slot_count`, …) |
|
|
|
|
|
| `overall_ok`, `issues`, `recommendations`, `gap_fill_offers`, … | wie bisher |
|
2026-06-10 13:05:49 +02:00
|
|
|
|
|
|
|
|
**API:** `POST /api/planning/progression-path-suggest` mit `evaluate_only: true` und `evaluate_steps[]` — QA ohne Re-Match.
|
|
|
|
|
|
2026-06-14 06:44:12 +02:00
|
|
|
**Bewertung veraltet:** Jede Graph-Änderung setzt `findingsStale: true` → Banner im Panel. Nach „Graph bewerten“ → `false`. Persistenz: `planning_roadmap.findings_stale`.
|
|
|
|
|
|
|
|
|
|
## Match-Flow („Übungen matchen“)
|
|
|
|
|
|
|
|
|
|
1. **Schritt 1:** `evaluate_only` + volle Pfad-QS (wie „Graph bewerten“)
|
|
|
|
|
2. **Schritt 2:** `unified_slot_review: true` → **`ProgressionOptimizeCompareModal`**
|
|
|
|
|
3. Pro Slot: aktuell vs. beste Bibliothek vs. optional KI-Vorschlag
|
|
|
|
|
4. **Vorauswahl:** Bibliothek nur wenn Stufen-Fit ≥ 50 % und besser als Baseline; sonst KI (bei leerem/schwachem Slot)
|
|
|
|
|
5. **Übernahme:** nur gewählte Slots speichern — **keine** automatische Nach-Bewertung
|
2026-06-10 13:05:49 +02:00
|
|
|
|
|
|
|
|
## Artefakt-Erweiterung (`GraphPlanningRoadmapArtifact`)
|
|
|
|
|
|
2026-06-14 06:44:12 +02:00
|
|
|
Optional:
|
2026-06-10 13:05:49 +02:00
|
|
|
|
|
|
|
|
- `slot_contents[]` — `{ major_step_index, primary, siblings[] }`
|
|
|
|
|
- `last_findings` — letzter `path_qa`-Snapshot
|
2026-06-14 06:44:12 +02:00
|
|
|
- **`findings_stale`** — bool, Bewertung bezieht sich nicht mehr auf aktuellen Graph-Stand
|
2026-06-10 13:05:49 +02:00
|
|
|
|
2026-06-10 15:42:29 +02:00
|
|
|
## UI (konsolidiert)
|
2026-06-10 13:05:49 +02:00
|
|
|
|
2026-06-10 15:42:29 +02:00
|
|
|
- **Eine Oberfläche:** `ExerciseProgressionGraphPanel` embeddet `ProgressionGraphEditor` (Slots + Findings)
|
|
|
|
|
- Kein separater Slot-Editor, kein 4-Schritt-KI-Wizard, kein `ProgressionChainEditor` im Panel
|
|
|
|
|
- Route `/progression-graphs/:id` → Redirect nach `/exercises` (Deep-Link wählt Graph)
|
2026-06-14 06:44:12 +02:00
|
|
|
- **Slot-Keys:** stabil `slot-{index}` (nicht Lernziel-Text) — sonst Fokusverlust beim Tippen
|
2026-06-10 13:05:49 +02:00
|
|
|
|
2026-06-10 15:42:29 +02:00
|
|
|
## Ersetzt (Legacy, nicht mehr im Panel)
|
2026-06-10 13:05:49 +02:00
|
|
|
|
2026-06-10 15:42:29 +02:00
|
|
|
- `ExerciseProgressionPathBuilder` · `ProgressionChainEditor` — Code bleibt vorerst, nicht eingebunden
|
2026-06-10 13:05:49 +02:00
|
|
|
|
|
|
|
|
## Implementierungsreihenfolge
|
|
|
|
|
|
2026-06-14 06:44:12 +02:00
|
|
|
| ID | Inhalt | Status |
|
|
|
|
|
|----|--------|--------|
|
|
|
|
|
| B.0 | Draft + Laden/Speichern Slots ↔ Kanten | ✅ |
|
|
|
|
|
| B.1 | Slot-Karten, Bibliothek + Entwurf | ✅ |
|
|
|
|
|
| B.2 | Findings-Panel + `evaluate_only` | ✅ |
|
|
|
|
|
| B.3 | Entwürfe im Artefakt + „Übung anlegen“ | ✅ |
|
|
|
|
|
| B.4 | Route + Panel vereinfachen | ✅ |
|
|
|
|
|
| B.5 | `last_findings` + Phase-C-Vorbereitung | ✅ |
|
|
|
|
|
| F15 | Unified Slot-Review, getrennte QS, `findings_stale` | ✅ |
|
|
|
|
|
|
|
|
|
|
**Ist-Doku:** `docs/architecture/PLANNING_PROGRESSION_GRAPH_KI.md` §8.1 · `docs/HANDOVER.md` §2.8 F15
|