CG-Feedback-Monitor/CLAUDE.md
2026-07-02 10:10:06 +02:00

102 lines
3.6 KiB
Markdown

# CLAUDE.md — Assignment Monitor
Progressive Web App zur Live-Bewertung von Capgemini-Trainees (Institutees) während Kunden-Assignments.
**Vollständige Dokumentation:** `docs/` — bei neuer Session zuerst `docs/HANDOVER.md` lesen.
---
## Stack
- React 18 + TypeScript + Vite (PWA)
- Tailwind CSS v4 — `@import "tailwindcss"` in CSS, **kein** `tailwind.config.js`
- Dexie.js v5 — IndexedDB-Wrapper, kein Backend
- React Router v6
- Capgemini-Brandfarbe: `#0070AD`
## Entwicklung
```bash
npm run dev # Dev-Server starten
npx tsc --noEmit # TypeScript-Check — muss vor jeder Abgabe fehlerfrei sein
```
---
## Kritische Eigenheiten
### Doppelte `criteriaId`-Semantik
```
Assessment.criteriaId → FeedbackCriterionItem.id (Gesamtbewertung)
ConversationSkillScore.criteriaId → FeedbackCategory.id (Schnellbewertung)
```
### AssignmentType.criteriaIds
Referenziert `FeedbackCriterionItem.id[]`. Leer = alle Kriterien anzeigen.
Filterlogik (immer so anwenden):
```typescript
const itemFilter = aType?.criteriaIds?.length ? new Set(aType.criteriaIds) : null
const filteredItems = itemFilter ? allItems.filter(i => itemFilter.has(i.id!)) : allItems
const visibleCatIds = new Set(filteredItems.map(i => i.categoryId))
const filteredCats = itemFilter ? allCats.filter(c => visibleCatIds.has(c.id!)) : allCats
```
### Rating-Skala
```typescript
type FeedbackRating = 'na' | 'not_client_ready' | 'partially_client_ready' | 'nearly_client_ready' | 'client_ready'
// Numerisch: na=0, not=1, partially=2, nearly=3, fully=4
// N/A gilt als "nicht gesetzt" — aus allen Berechnungen ausschließen!
```
Aggregation: gewichteter Durchschnitt → `avg < 1.5` Not · `< 2.5` Partially · `< 3.5` Nearly · `≥ 3.5` Fully
### Routing
```
/assignment/:id/meeting/:meetingId ← meetingId ist MeetingInstance.id, nicht Assignment-ID
```
MeetingView liest: `const { id, meetingId: meetingIdParam } = useParams()`
### Sonstige Fallstricke
- `MeetingInstance.generalNotes` kann `undefined` sein → immer `?? ''` als Fallback
- `PhaseKey` ist `string`, kein Union-Typ
- Tailwind v4: arbitrary values `bg-[#0070AD]` direkt im className — kein Config nötig
---
## Stil-Regeln
- **Keine Kommentare** außer für nicht-offensichtliche Invarianten (kein „Was", nur „Warum")
- **Keine Auto-Resize-Textarea via `rows={1}` + JS** — stattdessen View/Edit-Toggle oder `fieldSizing: 'content'` als Inline-Style
- **`RATING_OPTIONS`-Array** nicht neu definieren — immer aus dem bestehenden Array in der jeweiligen Datei verwenden
- **Kein `useEffect` für DB-Calls** außer bei initialem Load — lieber direkte `async`-Funktionen
---
## Offene Punkte (priorisiert)
| Prio | Aufgabe | Datei |
|---|---|---|
| M | `Evaluation.tsx` auf neue Datenstruktur migrieren | `src/pages/Evaluation.tsx` |
| M | AI-Prompt auf `feedbackCriterionItems` umstellen | `src/pages/AssignmentFeedbackPage.tsx` |
| M | `meetingExport.ts` — Kriterien-Auflösung anpassen | `src/utils/meetingExport.ts` |
| N | Dashboard: Assignment-Nummer anzeigen | `src/pages/Dashboard.tsx` |
| N | AssignmentCreate: Feld für Assignment-Nummer | `src/pages/AssignmentCreate.tsx` |
| N | Toter Code in FeedbackStructureConfig entfernen | `src/pages/FeedbackStructureConfig.tsx` |
| L | SQLite WASM + OPFS Migration (kein festes Datum) | `src/db/index.ts` |
---
## Datenschutz
- Alle Daten lokal (IndexedDB) — **kein Public Cloud Upload**
- GDPR-relevant: Institutee-Namen, Kundennamen, Gesprächsnotizen
- KI-API-Key in `localStorage` — nie loggen oder ausgeben
- Backup-JSON enthält alle personenbezogenen Daten → vertraulich behandeln