Zuletzt abgeschlossen (2026-07-02/03): zeitgewichteter Bewertungs-Vorschlag (`ratingTrend.ts`), Kriterium-Zuordnung für Freitext-Notizen (`ConversationEntry.lineTags` + `CriterionTagPicker.tsx`), Notation → Bewertungs-Vorschlag in der Gesamtbewertung, feinere Kriterium-Gewichtung (0,0–2,0) inkl. Division-durch-Null-Fix, diverse Export-/Backup-Fixes. Design-Hintergrund dazu: `docs/EVALUATION_FEEDBACK_REDESIGN.md`.
**Vollständige, priorisierte Liste der offenen Punkte:** siehe `CLAUDE.md` → Abschnitt "Offene Punkte (priorisiert)" — das ist die laufend gepflegte Quelle, hier nicht dupliziert. Größere offene Themen, die eine eigene Design-Session brauchen: mehrstufiges Prompt-System für die KI-Generierung, selbstlernendes Tagging.
**Assignment Monitor** ist eine PWA für Lars Stommer (Capgemini Management Consultant Trainee Program Lead). Die App wird auf dem Smartphone genutzt, um Trainees (intern: „Institutees") während ihrer Kunden-Assignments live zu begleiten und zu bewerten. Lars führt die Meetings, beobachtet die Trainees und möchte sofort Notizen und Bewertungen erfassen, ohne Stift/Papier.
## Tech-Stack
- **React 18 + TypeScript + Vite** (PWA)
- **Tailwind CSS v4** (`@import "tailwindcss"` — kein `tailwind.config.js`!)
- **Dexie.js v5** als IndexedDB-Wrapper (lokale DB im Browser, kein Backend)
- **React Router v6**
- **Capgemini-Brandfarbe:** `#0070AD`
- Arbeitsverzeichnis: `C:\dev\AssigmentMonitor`
## Bewertungsskala (kritisch für alle Berechnungen)
3.**N/A-Aggregationsbug**: Filter der Form `a.score !== null` schließen `'na'` nicht aus (N/A ist ein String, kein `null`!) → verfälscht Mittelwerte. Bereits gefixt in `Evaluation.tsx`. Noch offen in `AssignmentFeedbackPage.tsx:63` (buildAiPrompt) und `FeedbackDraftPage.tsx:66`.
4.**FeedbackDraftPage.tsx** — nutzt noch Legacy `categories`/`criteria`, sollte auf `feedbackCriterionItems` migriert werden (analog zu `Evaluation.tsx`); letzter Konsument der Legacy-Tabellen außer den Seeds
5.**`db/queries/`-Layer** — DB-Zugriffe aus Komponenten in domänenspezifische Query-Funktionen extrahieren, bereitet SQLite-Migration vor
6.**KI-Generierung funktionsunfähig** — `generateWithAi()` schlägt fehl, vermutlich Capgemini-Netzwerk/Firewall blockiert `openrouter.ai`. Root Cause nicht untersucht.
8.**Mehrstufiges, pro Dimension konfigurierbares Prompt-System** — löst den aktuellen Einzel-Prompt in `buildAiPrompt` ab, braucht Spezialwissen je Dimension + Platzhaltersystem.
9.**Selbstlernendes Tagging** — aus bisherigen Zeile-zu-Kriterium-Zuordnungen automatische Tag-Vorschläge beim Tippen ableiten.
**Erledigt (2026-07-02):** Zeitgewichteter Bewertungs-Vorschlag mit Trend-Erkennung — `src/utils/ratingTrend.ts` berechnet pro Kategorie einen zeitgewichteten Vorschlag aus den Meeting-Assessments (Gewichtungsfaktor konfigurierbar unter Config → Gewichtung, neue Tabelle `appSettings`), erkennt Verbesserung/Verschlechterung über die Laufzeit und zeigt beides als Badge auf `AssignmentFeedbackPage` (mit „Übernehmen" + „Trend in Text übernehmen"). `buildAiPrompt` wurde um einen Trend-Abschnitt erweitert; dabei wurde auch der alte `db.criteria`-Bug mitgefixt.
**Erledigt (2026-07-03):** Kriterium-Zuordnung für Freitext-Notizen (`ConversationEntry.lineTags`, `CriterionTagPicker.tsx`, nachträglich pro Zeile innerhalb eines zusammenhängenden Sprecher-Blocks). Notation → Bewertungs-Vorschlag in der Gesamtbewertung (`detectNotationRating()`, „Vorschlag aus Protokoll"-Badge + Kategorie-weite 💡-Zähler). `meetingExport.ts` und `dbBackup.ts` gefixt (Legacy-`db.criteria`-Bug bzw. fehlende `appSettings`-Tabelle im Backup). Assignment-Nummer ist jetzt Pflichtfeld. Kriterium-Gewichtung auf `0,0–2,0` verfeinert, dabei einen Division-durch-Null-Bug bei Gewicht `0` in allen gewichteten Mittelwerten gefunden und gefixt.
Alle 21 Tabellen-Namen sind in `TABLE_NAMES` aufgelistet — bei neuen Tabellen dort ergänzen (ein fehlender Eintrag fällt nicht auf, bis jemand ein Backup zurückspielt und Daten fehlen — genau so ist `appSettings` einmal vergessen worden, siehe Kommentar über der Liste).
4.`migrateToUnifiedCriteriaIfNeeded()` — Migration auf FeedbackCategory-IDs in PhaseTemplates
## Datenschutz-Hinweise
- Alle Daten lokal, kein Cloud-Backend
- GDPR-relevant: Institutee-Namen + Kundennamen in der DB
- KI-API: OpenRouter, API-Key in localStorage (nicht im Klartext loggen!)
- Backup-JSON enthält alle personenbezogenen Daten → vertraulich behandeln
## TypeScript-Build
```bash
npx tsc --noEmit # Muss ohne Fehler durchlaufen
npm run dev # Dev-Server starten
```
Vor jeder Abgabe: `npx tsc --noEmit` ausführen und alle Fehler beheben.
## Wichtige Eigenheiten / Fallstricke
1.**`MeetingInstance.generalNotes`**: Kann in alten Datensätzen `undefined` sein → immer `?? ''` fallback
2.**`Assessment.criteriaId`**: Zeigt auf `FeedbackCriterionItem.id`, NICHT auf `FeedbackCategory.id` — das verwirrt, weil der Feldname `criteriaId` ist
3.**`PhaseKey`**: Ist `type PhaseKey = string` (kein Union-Typ mehr)
4.**`aType2`** in `AssignmentDetail.tsx`: Doppelte Variable aus Refactoring — `aType` wird zweimal deklariert, zweite heißt `aType2`. Technische Schuld.
5.**`expandedCat`** in `MeetingView`: `Record<instituteeId, categoryId | null>` — öffnet pro Institutee genau eine Kategorie gleichzeitig
6.**Dexie v5**: `bulkAdd` schlägt fehl wenn IDs schon vorhanden → Backup-Import leert erst alle Tabellen
7.**Gewichtete Mittelwerte**: immer `Σ(score×weight)/Σ(weight)`, nie `score×weight` roh interpretieren; bei `Σweight === 0` (seit Gewicht `0` erlaubt ist) `null`/`continue` statt Division — sonst `NaN < x` überall `false` → fällt auf „Fully" durch. Siehe `catMode()` (`AssessmentTab.tsx`) und `buildGroupMeetingScores()` (`ratingTrend.ts`).
8.**`ConversationEntry`** entspricht einem ganzen Sprecher-Turn (mehrzeiliger Text-Block), nicht einer einzelnen Zeile — ein Zwischenstand mit "ein Entry pro Zeile" wurde verworfen. Kriterium-Zuordnung läuft über `lineTags` (Matching per Zeilentext, nicht Index).