fix(admin-v2): Restore complete admin-v2 application
The admin-v2 application was incomplete in the repository. This commit restores all missing components: - Admin pages (76 pages): dashboard, ai, compliance, dsgvo, education, infrastructure, communication, development, onboarding, rbac - SDK pages (45 pages): tom, dsfa, vvt, loeschfristen, einwilligungen, vendor-compliance, tom-generator, dsr, and more - Developer portal (25 pages): API docs, SDK guides, frameworks - All components, lib files, hooks, and types - Updated package.json with all dependencies The issue was caused by incomplete initial repository state - the full admin-v2 codebase existed in backend/admin-v2 and docs-src/admin-v2 but was never fully synced to the main admin-v2 directory. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
831
admin-v2/app/(admin)/compliance/ai-act/page.tsx
Normal file
831
admin-v2/app/(admin)/compliance/ai-act/page.tsx
Normal file
@@ -0,0 +1,831 @@
|
||||
'use client'
|
||||
|
||||
/**
|
||||
* EU-AI-Act Risk Classification Page
|
||||
*
|
||||
* Self-assessment and documentation of AI risk categories according to EU AI Act.
|
||||
* Provides module-by-module risk assessment, warning lines, and exportable documentation.
|
||||
*/
|
||||
|
||||
import { useState } from 'react'
|
||||
import { PagePurpose } from '@/components/common/PagePurpose'
|
||||
|
||||
// =============================================================================
|
||||
// TYPES
|
||||
// =============================================================================
|
||||
|
||||
type RiskLevel = 'unacceptable' | 'high' | 'limited' | 'minimal'
|
||||
|
||||
interface ModuleAssessment {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
riskLevel: RiskLevel
|
||||
justification: string
|
||||
humanInLoop: boolean
|
||||
transparencyMeasures: string[]
|
||||
aiActArticle: string
|
||||
}
|
||||
|
||||
interface WarningLine {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
wouldTrigger: RiskLevel
|
||||
currentStatus: 'safe' | 'approaching' | 'violated'
|
||||
recommendation: string
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// DATA - Breakpilot Module Assessments
|
||||
// =============================================================================
|
||||
|
||||
const MODULE_ASSESSMENTS: ModuleAssessment[] = [
|
||||
{
|
||||
id: 'text-suggestions',
|
||||
name: 'Textvorschlaege / Formulierhilfen',
|
||||
description: 'KI-generierte Textvorschlaege fuer Gutachten und Feedback',
|
||||
riskLevel: 'minimal',
|
||||
justification: 'Reine Assistenzfunktion ohne Entscheidungswirkung. Lehrer editieren und finalisieren alle Texte.',
|
||||
humanInLoop: true,
|
||||
transparencyMeasures: ['KI-Label auf generierten Texten', 'Editierbare Vorschlaege'],
|
||||
aiActArticle: 'Art. 69 (Freiwillige Verhaltenskodizes)',
|
||||
},
|
||||
{
|
||||
id: 'rag-sources',
|
||||
name: 'RAG-basierte Quellenanzeige',
|
||||
description: 'Retrieval Augmented Generation fuer Lehrplan- und Erwartungshorizont-Referenzen',
|
||||
riskLevel: 'minimal',
|
||||
justification: 'Zitierende Referenzfunktion. Zeigt nur offizielle Quellen an, trifft keine Entscheidungen.',
|
||||
humanInLoop: true,
|
||||
transparencyMeasures: ['Quellenangaben', 'Direkte Links zu Originaldokumenten'],
|
||||
aiActArticle: 'Art. 69 (Freiwillige Verhaltenskodizes)',
|
||||
},
|
||||
{
|
||||
id: 'correction-suggestions',
|
||||
name: 'Korrektur-Vorschlaege',
|
||||
description: 'KI-Vorschlaege fuer Bewertungskriterien und Punktevergabe',
|
||||
riskLevel: 'limited',
|
||||
justification: 'Vorschlaege ohne bindende Wirkung. Lehrkraft behaelt vollstaendige Entscheidungshoheit.',
|
||||
humanInLoop: true,
|
||||
transparencyMeasures: [
|
||||
'Klare Kennzeichnung als KI-Vorschlag',
|
||||
'Begruendung fuer jeden Vorschlag',
|
||||
'Einfache Ueberschreibung moeglich',
|
||||
],
|
||||
aiActArticle: 'Art. 52 (Transparenzpflichten)',
|
||||
},
|
||||
{
|
||||
id: 'eh-matching',
|
||||
name: 'Erwartungshorizont-Abgleich',
|
||||
description: 'Automatischer Abgleich von Schuelerantworten mit Erwartungshorizonten',
|
||||
riskLevel: 'limited',
|
||||
justification: 'Empfehlung, keine Entscheidung. Zeigt Uebereinstimmungen auf, bewertet nicht eigenstaendig.',
|
||||
humanInLoop: true,
|
||||
transparencyMeasures: [
|
||||
'Visualisierung der Matching-Logik',
|
||||
'Confidence-Score angezeigt',
|
||||
'Manuelle Korrektur jederzeit moeglich',
|
||||
],
|
||||
aiActArticle: 'Art. 52 (Transparenzpflichten)',
|
||||
},
|
||||
{
|
||||
id: 'report-drafts',
|
||||
name: 'Zeugnis-Textentwurf',
|
||||
description: 'KI-generierte Entwuerfe fuer Zeugnistexte und Beurteilungen',
|
||||
riskLevel: 'limited',
|
||||
justification: 'Entwurf, der von der Lehrkraft finalisiert wird. Keine automatische Uebernahme.',
|
||||
humanInLoop: true,
|
||||
transparencyMeasures: [
|
||||
'Entwurf-Wasserzeichen',
|
||||
'Pflicht zur manuellen Freigabe',
|
||||
'Vollstaendig editierbar',
|
||||
],
|
||||
aiActArticle: 'Art. 52 (Transparenzpflichten)',
|
||||
},
|
||||
{
|
||||
id: 'edu-search',
|
||||
name: 'Bildungssuche (edu-search)',
|
||||
description: 'Semantische Suche in Lehrplaenen und Bildungsmaterialien',
|
||||
riskLevel: 'minimal',
|
||||
justification: 'Informationsretrieval ohne Bewertungsfunktion. Reine Suchfunktion.',
|
||||
humanInLoop: true,
|
||||
transparencyMeasures: ['Quellenangaben', 'Ranking-Transparenz'],
|
||||
aiActArticle: 'Art. 69 (Freiwillige Verhaltenskodizes)',
|
||||
},
|
||||
]
|
||||
|
||||
// =============================================================================
|
||||
// DATA - Warning Lines (What we must never build)
|
||||
// =============================================================================
|
||||
|
||||
const WARNING_LINES: WarningLine[] = [
|
||||
{
|
||||
id: 'auto-grading',
|
||||
title: 'Automatische Notenvergabe',
|
||||
description: 'KI berechnet und vergibt Noten ohne menschliche Pruefung',
|
||||
wouldTrigger: 'high',
|
||||
currentStatus: 'safe',
|
||||
recommendation: 'Noten immer als Vorschlag, nie als finale Entscheidung',
|
||||
},
|
||||
{
|
||||
id: 'student-classification',
|
||||
title: 'Schuelerklassifikation',
|
||||
description: 'Automatische Einteilung in Leistungsgruppen (leistungsstark/schwach)',
|
||||
wouldTrigger: 'high',
|
||||
currentStatus: 'safe',
|
||||
recommendation: 'Keine automatische Kategorisierung von Schuelern implementieren',
|
||||
},
|
||||
{
|
||||
id: 'promotion-decisions',
|
||||
title: 'Versetzungsentscheidungen',
|
||||
description: 'Automatisierte Logik fuer Versetzung/Nichtversetzung',
|
||||
wouldTrigger: 'high',
|
||||
currentStatus: 'safe',
|
||||
recommendation: 'Versetzungsentscheidungen ausschliesslich bei Lehrkraeften belassen',
|
||||
},
|
||||
{
|
||||
id: 'unreviewed-assessments',
|
||||
title: 'Ungeprueft freigegebene Bewertungen',
|
||||
description: 'KI-Bewertungen ohne menschliche Kontrolle an Schueler/Eltern',
|
||||
wouldTrigger: 'high',
|
||||
currentStatus: 'safe',
|
||||
recommendation: 'Immer manuellen Freigabe-Schritt vor Veroeffentlichung',
|
||||
},
|
||||
{
|
||||
id: 'behavioral-profiling',
|
||||
title: 'Verhaltensprofilierung',
|
||||
description: 'Erstellung von Persoenlichkeits- oder Verhaltensprofilen von Schuelern',
|
||||
wouldTrigger: 'unacceptable',
|
||||
currentStatus: 'safe',
|
||||
recommendation: 'Keine Verhaltensanalyse oder Profiling implementieren',
|
||||
},
|
||||
{
|
||||
id: 'algorithmic-optimization',
|
||||
title: 'Algorithmische Schuloptimierung',
|
||||
description: 'KI optimiert Schulentscheidungen (Klassenzuteilung, Ressourcen)',
|
||||
wouldTrigger: 'high',
|
||||
currentStatus: 'safe',
|
||||
recommendation: 'Schulorganisatorische Entscheidungen bei Menschen belassen',
|
||||
},
|
||||
{
|
||||
id: 'auto-accept',
|
||||
title: 'Auto-Accept Funktionen',
|
||||
description: 'Ein-Klick-Uebernahme von KI-Vorschlaegen ohne Pruefung',
|
||||
wouldTrigger: 'high',
|
||||
currentStatus: 'safe',
|
||||
recommendation: 'Immer bewusste Bestaetigungsschritte einbauen',
|
||||
},
|
||||
{
|
||||
id: 'emotion-detection',
|
||||
title: 'Emotionserkennung',
|
||||
description: 'Analyse von Emotionen oder psychischem Zustand von Schuelern',
|
||||
wouldTrigger: 'unacceptable',
|
||||
currentStatus: 'safe',
|
||||
recommendation: 'Keine biometrische oder emotionale Analyse',
|
||||
},
|
||||
]
|
||||
|
||||
// =============================================================================
|
||||
// HELPER FUNCTIONS
|
||||
// =============================================================================
|
||||
|
||||
const getRiskLevelInfo = (level: RiskLevel) => {
|
||||
switch (level) {
|
||||
case 'unacceptable':
|
||||
return {
|
||||
label: 'Unzulaessig',
|
||||
color: 'bg-black text-white',
|
||||
borderColor: 'border-black',
|
||||
description: 'Verboten nach EU-AI-Act',
|
||||
}
|
||||
case 'high':
|
||||
return {
|
||||
label: 'Hoch',
|
||||
color: 'bg-red-600 text-white',
|
||||
borderColor: 'border-red-600',
|
||||
description: 'Strenge Anforderungen, Konformitaetsbewertung',
|
||||
}
|
||||
case 'limited':
|
||||
return {
|
||||
label: 'Begrenzt',
|
||||
color: 'bg-amber-500 text-white',
|
||||
borderColor: 'border-amber-500',
|
||||
description: 'Transparenzpflichten',
|
||||
}
|
||||
case 'minimal':
|
||||
return {
|
||||
label: 'Minimal',
|
||||
color: 'bg-green-600 text-white',
|
||||
borderColor: 'border-green-600',
|
||||
description: 'Freiwillige Verhaltenskodizes',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getStatusInfo = (status: 'safe' | 'approaching' | 'violated') => {
|
||||
switch (status) {
|
||||
case 'safe':
|
||||
return { label: 'Sicher', color: 'bg-green-100 text-green-700', icon: '✓' }
|
||||
case 'approaching':
|
||||
return { label: 'Annaehernd', color: 'bg-amber-100 text-amber-700', icon: '⚠' }
|
||||
case 'violated':
|
||||
return { label: 'Verletzt', color: 'bg-red-100 text-red-700', icon: '✗' }
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// COMPONENT
|
||||
// =============================================================================
|
||||
|
||||
export default function AIActClassificationPage() {
|
||||
const [activeTab, setActiveTab] = useState<'overview' | 'modules' | 'warnings' | 'documentation'>('overview')
|
||||
const [expandedModule, setExpandedModule] = useState<string | null>(null)
|
||||
|
||||
// Calculate statistics
|
||||
const stats = {
|
||||
totalModules: MODULE_ASSESSMENTS.length,
|
||||
minimalRisk: MODULE_ASSESSMENTS.filter((m) => m.riskLevel === 'minimal').length,
|
||||
limitedRisk: MODULE_ASSESSMENTS.filter((m) => m.riskLevel === 'limited').length,
|
||||
highRisk: MODULE_ASSESSMENTS.filter((m) => m.riskLevel === 'high').length,
|
||||
humanInLoop: MODULE_ASSESSMENTS.filter((m) => m.humanInLoop).length,
|
||||
warningsTotal: WARNING_LINES.length,
|
||||
warningsSafe: WARNING_LINES.filter((w) => w.currentStatus === 'safe').length,
|
||||
}
|
||||
|
||||
const generateMemo = () => {
|
||||
const date = new Date().toLocaleDateString('de-DE', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})
|
||||
|
||||
const memo = `
|
||||
================================================================================
|
||||
EU-AI-ACT RISIKOKLASSIFIZIERUNG - BREAKPILOT
|
||||
================================================================================
|
||||
Erstellungsdatum: ${date}
|
||||
Version: 1.0
|
||||
Verantwortlich: Breakpilot GmbH
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
1. ZUSAMMENFASSUNG
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
System: Breakpilot KI-Assistenzsystem fuer Bildung
|
||||
Gesamtrisikokategorie: LIMITED RISK (Art. 52 EU-AI-Act)
|
||||
|
||||
Begruendung:
|
||||
- KI liefert ausschliesslich Vorschlaege und Entwuerfe
|
||||
- Kein automatisiertes Entscheiden ueber Schueler
|
||||
- Mensch-in-the-Loop ist technisch erzwungen
|
||||
- Keine Schuelerklassifikation oder Profiling
|
||||
- Alle paedagogischen Entscheidungen verbleiben bei Lehrkraeften
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
2. MODUL-BEWERTUNG
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
${MODULE_ASSESSMENTS.map(
|
||||
(m) => `
|
||||
${m.name}
|
||||
Risikostufe: ${getRiskLevelInfo(m.riskLevel).label.toUpperCase()}
|
||||
Begruendung: ${m.justification}
|
||||
Human-in-Loop: ${m.humanInLoop ? 'JA' : 'NEIN'}
|
||||
AI-Act Artikel: ${m.aiActArticle}
|
||||
`
|
||||
).join('')}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
3. TRANSPARENZMASSNAHMEN
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Alle KI-generierten Inhalte sind:
|
||||
- Klar als KI-Vorschlag gekennzeichnet
|
||||
- Vollstaendig editierbar durch die Lehrkraft
|
||||
- Mit Quellenangaben versehen (wo zutreffend)
|
||||
- Erst nach manueller Freigabe wirksam
|
||||
|
||||
Zusaetzliche UI-Hinweise:
|
||||
- "Dieser Text wurde durch KI vorgeschlagen"
|
||||
- "Endverantwortung liegt bei der Lehrkraft"
|
||||
- Confidence-Scores wo relevant
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
4. HUMAN-IN-THE-LOOP GARANTIEN
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Technisch erzwungene Massnahmen:
|
||||
- Kein Auto-Accept fuer KI-Vorschlaege
|
||||
- Kein 1-Click-Bewerten
|
||||
- Pflicht-Bestaetigung vor Freigabe
|
||||
- Audit-Trail aller Aenderungen
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
5. WARNLINIEN (NICHT IMPLEMENTIEREN)
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
${WARNING_LINES.map(
|
||||
(w) => `
|
||||
[${getStatusInfo(w.currentStatus).icon}] ${w.title}
|
||||
Wuerde ausloesen: ${getRiskLevelInfo(w.wouldTrigger).label}
|
||||
Status: ${getStatusInfo(w.currentStatus).label}
|
||||
`
|
||||
).join('')}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
6. RECHTLICHE EINORDNUNG
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Breakpilot faellt NICHT unter die High-Risk Kategorie des EU-AI-Act, da:
|
||||
|
||||
1. Keine automatisierten Entscheidungen ueber natuerliche Personen
|
||||
2. Keine Bewertung von Schuelern ohne menschliche Kontrolle
|
||||
3. Keine Zugangs- oder Selektionsentscheidungen
|
||||
4. Reine Assistenzfunktion mit Human-in-the-Loop
|
||||
|
||||
Die Transparenzpflichten nach Art. 52 werden durch entsprechende
|
||||
UI-Kennzeichnungen und Nutzerinformationen erfuellt.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
7. MANAGEMENT-STATEMENT
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
"Breakpilot ist ein KI-Assistenzsystem mit begrenztem Risiko gemaess EU-AI-Act.
|
||||
Die KI trifft keine Entscheidungen, sondern unterstuetzt Lehrkraefte transparent
|
||||
und nachvollziehbar. Alle paedagogischen und rechtlichen Entscheidungen
|
||||
verbleiben beim Menschen."
|
||||
|
||||
================================================================================
|
||||
Dieses Dokument dient der internen Compliance-Dokumentation und kann
|
||||
Auditoren auf Anfrage vorgelegt werden.
|
||||
================================================================================
|
||||
`
|
||||
return memo
|
||||
}
|
||||
|
||||
const downloadMemo = () => {
|
||||
const memo = generateMemo()
|
||||
const blob = new Blob([memo], { type: 'text/plain;charset=utf-8' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = `breakpilot-ai-act-klassifizierung-${new Date().toISOString().split('T')[0]}.txt`
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
|
||||
const tabs = [
|
||||
{ id: 'overview', name: 'Uebersicht', icon: '📊' },
|
||||
{ id: 'modules', name: 'Module', icon: '🧩' },
|
||||
{ id: 'warnings', name: 'Warnlinien', icon: '⚠️' },
|
||||
{ id: 'documentation', name: 'Dokumentation', icon: '📄' },
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-50">
|
||||
{/* Header */}
|
||||
<div className="bg-white border-b border-slate-200">
|
||||
<div className="max-w-7xl mx-auto px-6 py-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-blue-600 to-indigo-700 flex items-center justify-center">
|
||||
<span className="text-2xl">🤖</span>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-slate-900">EU-AI-Act Klassifizierung</h1>
|
||||
<p className="text-slate-600">Risikoklassifizierung und Compliance-Dokumentation</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="max-w-7xl mx-auto px-6 py-6">
|
||||
{/* Page Purpose */}
|
||||
<PagePurpose
|
||||
title="KI-Risikoklassifizierung nach EU-AI-Act"
|
||||
purpose="Selbstbewertung und Dokumentation der Risikokategorien aller KI-Module gemaess EU-AI-Act. Definiert Warnlinien fuer Features, die nicht implementiert werden duerfen."
|
||||
audience={['Management', 'DSB', 'Compliance Officer', 'Auditor', 'Investoren']}
|
||||
gdprArticles={['EU-AI-Act Art. 52', 'EU-AI-Act Art. 69', 'EU-AI-Act Anhang III']}
|
||||
/>
|
||||
|
||||
{/* Stats Cards */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mt-6">
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-4">
|
||||
<div className="text-sm text-slate-500">Module gesamt</div>
|
||||
<div className="text-2xl font-bold text-slate-900">{stats.totalModules}</div>
|
||||
</div>
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-4">
|
||||
<div className="text-sm text-slate-500">Minimal Risk</div>
|
||||
<div className="text-2xl font-bold text-green-600">{stats.minimalRisk}</div>
|
||||
</div>
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-4">
|
||||
<div className="text-sm text-slate-500">Limited Risk</div>
|
||||
<div className="text-2xl font-bold text-amber-600">{stats.limitedRisk}</div>
|
||||
</div>
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-4">
|
||||
<div className="text-sm text-slate-500">Human-in-Loop</div>
|
||||
<div className="text-2xl font-bold text-blue-600">{stats.humanInLoop}/{stats.totalModules}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Classification Banner */}
|
||||
<div className="mt-6 bg-gradient-to-r from-amber-50 to-amber-100 border border-amber-200 rounded-xl p-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-16 h-16 rounded-full bg-amber-200 flex items-center justify-center flex-shrink-0">
|
||||
<span className="text-3xl">⚖️</span>
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-xl font-bold text-amber-900">Gesamtklassifizierung: LIMITED RISK</h2>
|
||||
<p className="text-amber-800 mt-1">
|
||||
Breakpilot ist ein KI-Assistenzsystem mit <strong>begrenztem Risiko</strong> gemaess EU-AI-Act (Art. 52).
|
||||
Es gelten Transparenzpflichten, aber keine Konformitaetsbewertung.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2 mt-3">
|
||||
<span className="px-3 py-1 bg-amber-200 text-amber-800 rounded-full text-sm font-medium">
|
||||
Art. 52 Transparenz
|
||||
</span>
|
||||
<span className="px-3 py-1 bg-green-200 text-green-800 rounded-full text-sm font-medium">
|
||||
Human-in-the-Loop
|
||||
</span>
|
||||
<span className="px-3 py-1 bg-blue-200 text-blue-800 rounded-full text-sm font-medium">
|
||||
Assistiv, nicht autonom
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="flex gap-2 mt-6 border-b border-slate-200">
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setActiveTab(tab.id as typeof activeTab)}
|
||||
className={`px-4 py-3 text-sm font-medium border-b-2 transition-colors ${
|
||||
activeTab === tab.id
|
||||
? 'border-purple-600 text-purple-600'
|
||||
: 'border-transparent text-slate-600 hover:text-slate-900'
|
||||
}`}
|
||||
>
|
||||
<span className="mr-2">{tab.icon}</span>
|
||||
{tab.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Tab Content */}
|
||||
<div className="mt-6">
|
||||
{/* Overview Tab */}
|
||||
{activeTab === 'overview' && (
|
||||
<div className="space-y-6">
|
||||
{/* Risk Level Pyramid */}
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
||||
<h3 className="font-semibold text-slate-900 mb-4">EU-AI-Act Risikopyramide</h3>
|
||||
<div className="space-y-3">
|
||||
{/* Unacceptable */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-32 text-right">
|
||||
<span className="px-3 py-1 bg-black text-white text-xs rounded font-medium">
|
||||
Unzulaessig
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 h-8 bg-slate-100 rounded relative overflow-hidden">
|
||||
<div className="absolute inset-y-0 left-0 w-0 bg-black rounded" />
|
||||
<span className="absolute inset-0 flex items-center justify-center text-xs text-slate-500">
|
||||
0 Module - Social Scoring, Manipulation verboten
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* High */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-32 text-right">
|
||||
<span className="px-3 py-1 bg-red-600 text-white text-xs rounded font-medium">
|
||||
Hoch
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 h-8 bg-slate-100 rounded relative overflow-hidden">
|
||||
<div className="absolute inset-y-0 left-0 w-0 bg-red-600 rounded" />
|
||||
<span className="absolute inset-0 flex items-center justify-center text-xs text-slate-500">
|
||||
0 Module - Keine automatischen Entscheidungen
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Limited */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-32 text-right">
|
||||
<span className="px-3 py-1 bg-amber-500 text-white text-xs rounded font-medium">
|
||||
Begrenzt
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 h-8 bg-slate-100 rounded relative overflow-hidden">
|
||||
<div
|
||||
className="absolute inset-y-0 left-0 bg-amber-500 rounded transition-all"
|
||||
style={{ width: `${(stats.limitedRisk / stats.totalModules) * 100}%` }}
|
||||
/>
|
||||
<span className="absolute inset-0 flex items-center justify-center text-xs font-medium text-slate-700">
|
||||
{stats.limitedRisk} Module - Transparenzpflichten
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Minimal */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-32 text-right">
|
||||
<span className="px-3 py-1 bg-green-600 text-white text-xs rounded font-medium">
|
||||
Minimal
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 h-8 bg-slate-100 rounded relative overflow-hidden">
|
||||
<div
|
||||
className="absolute inset-y-0 left-0 bg-green-600 rounded transition-all"
|
||||
style={{ width: `${(stats.minimalRisk / stats.totalModules) * 100}%` }}
|
||||
/>
|
||||
<span className="absolute inset-0 flex items-center justify-center text-xs font-medium text-slate-700">
|
||||
{stats.minimalRisk} Module - Freiwillige Kodizes
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Key Arguments */}
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
||||
<h3 className="font-semibold text-slate-900 mb-4">Kernargumente fuer Limited Risk</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg">
|
||||
<span className="text-xl">✓</span>
|
||||
<div>
|
||||
<div className="font-medium text-green-900">Assistiv, nicht autonom</div>
|
||||
<div className="text-sm text-green-700">KI liefert Vorschlaege, keine Entscheidungen</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg">
|
||||
<span className="text-xl">✓</span>
|
||||
<div>
|
||||
<div className="font-medium text-green-900">Human-in-the-Loop</div>
|
||||
<div className="text-sm text-green-700">Lehrkraft hat immer das letzte Wort</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg">
|
||||
<span className="text-xl">✓</span>
|
||||
<div>
|
||||
<div className="font-medium text-green-900">Keine Schuelerklassifikation</div>
|
||||
<div className="text-sm text-green-700">Keine Kategorisierung oder Profiling</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg">
|
||||
<span className="text-xl">✓</span>
|
||||
<div>
|
||||
<div className="font-medium text-green-900">Transparente Kennzeichnung</div>
|
||||
<div className="text-sm text-green-700">KI-Inhalte sind klar markiert</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Management Statement */}
|
||||
<div className="bg-gradient-to-br from-slate-800 to-slate-900 rounded-xl p-6 text-white">
|
||||
<div className="flex items-start gap-4">
|
||||
<span className="text-3xl">💬</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-lg">Management-Statement (Pitch-faehig)</h3>
|
||||
<blockquote className="mt-3 text-slate-300 italic border-l-4 border-amber-500 pl-4">
|
||||
“Breakpilot ist ein KI-Assistenzsystem mit begrenztem Risiko gemaess EU-AI-Act.
|
||||
Die KI trifft keine Entscheidungen, sondern unterstuetzt Lehrkraefte transparent und nachvollziehbar.
|
||||
Alle paedagogischen und rechtlichen Entscheidungen verbleiben beim Menschen.”
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Modules Tab */}
|
||||
{activeTab === 'modules' && (
|
||||
<div className="space-y-4">
|
||||
<div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead className="bg-slate-50 border-b border-slate-200">
|
||||
<tr>
|
||||
<th className="text-left px-4 py-3 text-xs font-medium text-slate-500 uppercase">Modul</th>
|
||||
<th className="text-left px-4 py-3 text-xs font-medium text-slate-500 uppercase">Risikostufe</th>
|
||||
<th className="text-left px-4 py-3 text-xs font-medium text-slate-500 uppercase">Human-in-Loop</th>
|
||||
<th className="text-left px-4 py-3 text-xs font-medium text-slate-500 uppercase">AI-Act Artikel</th>
|
||||
<th className="px-4 py-3"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-slate-100">
|
||||
{MODULE_ASSESSMENTS.map((module) => {
|
||||
const riskInfo = getRiskLevelInfo(module.riskLevel)
|
||||
const isExpanded = expandedModule === module.id
|
||||
return (
|
||||
<>
|
||||
<tr key={module.id} className="hover:bg-slate-50">
|
||||
<td className="px-4 py-3">
|
||||
<div className="font-medium text-slate-800">{module.name}</div>
|
||||
<div className="text-sm text-slate-500">{module.description}</div>
|
||||
</td>
|
||||
<td className="px-4 py-3">
|
||||
<span className={`px-3 py-1 rounded text-xs font-medium ${riskInfo.color}`}>
|
||||
{riskInfo.label}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-3">
|
||||
{module.humanInLoop ? (
|
||||
<span className="text-green-600 font-medium">✓ Ja</span>
|
||||
) : (
|
||||
<span className="text-red-600 font-medium">✗ Nein</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="px-4 py-3 text-sm text-slate-600">{module.aiActArticle}</td>
|
||||
<td className="px-4 py-3">
|
||||
<button
|
||||
onClick={() => setExpandedModule(isExpanded ? null : module.id)}
|
||||
className="text-purple-600 hover:text-purple-800 text-sm"
|
||||
>
|
||||
{isExpanded ? 'Weniger' : 'Details'}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{isExpanded && (
|
||||
<tr key={`${module.id}-details`}>
|
||||
<td colSpan={5} className="px-4 py-4 bg-slate-50">
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<div className="text-xs font-medium text-slate-500 uppercase mb-1">Begruendung</div>
|
||||
<div className="text-sm text-slate-700">{module.justification}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs font-medium text-slate-500 uppercase mb-1">
|
||||
Transparenzmassnahmen
|
||||
</div>
|
||||
<ul className="text-sm text-slate-700 list-disc list-inside">
|
||||
{module.transparencyMeasures.map((measure, i) => (
|
||||
<li key={i}>{measure}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Warnings Tab */}
|
||||
{activeTab === 'warnings' && (
|
||||
<div className="space-y-6">
|
||||
<div className="bg-red-50 border border-red-200 rounded-xl p-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<span className="text-3xl">🚫</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-red-900">
|
||||
Warnlinien: Was wir NIEMALS bauen duerfen
|
||||
</h3>
|
||||
<p className="text-red-700 mt-1">
|
||||
Diese Features wuerden Breakpilot in die High-Risk oder Unzulaessig-Kategorie verschieben.
|
||||
Sie sind explizit von der Roadmap ausgeschlossen.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4">
|
||||
{WARNING_LINES.map((warning) => {
|
||||
const statusInfo = getStatusInfo(warning.currentStatus)
|
||||
const riskInfo = getRiskLevelInfo(warning.wouldTrigger)
|
||||
return (
|
||||
<div
|
||||
key={warning.id}
|
||||
className={`bg-white rounded-xl border-2 ${
|
||||
warning.currentStatus === 'safe'
|
||||
? 'border-green-200'
|
||||
: warning.currentStatus === 'approaching'
|
||||
? 'border-amber-300'
|
||||
: 'border-red-400'
|
||||
} p-4`}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start gap-3">
|
||||
<div
|
||||
className={`w-10 h-10 rounded-full flex items-center justify-center text-lg ${statusInfo.color}`}
|
||||
>
|
||||
{statusInfo.icon}
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-slate-900">{warning.title}</h4>
|
||||
<p className="text-sm text-slate-600 mt-1">{warning.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-slate-500">Wuerde ausloesen:</span>
|
||||
<span className={`px-2 py-1 rounded text-xs font-medium ${riskInfo.color}`}>
|
||||
{riskInfo.label}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 pl-13 ml-13">
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<span className="text-slate-500">Empfehlung:</span>
|
||||
<span className="text-slate-700">{warning.recommendation}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Safe Zone Indicator */}
|
||||
<div className="bg-green-50 border border-green-200 rounded-xl p-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-16 h-16 rounded-full bg-green-200 flex items-center justify-center">
|
||||
<span className="text-3xl">✓</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-green-900">
|
||||
Alle Warnlinien eingehalten: {stats.warningsSafe}/{stats.warningsTotal}
|
||||
</h3>
|
||||
<p className="text-green-700 mt-1">
|
||||
Breakpilot befindet sich sicher im Limited/Minimal Risk Bereich des EU-AI-Act.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Documentation Tab */}
|
||||
{activeTab === 'documentation' && (
|
||||
<div className="space-y-6">
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<h3 className="font-semibold text-slate-900">Klassifizierungs-Memo exportieren</h3>
|
||||
<p className="text-slate-600 mt-1">
|
||||
Generiert ein vollstaendiges Compliance-Dokument zur Vorlage bei Auditoren oder Investoren.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={downloadMemo}
|
||||
className="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors flex items-center gap-2"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||
/>
|
||||
</svg>
|
||||
Als TXT herunterladen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Preview */}
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
||||
<h3 className="font-semibold text-slate-900 mb-4">Vorschau</h3>
|
||||
<pre className="bg-slate-900 text-slate-100 p-4 rounded-lg overflow-x-auto text-xs font-mono whitespace-pre-wrap max-h-96 overflow-y-auto">
|
||||
{generateMemo()}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
{/* Human-in-the-Loop Documentation */}
|
||||
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
||||
<h3 className="font-semibold text-slate-900 mb-4">Human-in-the-Loop Nachweis</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="p-4 bg-blue-50 rounded-lg">
|
||||
<h4 className="font-medium text-blue-900">Technische Massnahmen</h4>
|
||||
<ul className="mt-2 text-sm text-blue-800 space-y-1">
|
||||
<li>• Kein Auto-Accept Button fuer KI-Vorschlaege</li>
|
||||
<li>• Mindestens 2 Klicks fuer Uebernahme erforderlich</li>
|
||||
<li>• Alle KI-Outputs sind editierbar</li>
|
||||
<li>• Pflicht-Review vor Freigabe an Schueler/Eltern</li>
|
||||
<li>• Audit-Trail dokumentiert alle menschlichen Eingriffe</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="p-4 bg-blue-50 rounded-lg">
|
||||
<h4 className="font-medium text-blue-900">UI-Kennzeichnungen</h4>
|
||||
<ul className="mt-2 text-sm text-blue-800 space-y-1">
|
||||
<li>• “KI-Vorschlag” Label auf allen generierten Inhalten</li>
|
||||
<li>• “Endverantwortung liegt bei der Lehrkraft” Hinweis</li>
|
||||
<li>• Confidence-Scores wo relevant</li>
|
||||
<li>• Quellenangaben fuer RAG-basierte Inhalte</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user