A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
630 lines
22 KiB
Python
630 lines
22 KiB
Python
"""
|
|
Admin Klausurkorrektur Documentation Component.
|
|
|
|
Provides audit-ready documentation for education ministries and data protection officers.
|
|
Written in non-technical language for compliance review.
|
|
|
|
This component explains:
|
|
- Privacy-by-Design architecture
|
|
- DSGVO compliance measures
|
|
- Data flow and processing
|
|
- Security guarantees
|
|
"""
|
|
|
|
|
|
def get_admin_klausur_docs_css() -> str:
|
|
"""CSS for Klausur Documentation Panel."""
|
|
return """
|
|
/* ==========================================
|
|
KLAUSUR DOCUMENTATION STYLES (Audit-Ready)
|
|
========================================== */
|
|
|
|
.klausur-docs-panel {
|
|
background: var(--bp-surface-elevated);
|
|
border-radius: 12px;
|
|
padding: 24px;
|
|
margin-bottom: 20px;
|
|
border: 1px solid var(--bp-border);
|
|
}
|
|
|
|
.klausur-docs-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 24px;
|
|
padding-bottom: 16px;
|
|
border-bottom: 1px solid var(--bp-border);
|
|
}
|
|
|
|
.klausur-docs-header h2 {
|
|
margin: 0;
|
|
font-size: 20px;
|
|
color: var(--bp-text);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.audit-badge {
|
|
background: #065f46;
|
|
color: #6ee7b7;
|
|
font-size: 11px;
|
|
padding: 4px 10px;
|
|
border-radius: 4px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.doc-section {
|
|
margin-bottom: 32px;
|
|
}
|
|
|
|
.doc-section h3 {
|
|
color: var(--bp-text);
|
|
font-size: 16px;
|
|
margin: 0 0 16px 0;
|
|
padding-bottom: 8px;
|
|
border-bottom: 1px solid var(--bp-border-subtle);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.doc-section h3 .section-number {
|
|
background: var(--bp-primary);
|
|
color: white;
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.doc-content {
|
|
color: var(--bp-text-muted);
|
|
font-size: 14px;
|
|
line-height: 1.8;
|
|
}
|
|
|
|
.doc-content p {
|
|
margin: 0 0 12px 0;
|
|
}
|
|
|
|
.doc-content ul, .doc-content ol {
|
|
margin: 12px 0;
|
|
padding-left: 24px;
|
|
}
|
|
|
|
.doc-content li {
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.highlight-box {
|
|
background: rgba(6, 95, 70, 0.15);
|
|
border: 1px solid #065f46;
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.highlight-box.green {
|
|
background: rgba(6, 95, 70, 0.15);
|
|
border-color: #065f46;
|
|
}
|
|
|
|
.highlight-box.blue {
|
|
background: rgba(59, 130, 246, 0.1);
|
|
border-color: #3b82f6;
|
|
}
|
|
|
|
.highlight-box.yellow {
|
|
background: rgba(251, 191, 36, 0.1);
|
|
border-color: #fbbf24;
|
|
}
|
|
|
|
.highlight-box h4 {
|
|
color: inherit;
|
|
margin: 0 0 8px 0;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.highlight-box p, .highlight-box ul {
|
|
margin: 0;
|
|
color: inherit;
|
|
}
|
|
|
|
.highlight-box.green { color: #6ee7b7; }
|
|
.highlight-box.blue { color: #60a5fa; }
|
|
.highlight-box.yellow { color: #fbbf24; }
|
|
|
|
.data-flow-diagram {
|
|
background: var(--bp-surface);
|
|
border: 1px solid var(--bp-border);
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
margin: 16px 0;
|
|
font-family: monospace;
|
|
font-size: 12px;
|
|
overflow-x: auto;
|
|
white-space: pre;
|
|
color: var(--bp-text);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.legal-reference {
|
|
background: var(--bp-surface);
|
|
border-left: 3px solid var(--bp-primary);
|
|
padding: 12px 16px;
|
|
margin: 16px 0;
|
|
font-style: italic;
|
|
color: var(--bp-text-muted);
|
|
}
|
|
|
|
.legal-reference cite {
|
|
display: block;
|
|
margin-top: 8px;
|
|
font-style: normal;
|
|
font-weight: 600;
|
|
color: var(--bp-text);
|
|
}
|
|
|
|
.comparison-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 16px 0;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.comparison-table th,
|
|
.comparison-table td {
|
|
padding: 12px;
|
|
text-align: left;
|
|
border: 1px solid var(--bp-border);
|
|
}
|
|
|
|
.comparison-table th {
|
|
background: var(--bp-surface);
|
|
color: var(--bp-text);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.comparison-table td {
|
|
color: var(--bp-text-muted);
|
|
}
|
|
|
|
.comparison-table .good {
|
|
color: #22c55e;
|
|
}
|
|
|
|
.comparison-table .bad {
|
|
color: #ef4444;
|
|
}
|
|
|
|
.tech-specs {
|
|
background: var(--bp-surface);
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.tech-specs h4 {
|
|
margin: 0 0 12px 0;
|
|
color: var(--bp-text);
|
|
font-size: 14px;
|
|
}
|
|
|
|
.tech-specs table {
|
|
width: 100%;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.tech-specs td {
|
|
padding: 6px 0;
|
|
color: var(--bp-text-muted);
|
|
}
|
|
|
|
.tech-specs td:first-child {
|
|
color: var(--bp-text);
|
|
font-weight: 500;
|
|
width: 40%;
|
|
}
|
|
|
|
.print-button {
|
|
background: var(--bp-surface);
|
|
border: 1px solid var(--bp-border);
|
|
color: var(--bp-text);
|
|
padding: 10px 20px;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
font-size: 13px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.print-button:hover {
|
|
background: var(--bp-border);
|
|
}
|
|
|
|
@media print {
|
|
.klausur-docs-panel {
|
|
background: white;
|
|
color: black;
|
|
border: none;
|
|
}
|
|
|
|
.doc-content, .highlight-box, .tech-specs td {
|
|
color: black !important;
|
|
}
|
|
|
|
.print-button {
|
|
display: none;
|
|
}
|
|
}
|
|
"""
|
|
|
|
|
|
def get_admin_klausur_docs_html() -> str:
|
|
"""HTML for Klausur Documentation (Audit-Ready)."""
|
|
return """
|
|
<!-- Klausur Documentation Tab Content (Audit-Ready) -->
|
|
<div id="admin-content-klausur-docs" class="admin-content">
|
|
<div class="klausur-docs-panel">
|
|
<div class="klausur-docs-header">
|
|
<h2>
|
|
Datenschutz-Dokumentation Klausurkorrektur
|
|
<span class="audit-badge">Audit-Ready</span>
|
|
</h2>
|
|
<button class="print-button" onclick="window.print()">
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M6 9V2h12v7M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/>
|
|
<rect x="6" y="14" width="12" height="8"/>
|
|
</svg>
|
|
Drucken / PDF
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Section 1: Overview -->
|
|
<div class="doc-section">
|
|
<h3>
|
|
<span class="section-number">1</span>
|
|
Zusammenfassung fuer Entscheidungstraeger
|
|
</h3>
|
|
<div class="doc-content">
|
|
<div class="highlight-box green">
|
|
<h4>Kernaussage</h4>
|
|
<p>
|
|
Die KI-gestuetzte Klausurkorrektur verarbeitet <strong>keine personenbezogenen Daten</strong>
|
|
ausserhalb des Geraets der Lehrkraft. Die Verarbeitung ist datenschutzrechtlich
|
|
vergleichbar mit einer Korrektur auf dem eigenen PC der Lehrkraft.
|
|
</p>
|
|
</div>
|
|
|
|
<p>
|
|
Dieses System wurde nach dem Prinzip <strong>"Privacy by Design"</strong> entwickelt.
|
|
Schueler-Namen werden niemals an Server oder KI-Systeme uebermittelt.
|
|
Stattdessen werden zufaellige Dokumenten-Tokens (Pseudonyme) verwendet,
|
|
die nur die Lehrkraft lokal wieder aufloesen kann.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 2: Legal Basis -->
|
|
<div class="doc-section">
|
|
<h3>
|
|
<span class="section-number">2</span>
|
|
Rechtsgrundlage und DSGVO-Konformitaet
|
|
</h3>
|
|
<div class="doc-content">
|
|
<div class="legal-reference">
|
|
"Pseudonymisierung bezeichnet die Verarbeitung personenbezogener Daten in einer Weise,
|
|
dass die personenbezogenen Daten ohne Hinzuziehung zusaetzlicher Informationen nicht
|
|
mehr einer spezifischen betroffenen Person zugeordnet werden koennen."
|
|
<cite>— Art. 4 Nr. 5 DSGVO (Begriffsbestimmung Pseudonymisierung)</cite>
|
|
</div>
|
|
|
|
<p><strong>Anwendung auf unser System:</strong></p>
|
|
<ul>
|
|
<li>
|
|
<strong>Pseudonymisierung:</strong> Jedes Klausur-Dokument erhaelt einen
|
|
zufaelligen 128-Bit Token (UUID), der keinerlei Beziehung zur Schueleridentitaet hat.
|
|
</li>
|
|
<li>
|
|
<strong>Getrennte Speicherung:</strong> Die Zuordnung Token → Name wird
|
|
ausschliesslich lokal beim Lehrer gespeichert (verschluesselt mit AES-256).
|
|
</li>
|
|
<li>
|
|
<strong>Kein Zugriff:</strong> Der Server und die KI haben keinen Zugang
|
|
zur Zuordnungstabelle und koennen somit keine Re-Identifizierung durchfuehren.
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="highlight-box blue">
|
|
<h4>Rechtliche Einordnung</h4>
|
|
<p>
|
|
Da die KI nur pseudonymisierte Texte ohne jeglichen Personenbezug verarbeitet,
|
|
handelt es sich aus Sicht der KI-Verarbeitung um <strong>anonyme Daten</strong>.
|
|
Die DSGVO gilt nicht fuer anonyme Daten (Erwaegungsgrund 26).
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 3: Data Flow -->
|
|
<div class="doc-section">
|
|
<h3>
|
|
<span class="section-number">3</span>
|
|
Datenfluss und Verarbeitungsschritte
|
|
</h3>
|
|
<div class="doc-content">
|
|
<div class="data-flow-diagram">
|
|
┌─────────────────────────────────────────────────────────────────────────────────┐
|
|
│ DATENFLUSS KLAUSURKORREKTUR │
|
|
├─────────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ LEHRER-GERAET (Browser) SERVER (BreakPilot) │
|
|
│ ──────────────────────── ───────────────────── │
|
|
│ │
|
|
│ 1. Schuelerliste eingeben │
|
|
│ [Max, Anna, Tim, ...] │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 2. Lokale Verschluesselung ─────► Verschluesselte Zuordnung │
|
|
│ (AES-256, Passwort) (Server kann nicht lesen) │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 3. QR-Codes generieren ◄───── Zufaellige doc_tokens │
|
|
│ [abc123..., def456..., ...] (128-bit UUID) │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 4. QR-Bogen drucken │
|
|
│ │ │
|
|
│ ══════════╪══════════════════════════════════════════════════════════════ │
|
|
│ │ (Physisch: Klausur mit QR) │
|
|
│ ══════════╪══════════════════════════════════════════════════════════════ │
|
|
│ │ │
|
|
│ 5. Scan hochladen ─────► 6. QR erkennen │
|
|
│ (Bild der Klausur) │ │
|
|
│ ▼ │
|
|
│ 7. Kopfzeile entfernen │
|
|
│ (Name/Klasse redacted) │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 8. OCR + KI-Korrektur │
|
|
│ (Nur Token + Text) │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 10. Lokal entschluesseln ◄───── 9. Pseudonymisierte Ergebnisse │
|
|
│ + Namen zuordnen [abc123: Note 2+, ...] │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 11. Ergebnis: Max = 2+ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
LEGENDE:
|
|
─────► Verschluesselte oder pseudonymisierte Daten
|
|
═══════ Physischer Medienbruch (Papier)
|
|
Server kann NIEMALS: Schuelernamen sehen, Zuordnung aufloesen, Identitaet bestimmen
|
|
</div>
|
|
|
|
<p><strong>Erklaerung der Schritte:</strong></p>
|
|
<ol>
|
|
<li><strong>Schuelerliste:</strong> Der Lehrer gibt die Namen seiner Schueler ein. Diese verlassen das Geraet nicht.</li>
|
|
<li><strong>Verschluesselung:</strong> Die Zuordnung wird mit dem Passwort des Lehrers verschluesselt (AES-256-GCM).</li>
|
|
<li><strong>QR-Codes:</strong> Fuer jeden Schueler wird ein zufaelliger Token generiert. Kein Zusammenhang zum Namen.</li>
|
|
<li><strong>Drucken:</strong> Der QR-Bogen wird ausgedruckt. Schueler kleben ihren QR auf die Klausur.</li>
|
|
<li><strong>Scan:</strong> Die korrigierten Klausuren werden gescannt.</li>
|
|
<li><strong>QR-Erkennung:</strong> Der QR-Code wird automatisch erkannt, um das Dokument zuzuordnen.</li>
|
|
<li><strong>Redaction:</strong> Die Kopfzeile mit Name/Klasse wird automatisch geschwärzt.</li>
|
|
<li><strong>KI-Korrektur:</strong> Die KI sieht nur den anonymen Text und den Token - niemals einen Namen.</li>
|
|
<li><strong>Ergebnis:</strong> Das Ergebnis wird mit dem Token gespeichert (z.B. "abc123: 85 Punkte").</li>
|
|
<li><strong>Entschluesselung:</strong> Nur der Lehrer kann mit seinem Passwort die Zuordnung wiederherstellen.</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 4: Comparison -->
|
|
<div class="doc-section">
|
|
<h3>
|
|
<span class="section-number">4</span>
|
|
Vergleich mit anderen Loesungen
|
|
</h3>
|
|
<div class="doc-content">
|
|
<table class="comparison-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Kriterium</th>
|
|
<th>BreakPilot (diese Loesung)</th>
|
|
<th>Typische Cloud-KI (z.B. NovaGrade)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>Schuelernamen an Server</td>
|
|
<td class="good">Nein (nur Tokens)</td>
|
|
<td class="bad">Ja</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Schuelernamen an KI</td>
|
|
<td class="good">Nein</td>
|
|
<td class="bad">Ja (OpenAI/Claude API)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Datenspeicherung</td>
|
|
<td class="good">Self-Hosted (SysEleven, Deutschland)</td>
|
|
<td class="bad">US-Cloud (OpenAI, AWS)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Zuordnung abrufbar durch</td>
|
|
<td class="good">Nur Lehrer (verschluesselt)</td>
|
|
<td class="bad">Anbieter, evtl. Dritte</td>
|
|
</tr>
|
|
<tr>
|
|
<td>DSGVO-Risiko</td>
|
|
<td class="good">Minimal (pseudonymisiert)</td>
|
|
<td class="bad">Hoch (personenbezogen)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Vergleichbar mit</td>
|
|
<td class="good">Lokale PC-Korrektur</td>
|
|
<td class="bad">Cloud-Datenuebermittlung</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 5: Technical Security -->
|
|
<div class="doc-section">
|
|
<h3>
|
|
<span class="section-number">5</span>
|
|
Technische Sicherheitsmassnahmen
|
|
</h3>
|
|
<div class="doc-content">
|
|
<div class="tech-specs">
|
|
<h4>Kryptographische Parameter</h4>
|
|
<table>
|
|
<tr><td>Token-Generierung</td><td>UUID v4 (128-bit kryptographisch zufaellig)</td></tr>
|
|
<tr><td>Verschluesselung</td><td>AES-256-GCM (authentifizierte Verschluesselung)</td></tr>
|
|
<tr><td>Schluesselableitung</td><td>PBKDF2-SHA256, 100.000 Iterationen</td></tr>
|
|
<tr><td>Salt</td><td>128-bit zufaellig pro Sitzung</td></tr>
|
|
<tr><td>IV (Initialisierungsvektor)</td><td>96-bit zufaellig pro Verschluesselung</td></tr>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="tech-specs">
|
|
<h4>Infrastruktur</h4>
|
|
<table>
|
|
<tr><td>LLM-Hosting</td><td>SysEleven, Berlin (DE)</td></tr>
|
|
<tr><td>Datenbank</td><td>PostgreSQL mit Verschluesselung at rest</td></tr>
|
|
<tr><td>Netzwerk</td><td>TLS 1.3, kein Datenverkehr zu US-Servern</td></tr>
|
|
<tr><td>Datenloeschung</td><td>Automatisch nach 30 Tagen</td></tr>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="tech-specs">
|
|
<h4>Zugangskontrolle</h4>
|
|
<table>
|
|
<tr><td>Lehrer-Isolation</td><td>Strikte Mandantentrennung (teacher_id Filter)</td></tr>
|
|
<tr><td>Kein Admin-Zugriff auf Zuordnung</td><td>Zero-Knowledge-Design</td></tr>
|
|
<tr><td>Audit-Log</td><td>Alle Zugriffe protokolliert (ohne PII)</td></tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 6: Risk Assessment -->
|
|
<div class="doc-section">
|
|
<h3>
|
|
<span class="section-number">6</span>
|
|
Risikobewertung
|
|
</h3>
|
|
<div class="doc-content">
|
|
<p><strong>Potenzielle Risiken und Gegenmassnahmen:</strong></p>
|
|
|
|
<table class="comparison-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Risiko</th>
|
|
<th>Bewertung</th>
|
|
<th>Gegenmassnahme</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>Re-Identifizierung durch Server</td>
|
|
<td class="good">Technisch unmoeglich</td>
|
|
<td>Server hat keinen Zugang zur Zuordnung (Zero-Knowledge)</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Datenverlust</td>
|
|
<td class="good">Kein Personenbezug</td>
|
|
<td>Gestohlene Daten enthalten nur Tokens, keine Namen</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Passwort-Verlust durch Lehrer</td>
|
|
<td style="color: #fbbf24;">Mittel</td>
|
|
<td>Lokale Backup-Kopie im Browser (localStorage), Neustart moeglich</td>
|
|
</tr>
|
|
<tr>
|
|
<td>KI-Halluzination</td>
|
|
<td class="good">Kein Datenschutzrisiko</td>
|
|
<td>Lehrer prueft und korrigiert Ergebnisse manuell</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="highlight-box yellow">
|
|
<h4>Wichtiger Hinweis</h4>
|
|
<p>
|
|
Bei Verlust des Vault-Passworts kann die Zuordnung Token → Name nicht wiederhergestellt werden.
|
|
Die Lehrkraft sollte das Passwort sicher aufbewahren oder eine lokale Sicherung erstellen.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 7: Conclusion -->
|
|
<div class="doc-section">
|
|
<h3>
|
|
<span class="section-number">7</span>
|
|
Fazit und Empfehlung
|
|
</h3>
|
|
<div class="doc-content">
|
|
<div class="highlight-box green">
|
|
<h4>Bewertung: Datenschutzkonform</h4>
|
|
<p>
|
|
Die Klausurkorrektur mit BreakPilot ist <strong>vergleichbar mit einer lokalen Verarbeitung
|
|
auf dem PC der Lehrkraft</strong>. Personenbezogene Daten verlassen das Geraet der Lehrkraft
|
|
nicht. Die KI-Verarbeitung erfolgt ausschliesslich auf pseudonymisierten Daten.
|
|
</p>
|
|
<ul>
|
|
<li>Keine Uebermittlung personenbezogener Daten an Dritte</li>
|
|
<li>Kein US-Cloud-Transfer (Schrems II konform)</li>
|
|
<li>Volle Kontrolle der Lehrkraft ueber die Identitaets-Zuordnung</li>
|
|
<li>Automatische Datenloeschung nach 30 Tagen</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<p>
|
|
<strong>Empfehlung:</strong> Das System kann ohne zusaetzliche Genehmigung oder
|
|
Datenschutz-Folgenabschaetzung (DSFA) eingesetzt werden, da keine hohen Risiken
|
|
fuer die Rechte und Freiheiten der Betroffenen bestehen.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Version Info -->
|
|
<div style="margin-top: 32px; padding-top: 16px; border-top: 1px solid var(--bp-border); color: var(--bp-text-muted); font-size: 12px;">
|
|
<p>
|
|
<strong>Dokumentversion:</strong> 1.0 |
|
|
<strong>Stand:</strong> <span id="doc-date"></span> |
|
|
<strong>System:</strong> BreakPilot Klausurkorrektur |
|
|
<strong>Kontakt:</strong> datenschutz@breakpilot.de
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Set current date
|
|
document.getElementById('doc-date').textContent = new Date().toLocaleDateString('de-DE');
|
|
</script>
|
|
"""
|
|
|
|
|
|
def get_admin_klausur_docs_js() -> str:
|
|
"""JavaScript for Klausur Documentation Panel."""
|
|
return """
|
|
// Klausur Documentation Panel
|
|
// No interactive JS needed - documentation is static
|
|
// Print functionality uses native window.print()
|
|
|
|
console.log('Klausur Documentation loaded - Audit-ready version');
|
|
"""
|