import type { FeedbackRating } from '../db/types' export const BRAND_COLOR = '#0070AD' /** * Kanonische Reihenfolge der Rating-Skala (nicht ändern — DB-Werte sind stabil). * `color` = Badge/Display-State (inaktiv) * `active` = ausgewählter Button-State */ export const RATING_OPTIONS: ReadonlyArray<{ value: FeedbackRating short: string label: string color: string active: string }> = [ { value: 'na', short: 'N/A', label: 'N/A (0)', color: 'bg-gray-100 text-gray-500 border-gray-300', active: 'bg-gray-400 text-white border-gray-400' }, { value: 'not_client_ready', short: 'Not', label: 'Not (1)', color: 'bg-red-100 text-red-700 border-red-300', active: 'bg-red-500 text-white border-red-500' }, { value: 'partially_client_ready', short: 'Partially', label: 'Partially (2)', color: 'bg-orange-100 text-orange-700 border-orange-300', active: 'bg-orange-500 text-white border-orange-500' }, { value: 'nearly_client_ready', short: 'Nearly', label: 'Nearly (3)', color: 'bg-green-100 text-green-600 border-green-300', active: 'bg-green-400 text-white border-green-400' }, { value: 'client_ready', short: 'Fully', label: 'Fully (4)', color: 'bg-green-100 text-green-800 border-green-400', active: 'bg-green-700 text-white border-green-700' }, ] /** Farb-Schemata für Teilnehmer-Badges (Index = Reihenfolge im Assignment). */ export const INST_COLORS = [ { bg: 'bg-blue-50', border: 'border-blue-300', tag: 'bg-blue-500', text: 'text-blue-700' }, { bg: 'bg-purple-50', border: 'border-purple-300', tag: 'bg-purple-500', text: 'text-purple-700' }, { bg: 'bg-emerald-50', border: 'border-emerald-300', tag: 'bg-emerald-500', text: 'text-emerald-700' }, { bg: 'bg-orange-50', border: 'border-orange-300', tag: 'bg-orange-500', text: 'text-orange-700' }, ] as const export const AI_CONFIG = { localStorageKeyApiKey: 'ai_api_key', localStorageKeyModel: 'ai_model', defaultModel: 'openai/gpt-4o-mini', openRouterBaseUrl: 'https://openrouter.ai/api/v1', defaultDimensionPromptTemplate: `Du bist Führungskraft und Mentor bei Capgemini. Erstelle einen professionellen, konstruktiven Beitrag zum Performance-Feedback für einen Berater/Trainee, beschränkt auf die Dimension "{{DIMENSION_NAME}}", auf Basis der folgenden Beobachtungsdaten aus echten Kundenterminen. BERATER: {{BERATER_NAME}} ASSIGNMENT: {{ASSIGNMENT_TITEL}} | Kunde: {{ASSIGNMENT_KUNDE}} FÜLLWÖRTER GESAMT: {{FUELLWOERTER_GESAMT}} KATEGORIEN DIESER DIMENSION: {{KATEGORIEN_STRUKTUR}} BEOBACHTETE KRITERIEN UND SCORES (0-4): {{KRITERIEN_SCORES}} MANUELLE KATEGORIE-BEWERTUNGEN: {{KATEGORIE_BEWERTUNGEN}} ENTWICKLUNG ÜBER DIE LAUFZEIT (chronologisch je Kategorie): {{ENTWICKLUNG_VERLAUF}} ALLGEMEINE MEETING-NOTIZEN (Berater-unabhängig, chronologisch): {{NOTIZEN_ALLGEMEIN_MEETING}} NICHT EINEM KRITERIUM ZUGEORDNETE PROTOKOLL-NOTIZEN DIESES BERATERS (chronologisch, Notation: + gut, ! negativ, > Kundeninput): {{PROTOKOLL_UNZUGEORDNET}} Schreibe für JEDE der oben gelisteten Kategorien einen kurzen Bewertungstext (2-3 Sätze, konkret, auf Beobachtungen gestützt) sowie abschließend einen Achievements-Absatz (2-4 Sätze, anerkennend) und einen Development-Needs-Absatz (2-4 Sätze, konstruktiv, handlungsorientiert) für die gesamte Dimension. Falls eine Kategorie aus den Daten nicht beurteilbar ist, schreibe "n/a". Beziehe erkennbare Verbesserungen/Verschlechterungen aus der Entwicklung über die Laufzeit ein. Schreibe direkt und persönlich (du-Form), vermeide generische Phrasen. Antworte AUSSCHLIESSLICH in exakt diesem Format, ohne zusätzliche Erklärungen, ohne Markdown-Formatierung: KATEGORIE: KATEGORIE: ACHIEVEMENTS: DEVELOPMENT_NEEDS: `, dimensionPromptPlaceholders: [ { token: '{{BERATER_NAME}}', description: 'Vor- und Nachname des Institutee' }, { token: '{{ASSIGNMENT_TITEL}}', description: 'Titel des Assignments' }, { token: '{{ASSIGNMENT_KUNDE}}', description: 'Kundenname des Assignments' }, { token: '{{DIMENSION_NAME}}', description: 'Name der aktuellen Dimension' }, { token: '{{KATEGORIEN_STRUKTUR}}', description: 'Liste der Kategorienamen dieser Dimension' }, { token: '{{KRITERIEN_SCORES}}', description: 'Kriterien mit Ø-Score und zusammengeführten Notizen, gruppiert nach Kategorie' }, { token: '{{KATEGORIE_BEWERTUNGEN}}', description: 'Manuell gesetzte Kategorie-Bewertungen (Not/Partially/Nearly/Fully)' }, { token: '{{ENTWICKLUNG_VERLAUF}}', description: 'Chronologischer Bewertungs-Trend je Kategorie über die Meetings' }, { token: '{{NOTIZEN_ALLGEMEIN_MEETING}}', description: 'Allgemeine, Berater-unabhängige Notizen je Meeting, chronologisch' }, { token: '{{PROTOKOLL_UNZUGEORDNET}}', description: 'Nicht getaggte Protokollzeilen dieses Beraters, chronologisch je Meeting' }, { token: '{{FUELLWOERTER_GESAMT}}', description: 'Füllwörter-Summe dieses Beraters über alle Meetings' }, ], } as const /** Numerische Gewichte für Rating-Aggregation. N/A wird aus Berechnungen ausgeschlossen. */ export const RATING_NUM_MAP: Record = { na: 0, not_client_ready: 1, partially_client_ready: 2, nearly_client_ready: 3, client_ready: 4, } /** Default-Zeitgewichtung für den Bewertungs-Vorschlag, überschreibbar über Config > Gewichtung. */ export const DEFAULT_RATING_TREND_WEIGHT_STEP = 0.5 /** Mindest-Punktedelta zwischen erstem und letztem bewerteten Meeting einer Kategorie, ab dem ein Trend gilt. */ export const RATING_TREND_DELTA_THRESHOLD = 0.5