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:
BreakPilot Dev
2026-02-08 23:40:15 -08:00
parent f28244753f
commit 660295e218
385 changed files with 138126 additions and 3079 deletions

View 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">
&ldquo;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.&rdquo;
</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> &ldquo;KI-Vorschlag&rdquo; Label auf allen generierten Inhalten</li>
<li> &ldquo;Endverantwortung liegt bei der Lehrkraft&rdquo; Hinweis</li>
<li> Confidence-Scores wo relevant</li>
<li> Quellenangaben fuer RAG-basierte Inhalte</li>
</ul>
</div>
</div>
</div>
</div>
)}
</div>
</div>
</div>
)
}