import { DevPortalLayout, CodeBlock, InfoBox } from '@/components/DevPortalLayout'

export default function BYOEHDocsPage() {
  return (
    <DevPortalLayout
      title="Wie funktioniert das Klausur-Namespace-System?"
      description="Eine umfassende Erklaerung des BYOEH-Systems -- von der Anonymisierung bis zur sicheren KI-Korrektur."
    >
      {/* ============================================================ */}
      {/* 1. EINLEITUNG                                                 */}
      {/* ============================================================ */}
      <h2 id="einfuehrung">1. Was ist das Namespace-System?</h2>
      <p>
        Das <strong>BYOEH-System</strong> (Bring Your Own Expectation Horizon) ist eine
        Datenschutz-Architektur, die es Lehrern ermoeglicht, Klausuren <strong>anonym und
        verschluesselt</strong> von einer KI korrigieren zu lassen -- ohne dass jemals der Name
        eines Schuelers den Rechner des Lehrers verlaesst.
      </p>
      <blockquote>
        <em>&ldquo;Die Klausuren gehen anonym in die Cloud, werden dort von KI korrigiert,
        und kommen korrigiert zurueck. Nur der Lehrer kann die Ergebnisse wieder den
        Schuelern zuordnen -- denn nur seine Hardware hat den Schluessel dafuer.&rdquo;</em>
      </blockquote>
      <p>
        Das System loest ein grundlegendes Problem: Klausurkorrektur mit KI-Unterstuetzung
        <strong> ohne Datenschutzrisiko</strong>. Die Loesung besteht aus vier Bausteinen:
      </p>
      <ol>
        <li>
          <strong>Pseudonymisierung:</strong> Namen werden durch zufaellige Codes ersetzt.
          Niemand ausser dem Lehrer kennt die Zuordnung.
        </li>
        <li>
          <strong>Verschluesselung:</strong> Alles wird <em>im Browser des Lehrers</em>
          verschluesselt, bevor es den Rechner verlaesst. Der Server sieht nur unlesbaren
          Datensalat.
        </li>
        <li>
          <strong>Namespace-Isolation:</strong> Jeder Lehrer hat einen eigenen, abgeschotteten
          Bereich (Namespace). Kein Lehrer kann auf die Daten eines anderen zugreifen.
        </li>
        <li>
          <strong>KI-Korrektur:</strong> Die KI arbeitet mit den verschluesselten Daten
          und dem Erwartungshorizont (EH) des Lehrers. Korrekturvorschlaege gehen zurueck
          an den Lehrer.
        </li>
      </ol>

      <InfoBox type="info" title="Kern-Designprinzip: Operator Blindness">
        <strong>Breakpilot kann die Klausuren nicht lesen.</strong> Der Server sieht nur
        verschluesselte Daten und einen Schluessel-Hash (nicht den Schluessel selbst). Die
        Passphrase zum Entschluesseln existiert <em>nur</em> im Browser des Lehrers und
        wird niemals uebertragen. Selbst ein Angriff auf den Server wuerde keine
        Klausurtexte preisgeben.
      </InfoBox>

      {/* ============================================================ */}
      {/* 2. DER KOMPLETTE ABLAUF                                      */}
      {/* ============================================================ */}
      <h2 id="ablauf">2. Der komplette Ablauf im Ueberblick</h2>
      <p>
        Der Prozess laesst sich in sieben Schritte unterteilen. Stellen Sie sich vor, der
        Lehrer sitzt an seinem Rechner und hat einen Stapel gescannter Klausuren:
      </p>

      <CodeBlock language="text" filename="Der komplette Workflow: Von der Klausur zur KI-Korrektur">
{`SCHRITT 1: KLAUSUREN SCANNEN & HOCHLADEN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Lehrer scannt Klausuren ein (PDF oder Bild)
  → System erkennt automatisch den Kopfbereich mit Namen
  → Kopfbereich wird permanent entfernt (Header-Redaction)
  → Jede Klausur erhaelt einen zufaelligen Code (doc_token)

SCHRITT 2: VERSCHLUESSELUNG IM BROWSER
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Lehrer gibt eine Passphrase ein (z.B. "MeinGeheimesPasswort2025!")
  → Browser leitet daraus einen 256-Bit-Schluessel ab (PBKDF2)
  → Klausur wird mit AES-256-GCM verschluesselt
  → Nur der Hash des Schluessels wird an den Server gesendet
  → Passphrase und Schluessel verlassen NIEMALS den Browser

SCHRITT 3: IDENTITAETS-MAP SICHERN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Die Zuordnung "doc_token → Schuelername" wird verschluesselt:
  → Tabelle: "a7f3c2d1... = Max Mustermann, b9e4a1f8... = Anna Schmidt"
  → Diese Tabelle wird mit dem gleichen Schluessel verschluesselt
  → Ohne Passphrase kann niemand die Zuordnung wiederherstellen

SCHRITT 4: UPLOAD IN DEN NAMESPACE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Die verschluesselten Dateien gehen in den persoenlichen Namespace:
  → Jeder Lehrer hat eine eigene tenant_id
  → Daten werden in MinIO (verschluesselt) + Qdrant (Vektoren) gespeichert
  → Server sieht: verschluesselter Blob + Schluessel-Hash + Salt

SCHRITT 5: KI-KORREKTUR
━━━━━━━━━━━━━━━━━━━━━━━
Der Lehrer startet die KI-Korrektur:
  → RAG-System durchsucht den Erwartungshorizont (EH)
  → KI generiert Korrekturvorschlaege pro Kriterium
  → Vorschlaege basieren auf dem EH, nicht auf Halluzinationen

SCHRITT 6: ERGEBNISSE ZURUECK
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Korrekturvorschlaege gehen an den Lehrer:
  → Lehrer gibt Passphrase ein
  → Browser entschluesselt die Ergebnisse
  → Lehrer sieht: Vorschlaege pro Kriterium + Gesamtnote

SCHRITT 7: ZUORDNUNG & FINALISIERUNG
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Lehrer ordnet Ergebnisse den Schuelern zu:
  → Identitaets-Map wird entschluesselt
  → doc_token wird wieder dem echten Namen zugeordnet
  → Lehrer ueberprueft/korrigiert KI-Vorschlaege
  → Fertige Korrektur + Gutachten koennen exportiert werden`}
      </CodeBlock>

      {/* ============================================================ */}
      {/* 3. PSEUDONYMISIERUNG                                         */}
      {/* ============================================================ */}
      <h2 id="pseudonymisierung">3. Pseudonymisierung: Wie Namen verschwinden</h2>
      <p>
        Pseudonymisierung bedeutet: personenbezogene Daten werden durch <strong>zufaellige
        Codes</strong> ersetzt, sodass ohne Zusatzinformation kein Rueckschluss auf die Person
        moeglich ist. Im BYOEH-System passiert das auf zwei Ebenen:
      </p>

      <h3>3.1 Der doc_token: Ein zufaelliger Ausweis</h3>
      <p>
        Jede Klausur erhaelt einen <strong>doc_token</strong> -- einen 128-Bit-Zufallscode im
        UUID4-Format (z.B. <code>a7f3c2d1-4e9b-4a5f-8c7d-6b2e1f0a9d3c</code>). Dieser Code:
      </p>
      <ul>
        <li>Ist <strong>kryptographisch zufaellig</strong> -- es gibt keinen Zusammenhang zwischen
          Token und Schueler</li>
        <li>Kann <strong>nicht zurueckgerechnet</strong> werden -- auch mit Kenntnis des Algorithmus
          ist kein Rueckschluss moeglich</li>
        <li>Wird <strong>auf der Klausur aufgedruckt</strong> (als QR-Code), damit die physische
          Klausur spaeter wieder zugeordnet werden kann</li>
      </ul>

      <h3>3.2 Header-Redaction: Der Name wird entfernt</h3>
      <p>
        Bevor eine Klausur verarbeitet wird, entfernt das System den <strong>Kopfbereich</strong>
        der gescannten Seite -- dort, wo typischerweise Name, Klasse und Datum stehen. Diese
        Entfernung ist <strong>permanent</strong>: Die Originaldaten werden nicht gespeichert.
      </p>

      <div className="not-prose my-6 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Methode</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Wie es funktioniert</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Wann verwendet</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr>
              <td className="px-4 py-3 font-medium">Einfache Redaction</td>
              <td className="px-4 py-3">Obere ~2,5 cm der Seite werden weiss ueberschrieben</td>
              <td className="px-4 py-3">Standard bei allen Uploads</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Smarte Redaction</td>
              <td className="px-4 py-3">OpenCV erkennt Textbereiche und entfernt gezielt den Kopf, verschont aber QR-Codes</td>
              <td className="px-4 py-3">Wenn QR-Codes auf der Klausur sind</td>
            </tr>
          </tbody>
        </table>
      </div>

      <h3>3.3 Die Identitaets-Map: Nur der Lehrer kennt die Zuordnung</h3>
      <p>
        Die Zuordnung <em>doc_token → Schuelername</em> wird als <strong>verschluesselte Tabelle</strong>
        gespeichert. Das Datenbankmodell sieht so aus:
      </p>

      <CodeBlock language="text" filename="Datenbank: ExamSession (vereinfacht)">
{`ExamSession
├── teacher_id            = "lehrer-uuid-123"     ← Pflichtfeld (Isolation)
├── encrypted_identity_map = [verschluesselte Bytes]  ← Nur mit Passphrase lesbar
├── identity_map_iv       = "a3f2c1..."           ← Initialisierungsvektor (fuer AES)
│
└── PseudonymizedDocument (pro Klausur)
    ├── doc_token          = "a7f3c2d1-..."       ← Zufaelliger Code (Primary Key)
    ├── exam_session_id    = [Referenz]
    └── (Kein Name, keine Klasse, kein persoenliches Datum)`}
      </CodeBlock>

      <InfoBox type="success" title="DSGVO Art. 4 Nr. 5 konform">
        Die Pseudonymisierung erfuellt die Definition aus der DSGVO: Die personenbezogenen Daten
        (Schuelernamen) koennen <strong>ohne Hinzuziehung zusaetzlicher Informationen</strong>
        (der verschluesselten Identitaets-Map + der Passphrase des Lehrers) nicht mehr einer
        bestimmten Person zugeordnet werden.
      </InfoBox>

      {/* ============================================================ */}
      {/* 4. VERSCHLUESSELUNG                                          */}
      {/* ============================================================ */}
      <h2 id="verschluesselung">4. Verschluesselung: Wie Daten geschuetzt werden</h2>
      <p>
        Die Verschluesselung ist das Herzsstueck des Datenschutzes. Sie findet <strong>vollstaendig
        im Browser</strong> statt -- der Server bekommt nur verschluesselte Daten zu sehen.
      </p>

      <h3>4.1 Der Verschluesselungsvorgang</h3>
      <p>
        Wenn der Lehrer eine Klausur oder einen Erwartungshorizont hochlaedt, passiert im
        Browser folgendes:
      </p>

      <CodeBlock language="text" filename="Client-seitige Verschluesselung (im Browser)">
{`┌─────────────────────────────────────────────────────────────────┐
│                    Browser des Lehrers                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. Lehrer gibt Passphrase ein (z.B. "MeinGeheimesPasswort!")   │
│     │           ↑                                               │
│     │           │ Passphrase bleibt hier -- wird NIE gesendet   │
│     ▼                                                           │
│  2. Schluessel-Ableitung:                                       │
│     PBKDF2-SHA256(Passphrase, zufaelliger Salt, 100.000 Runden) │
│     │                                                           │
│     │  → Ergebnis: 256-Bit-Schluessel (32 Bytes)                │
│     │  → Selbst bei Kenntnis des Salts sind 100.000 Runden      │
│     │    noetig, um den Schluessel zu erraten                    │
│     ▼                                                           │
│  3. Verschluesselung:                                           │
│     AES-256-GCM(Schluessel, zufaelliger IV, Datei-Inhalt)       │
│     │                                                           │
│     │  → AES-256: Militaerstandard, 2^256 moegliche Schluessel  │
│     │  → GCM: Garantiert Integritaet (Manipulation erkennbar)   │
│     ▼                                                           │
│  4. Schluessel-Hash:                                            │
│     SHA-256(abgeleiteter Schluessel) → Hash fuer Verifikation   │
│     │                                                           │
│     │  → Der Server speichert nur diesen Hash                   │
│     │  → Damit kann geprueft werden ob die Passphrase stimmt    │
│     │  → Vom Hash kann der Schluessel NICHT zurueckgerechnet    │
│     │    werden                                                 │
│     ▼                                                           │
│  5. Upload: Nur diese Daten gehen an den Server:                │
│     • Verschluesselter Blob (unlesbar ohne Schluessel)          │
│     • Salt (zufaellige Bytes, harmlos)                          │
│     • IV (Initialisierungsvektor, harmlos)                      │
│     • Schluessel-Hash (zur Verifikation, nicht umkehrbar)       │
│                                                                 │
│     Was NICHT an den Server geht:                               │
│     ✗ Passphrase                                                │
│     ✗ Abgeleiteter Schluessel                                   │
│     ✗ Unverschluesselter Klartext                               │
└─────────────────────────────────────────────────────────────────┘`}
      </CodeBlock>

      <h3>4.2 Warum ist das sicher?</h3>
      <div className="not-prose my-6 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Angriffsszenario</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Was der Angreifer sieht</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Ergebnis</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr>
              <td className="px-4 py-3 font-medium">Server wird gehackt</td>
              <td className="px-4 py-3">Verschluesselte Blobs + Hashes</td>
              <td className="px-4 py-3 text-green-700 font-medium">Keine lesbaren Klausuren</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Datenbank wird geleakt</td>
              <td className="px-4 py-3">encrypted_identity_map (verschluesselt)</td>
              <td className="px-4 py-3 text-green-700 font-medium">Keine Schuelernamen</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Netzwerkverkehr abgefangen</td>
              <td className="px-4 py-3">Verschluesselte Daten (HTTPS + AES)</td>
              <td className="px-4 py-3 text-green-700 font-medium">Doppelt verschluesselt</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Betreiber (Breakpilot) will mitlesen</td>
              <td className="px-4 py-3">Verschluesselte Blobs, kein Schluessel</td>
              <td className="px-4 py-3 text-green-700 font-medium">Operator Blindness</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Anderer Lehrer versucht Zugriff</td>
              <td className="px-4 py-3">Nichts (Tenant-Isolation)</td>
              <td className="px-4 py-3 text-green-700 font-medium">Namespace blockiert</td>
            </tr>
          </tbody>
        </table>
      </div>

      {/* ============================================================ */}
      {/* 5. NAMESPACE / TENANT-ISOLATION                              */}
      {/* ============================================================ */}
      <h2 id="namespace">5. Namespace-Isolation: Jeder Lehrer hat seinen eigenen Bereich</h2>
      <p>
        Ein <strong>Namespace</strong> (auch &ldquo;Tenant&rdquo; genannt) ist ein abgeschotteter
        Bereich im System. Man kann es sich wie <strong>separate Schliessfaecher</strong> in einer
        Bank vorstellen: Jeder Lehrer hat sein eigenes Fach, und kein Schluessel passt in ein
        anderes Fach.
      </p>

      <h3>5.1 Wie die Isolation funktioniert</h3>
      <p>
        Jeder Lehrer erhaelt beim ersten Login eine eindeutige <code>tenant_id</code>. Diese ID wird
        bei <strong>jeder einzelnen Datenbankabfrage</strong> als Pflichtfilter mitgefuehrt:
      </p>

      <CodeBlock language="text" filename="Tenant-Isolation in der Vektordatenbank (Qdrant)">
{`Lehrer A (tenant_id: "school-A-lehrer-1")
├── Klausur 1 (verschluesselt)
├── Klausur 2 (verschluesselt)
└── Erwartungshorizont Deutsch LK 2025

Lehrer B (tenant_id: "school-B-lehrer-2")
├── Klausur 1 (verschluesselt)
└── Erwartungshorizont Mathe GK 2025

Suchanfrage von Lehrer A:
  "Wie soll die Einleitung strukturiert sein?"
  → Suche NUR in tenant_id = "school-A-lehrer-1"
  → Lehrer B's Daten sind UNSICHTBAR

Jede Qdrant-Query hat diesen Pflichtfilter:
  must_conditions = [
    FieldCondition(key="tenant_id", match="school-A-lehrer-1")
  ]

Es gibt KEINE Abfrage ohne tenant_id-Filter.`}
      </CodeBlock>

      <h3>5.2 Drei Ebenen der Isolation</h3>
      <div className="not-prose my-6 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Ebene</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">System</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Isolation</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr>
              <td className="px-4 py-3 font-medium">Dateisystem</td>
              <td className="px-4 py-3">MinIO (S3-Storage)</td>
              <td className="px-4 py-3">Eigener Ordner pro Lehrer: <code>/tenant-id/eh-id/encrypted.bin</code></td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Vektordatenbank</td>
              <td className="px-4 py-3">Qdrant</td>
              <td className="px-4 py-3">Pflichtfilter <code>tenant_id</code> bei jeder Suche</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Metadaten-DB</td>
              <td className="px-4 py-3">PostgreSQL</td>
              <td className="px-4 py-3">Jede Tabelle hat <code>teacher_id</code> als Pflichtfeld</td>
            </tr>
          </tbody>
        </table>
      </div>

      <InfoBox type="warning" title="Kein Training mit Lehrerdaten">
        Auf allen Vektoren in Qdrant ist das Flag <code>training_allowed: false</code> gesetzt.
        Das bedeutet: Die Inhalte der Lehrer werden <strong>ausschliesslich fuer RAG-Suchen</strong>
        (Abruf relevanter Textpassagen) verwendet und <strong>niemals zum Trainieren</strong> eines
        KI-Modells eingesetzt.
      </InfoBox>

      {/* ============================================================ */}
      {/* 6. DER ERWARTUNGSHORIZONT (EH)                               */}
      {/* ============================================================ */}
      <h2 id="erwartungshorizont">6. Der Erwartungshorizont: Die Grundlage fuer KI-Korrektur</h2>
      <p>
        Ein <strong>Erwartungshorizont</strong> (EH) ist das Dokument, das beschreibt, was in
        einer Klausur erwartet wird: welche Inhalte in welcher Qualitaet vorkommen sollen.
        Im BYOEH-System laedt der Lehrer seinen eigenen EH hoch, und die KI nutzt ihn als
        Referenz fuer Korrekturvorschlaege.
      </p>

      <h3>6.1 Upload-Wizard (5 Schritte)</h3>
      <div className="not-prose my-4 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Schritt</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Was passiert</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Warum</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr><td className="px-4 py-3 font-medium">1. Datei waehlen</td><td className="px-4 py-3">PDF per Drag &amp; Drop hochladen</td><td className="px-4 py-3">Der EH als digitales Dokument</td></tr>
            <tr><td className="px-4 py-3 font-medium">2. Metadaten</td><td className="px-4 py-3">Titel, Fach, Niveau (eA/gA), Jahr</td><td className="px-4 py-3">Fuer Filterung und Organisation</td></tr>
            <tr><td className="px-4 py-3 font-medium">3. Rechtebestaetigung</td><td className="px-4 py-3">Checkbox: &ldquo;Ich bin berechtigt&rdquo;</td><td className="px-4 py-3">Rechtliche Absicherung (Urheberrecht)</td></tr>
            <tr><td className="px-4 py-3 font-medium">4. Verschluesselung</td><td className="px-4 py-3">Passphrase eingeben (2x bestaetigen)</td><td className="px-4 py-3">Schluessel fuer Ende-zu-Ende-Verschluesselung</td></tr>
            <tr><td className="px-4 py-3 font-medium">5. Zusammenfassung</td><td className="px-4 py-3">Pruefen und bestaetigen</td><td className="px-4 py-3">Letzte Kontrolle vor dem Upload</td></tr>
          </tbody>
        </table>
      </div>

      <h3>6.2 RAG-Pipeline: Wie der EH fuer die KI nutzbar wird</h3>
      <p>
        Nach dem Upload wird der EH fuer die KI-Suche vorbereitet. Dieser Vorgang heisst
        <strong> Indexierung</strong> und funktioniert wie das Erstellen eines Stichwortverzeichnisses
        fuer ein Buch:
      </p>

      <CodeBlock language="text" filename="Indexierung: Vom PDF zum durchsuchbaren EH">
{`Erwartungshorizont (verschluesselt auf Server)
     |
     v
┌────────────────────────────────┐
│  1. Passphrase-Verifikation    │  ← Lehrer gibt Passphrase ein
│     Hash pruefen               │     Server vergleicht mit gespeichertem Hash
└──────────┬─────────────────────┘
           |
           v
┌────────────────────────────────┐
│  2. Entschluesselung           │  ← Temporaer im Arbeitsspeicher
│     AES-256-GCM Decrypt        │     (wird nach Verarbeitung geloescht)
└──────────┬─────────────────────┘
           |
           v
┌────────────────────────────────┐
│  3. Text-Extraktion            │  ← PDF → Klartext
│     Tabellen, Listen erkennen  │
└──────────┬─────────────────────┘
           |
           v
┌────────────────────────────────┐
│  4. Chunking                   │  ← Text in 1.000-Zeichen-Abschnitte zerlegen
│     Ueberlappung: 200 Zeichen  │     (mit Ueberlappung, damit kein Kontext
│                                │      verloren geht)
└──────────┬─────────────────────┘
           |
           v
┌────────────────────────────────┐
│  5. Embedding                  │  ← Jeder Abschnitt wird in einen
│     Text → 1.536 Zahlen        │     Bedeutungsvektor umgewandelt
└──────────┬─────────────────────┘
           |
           v
┌────────────────────────────────┐
│  6. Re-Encryption              │  ← Jeder Chunk wird ERNEUT verschluesselt
│     AES-256-GCM pro Chunk      │     bevor er gespeichert wird
└──────────┬─────────────────────┘
           |
           v
┌────────────────────────────────┐
│  7. Qdrant-Indexierung          │  ← Vektor + verschluesselter Chunk
│     tenant_id: "lehrer-123"    │     werden mit Tenant-Filter gespeichert
│     training_allowed: false    │
└────────────────────────────────┘`}
      </CodeBlock>

      <h3>6.3 Wie die KI den EH nutzt (RAG-Query)</h3>
      <p>
        Wenn der Lehrer bei der Korrektur einen Vorschlag anfordert, passiert folgendes:
      </p>
      <ol>
        <li>
          <strong>Frage formulieren:</strong> Das System erstellt eine Suchanfrage aus dem
          Klausurtext und dem aktuellen Bewertungskriterium (z.B. &ldquo;Wie gut ist die
          Einleitung im Vergleich zum Erwartungshorizont?&rdquo;).
        </li>
        <li>
          <strong>Semantische Suche:</strong> Die Anfrage wird in einen Vektor umgewandelt und
          gegen die EH-Vektoren in Qdrant gesucht -- <em>nur im Namespace des Lehrers</em>.
        </li>
        <li>
          <strong>Entschluesselung:</strong> Die gefundenen Chunks werden mit der Passphrase
          des Lehrers entschluesselt.
        </li>
        <li>
          <strong>KI-Antwort:</strong> Die entschluesselten EH-Passagen werden als Kontext
          an die KI uebergeben, die daraus einen Korrekturvorschlag generiert.
        </li>
      </ol>

      {/* ============================================================ */}
      {/* 7. KEY SHARING                                               */}
      {/* ============================================================ */}
      <h2 id="key-sharing">7. Key Sharing: Zweitkorrektur ermoeglichen</h2>
      <p>
        Bei Abiturklausuren muss eine <strong>Zweitkorrektur</strong> durch einen anderen Lehrer
        erfolgen. Das Key-Sharing-System ermoeglicht es dem Erstpruefer, seinen Erwartungshorizont
        sicher mit dem Zweitpruefer zu teilen -- ohne die Verschluesselung aufzugeben.
      </p>

      <h3>7.1 Einladungs-Workflow</h3>
      <CodeBlock language="text" filename="Key Sharing: Sicheres Teilen zwischen Pruefern">
{`Erstpruefer                        Server                     Zweitpruefer
     │                                │                             │
     │  1. Einladung senden            │                             │
     │     (E-Mail + Rolle + Klausur)  │                             │
     │─────────────────────────────────▶                             │
     │                                │                             │
     │                                │  2. Einladung erstellt       │
     │                                │     (14 Tage gueltig)        │
     │                                │                             │
     │                                │  3. Benachrichtigung ──────▶│
     │                                │                             │
     │                                │                      4. Einladung annehmen
     │                                │◀─────────────────────────────│
     │                                │                             │
     │                                │  5. Key-Share erstellt       │
     │                                │     (verschluesselte         │
     │                                │      Passphrase)             │
     │                                │                             │
     │                                │  6. Zweitpruefer kann ──────▶│
     │                                │     jetzt RAG-Queries        │
     │                                │     ausfuehren               │
     │                                │                             │
     │  7. Zugriff widerrufen          │                             │
     │     (jederzeit moeglich)       │                             │
     │─────────────────────────────────▶                             │
     │                                │  Share deaktiviert           │`}
      </CodeBlock>

      <h3>7.2 Rollen beim Key-Sharing</h3>
      <div className="not-prose my-4 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Rolle</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Wer</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Rechte</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr><td className="px-4 py-3 font-medium">Erstpruefer (EK)</td><td className="px-4 py-3">Kurslehrer</td><td className="px-4 py-3">Vollzugriff, kann teilen &amp; widerrufen</td></tr>
            <tr><td className="px-4 py-3 font-medium">Zweitpruefer (ZK)</td><td className="px-4 py-3">Anderer Fachlehrer</td><td className="px-4 py-3">Nur Lesen, RAG-Queries, eigene Annotations</td></tr>
            <tr><td className="px-4 py-3 font-medium">Drittpruefer (DK)</td><td className="px-4 py-3">Bei Differenz &ge; 4 Punkte</td><td className="px-4 py-3">Nur Lesen, RAG-Queries</td></tr>
            <tr><td className="px-4 py-3 font-medium">Fachvorsitz</td><td className="px-4 py-3">Fachbereichsleitung</td><td className="px-4 py-3">Nur Lesen (Aufsichtsfunktion)</td></tr>
          </tbody>
        </table>
      </div>

      {/* ============================================================ */}
      {/* 8. BEWERTUNGSKRITERIEN                                       */}
      {/* ============================================================ */}
      <h2 id="bewertung">8. KI-gestuetzte Bewertung: Wie die Korrektur funktioniert</h2>
      <p>
        Die KI bewertet jede Klausur anhand von <strong>fuenf Kriterien</strong>, die
        zusammen 100% ergeben:
      </p>
      <div className="not-prose my-6 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Kriterium</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Gewichtung</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Was geprueft wird</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr><td className="px-4 py-3 font-medium">Rechtschreibung</td><td className="px-4 py-3">15%</td><td className="px-4 py-3">Orthographie, Zeichensetzung</td></tr>
            <tr><td className="px-4 py-3 font-medium">Grammatik</td><td className="px-4 py-3">15%</td><td className="px-4 py-3">Satzbau, Kongruenz, Tempus</td></tr>
            <tr className="bg-blue-50"><td className="px-4 py-3 font-bold text-blue-800">Inhalt</td><td className="px-4 py-3 font-bold text-blue-800">40%</td><td className="px-4 py-3">Bezug zum EH, Vollstaendigkeit, Argumentation</td></tr>
            <tr><td className="px-4 py-3 font-medium">Struktur</td><td className="px-4 py-3">15%</td><td className="px-4 py-3">Gliederung, Einleitung/Schluss, roter Faden</td></tr>
            <tr><td className="px-4 py-3 font-medium">Stil</td><td className="px-4 py-3">15%</td><td className="px-4 py-3">Ausdruck, Wortwahl, Fachsprache</td></tr>
          </tbody>
        </table>
      </div>

      <p>
        Die Bewertung folgt dem <strong>15-Punkte-System</strong> (0-15 Notenpunkte),
        das fuer die gymnasiale Oberstufe gilt. Aus den Teilbewertungen wird automatisch
        eine Gesamtnote berechnet.
      </p>

      <InfoBox type="info" title="KI schlaegt vor, Lehrer entscheidet">
        Alle KI-Bewertungen sind <strong>Vorschlaege</strong>. Der Lehrer hat bei jedem
        Kriterium die volle Kontrolle: Er kann den Vorschlag annehmen, aendern oder
        komplett ueberschreiben. Die finale Note setzt immer der Lehrer.
      </InfoBox>

      {/* ============================================================ */}
      {/* 9. AUDIT-TRAIL                                               */}
      {/* ============================================================ */}
      <h2 id="audit">9. Audit-Trail: Alles wird protokolliert</h2>
      <p>
        Jede Aktion im System wird revisionssicher im <strong>Audit-Log</strong> gespeichert.
        Das ist wichtig fuer die Nachvollziehbarkeit und fuer den Fall, dass Schueler oder
        Eltern eine Korrektur anfechten.
      </p>

      <div className="not-prose my-4 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Aktion</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Was protokolliert wird</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr><td className="px-4 py-3 font-medium">upload</td><td className="px-4 py-3">EH hochgeladen (Dateigroesse, Metadaten, Zeitstempel)</td></tr>
            <tr><td className="px-4 py-3 font-medium">index</td><td className="px-4 py-3">EH fuer RAG indexiert (Anzahl Chunks, Dauer)</td></tr>
            <tr><td className="px-4 py-3 font-medium">rag_query</td><td className="px-4 py-3">RAG-Suchanfrage ausgefuehrt (Query-Hash, Anzahl Ergebnisse, Score)</td></tr>
            <tr><td className="px-4 py-3 font-medium">share</td><td className="px-4 py-3">EH mit anderem Pruefer geteilt (Empfaenger, Rolle)</td></tr>
            <tr><td className="px-4 py-3 font-medium">revoke_share</td><td className="px-4 py-3">Zugriff widerrufen (wer, wann)</td></tr>
            <tr><td className="px-4 py-3 font-medium">link_klausur</td><td className="px-4 py-3">EH mit Klausur verknuepft</td></tr>
            <tr><td className="px-4 py-3 font-medium">delete</td><td className="px-4 py-3">EH geloescht (Soft Delete, bleibt in Logs)</td></tr>
          </tbody>
        </table>
      </div>

      {/* ============================================================ */}
      {/* 10. API-ENDPUNKTE                                            */}
      {/* ============================================================ */}
      <h2 id="api">10. API-Endpunkte (Technische Referenz)</h2>
      <p>
        Alle Endpunkte laufen ueber den <strong>klausur-service</strong> auf Port 8086.
        Authentifizierung erfolgt ueber JWT-Token.
      </p>

      <h3>10.1 Erwartungshorizont-Verwaltung</h3>
      <div className="not-prose my-4 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Methode</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Endpunkt</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Beschreibung</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/upload</td><td className="px-4 py-3">Verschluesselten EH hochladen</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh</td><td className="px-4 py-3">Eigene EHs auflisten</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/{'{id}'}</td><td className="px-4 py-3">Einzelnen EH abrufen</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-red-100 text-red-800 text-xs font-bold">DELETE</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/{'{id}'}</td><td className="px-4 py-3">EH loeschen (Soft Delete)</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/{'{id}'}/index</td><td className="px-4 py-3">EH fuer RAG indexieren</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/rag-query</td><td className="px-4 py-3">RAG-Suchanfrage ausfuehren</td></tr>
          </tbody>
        </table>
      </div>

      <h3>10.2 Key Sharing</h3>
      <div className="not-prose my-4 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Methode</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Endpunkt</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Beschreibung</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/{'{id}'}/share</td><td className="px-4 py-3">EH mit Pruefer teilen</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/{'{id}'}/shares</td><td className="px-4 py-3">Geteilte Zugriffe auflisten</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-red-100 text-red-800 text-xs font-bold">DELETE</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/{'{id}'}/shares/{'{shareId}'}</td><td className="px-4 py-3">Zugriff widerrufen</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/shared-with-me</td><td className="px-4 py-3">Mit mir geteilte EHs</td></tr>
          </tbody>
        </table>
      </div>

      <h3>10.3 Klausur-Integration</h3>
      <div className="not-prose my-4 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Methode</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Endpunkt</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Beschreibung</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/{'{id}'}/link-klausur</td><td className="px-4 py-3">EH mit Klausur verknuepfen</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-red-100 text-red-800 text-xs font-bold">DELETE</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/eh/{'{id}'}/link-klausur/{'{klausurId}'}</td><td className="px-4 py-3">Verknuepfung loesen</td></tr>
            <tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/klausuren/{'{id}'}/linked-eh</td><td className="px-4 py-3">Verknuepften EH abrufen</td></tr>
          </tbody>
        </table>
      </div>

      {/* ============================================================ */}
      {/* 11. DATEISTRUKTUR                                            */}
      {/* ============================================================ */}
      <h2 id="dateien">11. Dateistruktur im Code</h2>

      <CodeBlock language="text" filename="Relevante Dateien im Repository">
{`klausur-service/
├── backend/
│   ├── main.py                 # API-Endpunkte + Datenmodelle
│   ├── qdrant_service.py       # Vektordatenbank-Operationen (Tenant-Filter)
│   └── eh_pipeline.py          # Chunking, Embedding, Verschluesselung
│
├── frontend/
│   └── src/
│       ├── components/
│       │   └── EHUploadWizard.tsx    # 5-Schritt-Upload-Wizard
│       └── services/
│           ├── api.ts                # API-Client
│           └── encryption.ts         # Client-seitige Kryptographie
│
└── docs/
    ├── BYOEH-Architecture.md         # Technische Architektur
    └── BYOEH-Developer-Guide.md      # Entwickler-Handbuch

backend/klausur/
├── db_models.py                # ExamSession, PseudonymizedDocument
└── services/
    └── pseudonymizer.py        # QR-Codes, Header-Redaction, doc_tokens`}
      </CodeBlock>

      {/* ============================================================ */}
      {/* 12. ZUSAMMENFASSUNG                                          */}
      {/* ============================================================ */}
      <h2 id="zusammenfassung">12. Zusammenfassung: Die Sicherheitsgarantien</h2>

      <div className="not-prose my-6 overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 text-sm">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Garantie</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Wie umgesetzt</th>
              <th className="px-4 py-3 text-left font-medium text-gray-500">Regelwerk</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            <tr>
              <td className="px-4 py-3 font-medium">Kein Name verlaesst den Rechner</td>
              <td className="px-4 py-3">Header-Redaction + verschluesselte Identity-Map</td>
              <td className="px-4 py-3">DSGVO Art. 4 Nr. 5</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Betreiber kann nicht mitlesen</td>
              <td className="px-4 py-3">Client-seitige AES-256-GCM Verschluesselung</td>
              <td className="px-4 py-3">DSGVO Art. 32</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Kein Zugriff durch andere Lehrer</td>
              <td className="px-4 py-3">Tenant-Isolation (Namespace) auf allen 3 Ebenen</td>
              <td className="px-4 py-3">DSGVO Art. 25</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Kein KI-Training mit Schuelerdaten</td>
              <td className="px-4 py-3"><code>training_allowed: false</code> auf allen Vektoren</td>
              <td className="px-4 py-3">AI Act Art. 10</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Alles nachvollziehbar</td>
              <td className="px-4 py-3">Vollstaendiger Audit-Trail aller Aktionen</td>
              <td className="px-4 py-3">DSGVO Art. 5 Abs. 2</td>
            </tr>
            <tr>
              <td className="px-4 py-3 font-medium">Lehrer behaelt volle Kontrolle</td>
              <td className="px-4 py-3">KI-Vorschlaege, keine KI-Entscheidungen + jederzeitiger Widerruf</td>
              <td className="px-4 py-3">DSGVO Art. 22</td>
            </tr>
          </tbody>
        </table>
      </div>

      <InfoBox type="success" title="Das Wichtigste in einem Satz">
        Das BYOEH-System ermoeglicht KI-gestuetzte Klausurkorrektur, bei der
        <strong> kein Schuelername den Rechner des Lehrers verlaesst</strong>, alle Daten
        <strong> Ende-zu-Ende verschluesselt</strong> sind, jeder Lehrer seinen
        <strong> eigenen abgeschotteten Namespace</strong> hat, und die KI
        <strong> nur Vorschlaege macht</strong> -- die finale Bewertung trifft immer der Lehrer.
      </InfoBox>
    </DevPortalLayout>
  )
}
