- buildAiPrompt (AssignmentFeedbackPage.tsx): 'na' wird jetzt korrekt aus dem Score-Mittelwert ausgeschlossen (war bislang als 0 mitgerechnet) - FeedbackDraftPage.tsx auf feedbackCriterionItems/feedbackCategories migriert, letzter Konsument der Legacy-Tabellen außer den Seeds. Notizen hängen jetzt korrekt pro Kriterium über lineTags, statt ungefiltert an jedes Kriterium. Score-Anzeige nutzt RATING_OPTIONS-Labels statt rohem /5-Wert. - FeedbackStructureConfig.tsx: verwaisten AssignmentType/PhaseTemplate-CRUD-Code entfernt (Funktionalität war bereits nach AssignmentTypeConfig.tsx verschoben) - Doku aktualisiert: CLAUDE.md, docs/HANDOVER.md, docs/STATUS_UND_OFFENE_PUNKTE.md, docs/TECHNISCHE_ARCHITEKTUR.md Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
119 lines
11 KiB
Markdown
119 lines
11 KiB
Markdown
# Projektstatus und offene Punkte — Assignment Monitor
|
||
|
||
Stand: 2026-07-03
|
||
|
||
---
|
||
|
||
## Implementierungsstatus
|
||
|
||
### ✅ Vollständig implementiert
|
||
|
||
| Feature | Seite / Datei |
|
||
|---|---|
|
||
| Dashboard: Assignment-Liste | `Dashboard.tsx` |
|
||
| Assignment anlegen (Typ, Institutees, Phasen-Preview) | `AssignmentCreate.tsx` |
|
||
| Assignment nachbearbeiten (Nummer, Typ-Wechsel-Warnung, Institutee-Laufzeiten) | `AssignmentEdit.tsx` |
|
||
| Phasen-Flow-Ansicht pro Assignment | `AssignmentDetail.tsx` |
|
||
| Soft-Delete + Papierkorb für Meetings | `AssignmentDetail.tsx` |
|
||
| Bewertungs-Chips je Institutee + Kategorie in der Übersicht | `AssignmentDetail.tsx` |
|
||
| Live-Gesprächsprotokoll mit Sprecher-Zeitlinie | `MeetingView.tsx` |
|
||
| Schnellnotation (+, !, >, […]) mit farbigem Rendering | `MeetingView.tsx`, `notationParser.tsx` |
|
||
| Äh-Counter pro Institutee (live + nachträgliche Anpassung) | `MeetingView.tsx` |
|
||
| Gesamtbewertung auf Kriterium-Ebene (Accordion, farbige Kategorie-Header) | `MeetingView.tsx` |
|
||
| Auto-Calc Bewertung aus Protokoll-Kategorie-Scores | `MeetingView.tsx` |
|
||
| Allgemeine Notizen mit Auto-Resize + Notation-Rendering | `MeetingView.tsx` |
|
||
| Meeting-Export: Markdown + JSON, strukturierter Dateiname | `meetingExport.ts` |
|
||
| Assignment-Nummer im Dateinamen | `MeetingView.tsx`, `AssignmentDetail.tsx` |
|
||
| Strukturiertes Abschluss-Feedback pro Institutee | `AssignmentFeedbackPage.tsx` |
|
||
| KI-Feedback-Generierung via OpenRouter | `AssignmentFeedbackPage.tsx` |
|
||
| Feedback-Status: Entwurf → Final | `AssignmentFeedbackPage.tsx` |
|
||
| Feedback-Dimensionsstruktur CRUD mit Gewichtung (0,0–2,0 in 0,1-Schritten) | `FeedbackStructureConfig.tsx` |
|
||
| AssignmentTyp CRUD mit Phasen-Templates | `AssignmentTypeConfig.tsx` |
|
||
| Kriterien-Auswahl je Typ (Baumstruktur, Indeterminate) | `AssignmentTypeConfig.tsx` |
|
||
| Kriterien-Filterung je Typ in Meetings + Übersicht | `MeetingView.tsx`, `AssignmentDetail.tsx` |
|
||
| Vollständiges DB-Backup (JSON Export/Import) | `dbBackup.ts`, `Configuration.tsx` |
|
||
| Berater/Gruppen-Verwaltung | `Consultants.tsx` |
|
||
| PWA (installierbar, Offline-fähig) | Vite-PWA-Plugin |
|
||
| Konfiguration zentralisiert (Farben, Ratings, AI-Settings) | `src/config/constants.ts` |
|
||
| `db/index.ts` in types/schema/seeds aufgeteilt (Re-Export bleibt kompatibel) | `src/db/` |
|
||
| `MeetingView.tsx` in 3 Dateien aufgeteilt | `src/pages/meeting/` |
|
||
| Auswertung auf `feedbackCriterionItems` migriert, nach Assignment gruppiert, Papierkorb/Status gefiltert, N/A-Bug gefixt | `Evaluation.tsx` |
|
||
| Zeitgewichteter Bewertungs-Vorschlag mit Trend-Erkennung (konfigurierbarer Gewichtungsfaktor, Vorschlags-Badge auf Feedback-Seite, Trend-Satz-Insertion, KI-Prompt-Erweiterung) | `Evaluation.tsx`, `AssignmentFeedbackPage.tsx`, `src/utils/ratingTrend.ts`, `RatingWeightConfig.tsx` |
|
||
| Kriterium-Zuordnung für Freitext-Notizen — pro Zeile innerhalb eines zusammenhängenden Sprecher-Blocks (`ConversationEntry.lineTags`, Matching per Zeilentext), Chip+Popover mit Suche direkt an der Zeile, nachträglich im Protokoll; `buildAiPrompt` führt Assessment- und Konversations-Notizen pro Kriterium zusammen | `ConversationTab.tsx`, `CriterionTagPicker.tsx`, `notationParser.tsx`, `MeetingView.tsx`, `AssignmentFeedbackPage.tsx` |
|
||
| Notation → Bewertungs-Vorschlag in der Gesamtbewertung: `!`/`(!)`/`(+)`/`+` an getaggten Zeilen ergeben einen Rating-Vorschlag je Kriterium ("Vorschlag aus Protokoll" + Übernehmen), plus Kategorie-Kopfzeile zeigt Anzahl offener Vorschläge (💡 N) auch zugeklappt | `AssessmentTab.tsx`, `notationParser.tsx` (`detectNotationRating`) |
|
||
| Meeting-Export (Markdown) zeigt Kriterium-Namen korrekt (`db.criteria`-Legacy-Bug gefixt) + Kriterium pro getaggter Zeile; Voll-Backup deckt wieder alle Tabellen ab (`appSettings` ergänzt) | `meetingExport.ts`, `dbBackup.ts` |
|
||
| Assignment-Nummer ist Pflichtfeld beim Anlegen | `AssignmentCreate.tsx` |
|
||
| Kriterium-Gewichtung feiner (0,0–2,0 in 0,1-Schritten statt `×1`–`×5`), inkl. Division-durch-Null-Fix bei Gewicht 0 in allen gewichteten Mittelwerten | `FeedbackStructureConfig.tsx`, `AssessmentTab.tsx`, `ratingTrend.ts` |
|
||
| Sprecher eines Protokoll-Beitrags nachträglich änderbar (im Bearbeiten-Modus) | `ConversationTab.tsx`, `MeetingView.tsx` |
|
||
| N/A-Aggregationsbug in `buildAiPrompt` gefixt (letzte offene Stelle außer Legacy-Code) | `AssignmentFeedbackPage.tsx` |
|
||
| `FeedbackDraftPage.tsx` auf `feedbackCriterionItems`/`feedbackCategories` migriert, Notizen korrekt pro Kriterium über `lineTags` (nicht mehr alle Protokoll-Notizen an jedes Kriterium), Score-Anzeige auf `RATING_OPTIONS`-Labels | `FeedbackDraftPage.tsx` |
|
||
| Toter Code (verwaiste AssignmentType/PhaseTemplate-CRUD-Reste) entfernt | `FeedbackStructureConfig.tsx` |
|
||
|
||
---
|
||
|
||
## ⚠️ Offene Punkte / Bugs
|
||
|
||
### Priorität Hoch
|
||
|
||
| # | Beschreibung | Datei | Aufwand |
|
||
|---|---|---|---|
|
||
| H1 | **IndexedDB-Robustheit**: Browser kann IndexedDB unter Speicherdruck löschen. Migration zu SQLite WASM + OPFS geplant. Bis dahin: regelmäßige Backups als einzige Sicherheit. | `db/schema.ts` | L (Wochen) |
|
||
| H2 | **Backup-Reminder fehlt**: Es gibt keine automatische Erinnerung / keinen Hinweis nach abgeschlossenem Meeting, dass ein Backup erstellt werden sollte. | `pages/meeting/MeetingView.tsx` | S |
|
||
| H6 | **KI-Generierung funktionsunfähig**: `generateWithAi()` schlägt beim Ausführen fehl, vermutlich Capgemini-Netzwerk/Firewall blockiert den Call zu `openrouter.ai`. Root Cause noch nicht untersucht. | `AssignmentFeedbackPage.tsx` | ? |
|
||
| H7 | **Prompt-System-Neubau (noch nicht gescoped)**: Mehrstufiges, pro Dimension konfigurierbares Prompt-System mit Spezialwissen je Dimension + Platzhaltersystem, löst den aktuellen Einzel-Prompt in `buildAiPrompt` ab. Braucht eigene Design-Session. | `AssignmentFeedbackPage.tsx` | L |
|
||
|
||
### Priorität Mittel
|
||
|
||
| # | Beschreibung | Datei | Aufwand |
|
||
|---|---|---|---|
|
||
| M5 | **`db/queries/`-Layer fehlt**: DB-Zugriffe direkt aus Komponenten (`db.*`), keine Abstraktionsschicht. Erschwert die geplante SQLite-Migration (H1). | `src/db/queries/` (neu) | M |
|
||
| M6 | **Selbstlernendes Tagging (Idee, noch nicht gescoped)**: Zeile-zu-Kriterium-Zuordnungen sammeln und daraus beim Tippen automatische Tag-Vorschläge ableiten. Braucht eigene Design-Session. | `CriterionTagPicker.tsx` | ? |
|
||
|
||
### Priorität Niedrig
|
||
|
||
| # | Beschreibung | Datei | Aufwand |
|
||
|---|---|---|---|
|
||
| N5 | **AssignmentCreate**: Erstellt keine `instituteeEnrollments`. Von/Bis-Daten können nur über Edit gepflegt werden. | `AssignmentCreate.tsx` | S |
|
||
| N6 | **Meeting-Route**: URL ist `/assignment/:id/meeting/:meetingId` — `:id` ist die Assignment-ID, aber die Assignment-Nummer (z.B. CGI-2024-001) ist nicht in der URL. Akzeptiert als nice-to-have. | `App.tsx` | M |
|
||
|
||
---
|
||
|
||
## Geplante Erweiterungen (Roadmap)
|
||
|
||
### SQLite WASM + OPFS (Datenbankevolution)
|
||
**Ziel:** Robuste lokale Datenhaltung ohne Installation, ohne Risiko durch Browser-Speicherdruck.
|
||
**Technologie:** SQLite compiled to WebAssembly, persistiert via Origin Private File System (OPFS).
|
||
**Vorteil:** Echte Datei auf Gerät, nicht löschbar wie IndexedDB. Kein Server nötig.
|
||
**Status:** Konzept beschlossen. Implementierung steht aus. Paralleles Backup-System ist die aktuelle Notlösung.
|
||
|
||
### Evaluation — Zeitgewichteter Vorschlag (erledigt, 2026-07-02)
|
||
Vollständig umgesetzt, siehe `docs/EVALUATION_FEEDBACK_REDESIGN.md` für die Design-Entscheidungen:
|
||
- Kategorie-Scores werden über `src/utils/ratingTrend.ts` zeitgewichtet gemittelt (Rang = Reihenfolge der tatsächlich erfolgten Bewertungen dieser Kategorie, nicht fester Meeting-Index); Gewichtungsfaktor konfigurierbar unter Config → Gewichtung (`RatingWeightConfig.tsx`, Tabelle `appSettings`)
|
||
- Trend (Verbesserung/Verschlechterung) wird ab 2 bewerteten Meetings pro Kategorie erkannt (Delta ≥ 0,5 Punkte)
|
||
- Vorschlags-Badge auf `AssignmentFeedbackPage` dauerhaft sichtbar neben dem manuellen Rating, mit „Übernehmen“ und „Trend in Text übernehmen" (fügt deterministischen Satz in Achievements/Development Needs ein)
|
||
- `buildAiPrompt` um Trend-Abschnitt erweitert; dabei auch den Legacy-`db.criteria`-Bug (ehem. M2) gefixt
|
||
- `Assessment`- und `FeedbackCategoryRating`-Daten bleiben bewusst getrennte, unabhängige Strukturen — der Vorschlag ist rein additiv
|
||
|
||
### Kriterium-Tagging + Notation-Vorschlag (erledigt, 2026-07-03)
|
||
- `ConversationEntry.lineTags: { text, criterionItemId }[]` ordnet einzelne Zeilen innerhalb eines Sprecher-Blocks einem Kriterium zu (Matching per exaktem Zeilentext, nicht Index — überlebt nachträgliches Einfügen/Löschen von Zeilen). Ein früherer Zwischenstand mit "ein Entry pro Zeile" wurde verworfen, weil er die Protokoll-Lesbarkeit zerstört hat.
|
||
- `detectNotationRating()` (`notationParser.tsx`) mappt `!`/`(!)`/`(+)`/`+` auf eine Bewertungsstufe; kombiniert mit getaggten Zeilen liefert `AssessmentTab.tsx` einen Rating-Vorschlag pro Kriterium-Item ("Vorschlag aus Protokoll"), unabhängig von der bestehenden `ConversationSkillScore`-Kategorie-Schnellbewertung.
|
||
- Füllwörter/Weichmacher-Formulierungen werden bewusst nicht über eigene Text-Erkennung behandelt, sondern über ein niedrig gewichtetes Kriterium + normales Tagging abgedeckt.
|
||
- Kriterium-Gewichtung dabei auf `0,0–2,0` (0,1-Schritte) verfeinert; ein latenter Division-durch-Null-Bug bei Gewicht `0` in allen gewichteten Mittelwerten (`catMode`, `ratingTrend.ts`) wurde dabei gefunden und gefixt.
|
||
|
||
### Dashboard-Verbesserungen (N1 oben)
|
||
- Assignment-Nummer anzeigen
|
||
- Filtern nach Status (aktiv/abgeschlossen)
|
||
- Sortierung nach Datum / Assignment-Nummer
|
||
|
||
---
|
||
|
||
## Bekannte Datenkonsistenz-Risiken
|
||
|
||
| Risiko | Beschreibung | Mitigation |
|
||
|---|---|---|
|
||
| `criteriaIds` auf `AssignmentType` | Referenziert `FeedbackCriterionItem.id`. Wenn Kriterien gelöscht werden, bleiben verwaiste IDs in `criteriaIds`. Filter ignoriert fehlende IDs stillschweigend. | Beim Löschen von Items: `criteriaIds` in allen AssignmentTypes bereinigen |
|
||
| `Assessment.criteriaId` | Referenziert `FeedbackCriterionItem.id`. Kein FK-Constraint in IndexedDB. | Beim Löschen von Items: zugehörige Assessments löschen |
|
||
| `ConversationSkillScore.criteriaId` | Referenziert `FeedbackCategory.id`. Gleiche Gefahr. | Beim Löschen von Kategorien: ConversationSkillScores bereinigen |
|
||
| `ConversationEntry.lineTags[].criterionItemId` | Referenziert `FeedbackCriterionItem.id`. Kein FK-Constraint — beim Löschen eines Kriterium-Items bleiben Zeilen-Tags verwaist (Anzeige zeigt dann kein Kriterium mehr, aber Datensatz bleibt). | Beim Löschen von Items: `lineTags` in betroffenen `conversationEntries` bereinigen |
|
||
| Typ-Wechsel bei Assignment | Zeigt Warnung, löscht aber keine alten Meeting-Bewertungen. Bewertungen mit IDs aus dem alten Typ-Kriteriensatz bleiben erhalten, werden aber möglicherweise nicht mehr angezeigt. | Dokumentiertes Verhalten, absichtlich so gestaltet |
|