3.6 KiB
3.6 KiB
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, keintailwind.config.js - Dexie.js v5 — IndexedDB-Wrapper, kein Backend
- React Router v6
- Capgemini-Brandfarbe:
#0070AD
Entwicklung
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):
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
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.generalNoteskannundefinedsein → immer?? ''als FallbackPhaseKeyiststring, 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 oderfieldSizing: 'content'als Inline-Style RATING_OPTIONS-Array nicht neu definieren — immer aus dem bestehenden Array in der jeweiligen Datei verwenden- Kein
useEffectfür DB-Calls außer bei initialem Load — lieber direkteasync-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