Admin — OCR: Übersicht & Modell-Detail

Neue Admin-Sektion für das OCR-Pipeline-Monitoring. Zwei Seiten: Die Übersicht zeigt Systemstatus, globale Block-Statistiken und alle Modelle (global + sendergebunden) in einer Tabelle auf einen Blick. Die Modell-Detailseite zeigt die aktuellen Trainingsmetriken und die vollständige Trainingshistorie für ein einzelnes Modell, mit Aktions-Buttons direkt über der Tabelle. Tägliche Nutzung — Statistiken und aktive Läufe sind daher immer sofort sichtbar.

Route: /admin/ocr Route: /admin/ocr/global Route: /admin/ocr/[personId] Neue EntityNav-Sektion: System → OCR Breakpoints: 320 / 640 / 1024 / 1440 API: GET /api/ocr/training-info · POST /api/ocr/train · POST /api/ocr/segtrain

1 — Übersicht: Desktop (≥1024px)

Die Übersichtsseite öffnet sich beim Klick auf „OCR" in der EntityNav. Kein Split-Panel — OCR ist kein Entity-Editor. Der volle Bereich rechts der EntityNav gehört dem Dashboard. Vertikaler Fluss: Health-Bar → Statistiken → Modelltabelle → Globale Aktionen. Beim Klick auf eine Tabellenzeile wird die Modell-Detailseite geöffnet.

Desktop lg (1280px) — kein aktiver Lauf
Dokumente Personen Admin
M
Admin
5
Benutzer
3
Gruppen
142
Schlagwörter
System
7
OCR
OCR-Administration
● Service online
Kein aktiver Trainingsauftrag
Letzter Lauf: sender_anna_raddatz · vor 2 Std.
1.842
Eligible Blocks
Kurrent-Erkennung
23
Dokumente
mit annotierten Blöcken
310
Seg. Blocks
Segmentierungstraining
Alle Modelle
Modell / Absender Genauigkeit ZFR ① Blöcke Letzter Lauf Status
global_kurrent
Globales Erkennungsmodell
95,1 % 2,3 % 1.842 vor 1 Tag ✓ Fertig
Anna Raddatz
sender_anna_raddatz
98,3 % 1,7 % 128 vor 2 Std. ✓ Fertig
Franz Kaufmann
sender_franz_kaufmann
45 vor 3 Tagen ✕ Fehler
Marie Schulz
sender_marie_schulz
96,7 % 1,9 % 203 vor 3 Tagen ✓ Fertig
Johann Raddatz
sender_johann_raddatz
94,2 % 2,9 % 87 vor 1 Woche ✓ Fertig
+ 3 weitere Modelle
Globale Aktionen
Training Erkennung Training Segmentierung Erkennungsdaten exportieren Segmentierungsdaten exportieren
Desktop lg — mit aktivem Lauf (Health-Bar + Tabellenzeile)
Dokumente Personen Admin
M
Admin
5
Benutzer
3
Gruppen
142
Schlagwörter
System
7
OCR
OCR-Administration
● Service online
⟳ sender_anna_raddatz · läuft seit 4 Min.
⏳ 1 in Warteschlange
Alle Modelle
Modell / AbsenderGenauigkeitZFRBlöckeLetzter LaufStatus
global_kurrent
Globales Erkennungsmodell
95,1 %2,3 %1.842 vor 1 Tag✓ Fertig
Anna Raddatz
sender_anna_raddatz
98,3 %1,7 %128 gerade jetzt⟳ Läuft
Marie Schulz
sender_marie_schulz
203 ⏳ Warteschlange
1
Globales Modell immer an Position 0. Die global_kurrent-Zeile hat einen leicht bläulichen Hintergrund (bg-[#F8F8FC]) und ist unabhängig von Sortierung immer die erste Zeile. Sie wird anhand personId === null identifiziert.
2
Health-Bar als Echtzeit-Primärindikator. Der Status (RUNNING, QUEUED, idle) wird via SSE aktualisiert — derselbe /api/ocr/jobs/{jobId}/progress-Kanal wie in der Dokumentenansicht. RUNNING-Tabellenzeilen erhalten zusätzlich bg-amber-50. Die Buttons „Training Erkennung" und „Training Segmentierung" werden disabled + opacity-50 wenn ein Lauf aktiv ist.
3
① ZFR = Zeichenfehlerrate (CER). Abkürzung im <th> mit title="Zeichenfehlerrate (Character Error Rate)" und aria-label für Screenreader. Kleinere Werte sind besser — ein Pfeil in der Implementierung ist optional.

2 — Übersicht: Mobile (320px)

Auf kleinen Bildschirmen stapeln sich die drei Stat-Karten einspaltig. Die Modelltabelle zeigt nur Name und Status-Pill (keine Metriken-Spalten — zu schmal). Aktions-Buttons werden vollbreit und vertikal gestapelt.

320px
09:41●●●●
OCR-Administration
● Online Kein aktiver Lauf
1.842
Eligible Blocks
23
Dokumente
310
Seg. Blocks
Alle Modelle
global_kurrent
95,1 % · 1.842 Bl.
Anna Raddatz
98,3 % · 128 Bl.
Franz Kaufmann
Fehler · 45 Bl.
Marie Schulz
96,7 % · 203 Bl.
+ 4 weitere…
Training Erkennung Training Segmentierung Erkennungsdaten exportieren

3 — Modell-Detail: Desktop (≥1024px)

Die Detailseite öffnet sich beim Klick auf eine Zeile der Übersichtstabelle. Sie folgt demselben vertikalen Muster: Metric-Cards oben, darunter die vollständige Trainingshistorie nur für dieses Modell. Für Sender-Modelle gibt es einen Link zur Personen-Detailseite. Zwei Varianten: Sender-Modell (mit Personen-Link) und globales Modell (ohne).

Desktop lg — sender_anna_raddatz (Lauf aktiv)
Dokumente Personen Admin
M
Admin
5
Benutzer
3
Gruppen
142
Schlagwörter
System
7
OCR
← OCR sender_anna_raddatz · Anna Raddatz ⟳ Läuft
98,3 %
Genauigkeit
↑ von 97,1 % (vorher)
1,7 %
Zeichenfehlerrate
↓ von 2,2 % (vorher)
128
Training-Blöcke
beim letzten Lauf
50
Epochs
letztes Training
Trainingshistorie Jetzt neu trainieren Training-Daten exportieren → Anna Raddatz
Status Zeitpunkt Genauigkeit ZFR Blöcke Epochs
⟳ Läuft gerade jetzt 128
✓ Fertig vor 2 Std. 98,3 % 1,7 % 128 50
✓ Fertig vor 3 Tagen 97,1 % 2,2 % 92 50
✓ Fertig vor 1 Woche 96,4 % 2,8 % 74 40
✕ Fehler vor 3 Wochen 60
Fehler: Connection timeout nach 120 s — OCR-Service nicht erreichbar
Desktop lg — global_kurrent (kein Personen-Link)
Dokumente Personen Admin
M
Admin
5
Benutzer
3
Gruppen
142
Schlagwörter
System
7
OCR
← OCR global_kurrent · Globales Erkennungsmodell ✓ Fertig
95,1 %
Genauigkeit
↑ von 94,8 % (vorher)
2,3 %
Zeichenfehlerrate
↓ von 2,7 % (vorher)
1.842
Training-Blöcke
beim letzten Lauf
100
Epochs
letztes Training
Trainingshistorie Jetzt neu trainieren Training-Daten exportieren
StatusZeitpunktGenauigkeitZFRBlöckeEpochs
✓ Fertig vor 1 Tag 95,1 %2,3 %1.842100
✓ Fertig vor 5 Tagen 94,8 %2,7 %1.650100
✓ Fertig vor 2 Wochen 93,2 %3,1 %1.420100
4
Delta-Zeile in Metric-Cards. Unter jedem Metrikwert erscheint ein Vergleich zum vorherigen erfolgreichen Lauf (↑ / ↓ von X % (vorher)). Grün für Verbesserung, rot für Verschlechterung. Berechnung: letzter DONE-Lauf vs. vorletzter DONE-Lauf im nach completedAt sortierten Array. Entfällt wenn weniger als zwei DONE-Läufe vorhanden.
5
FAILED-Fehlertext inline. Bei einer FAILED-Zeile erscheint direkt darunter eine zweite Zeile mit dem errorMessage-Feld — leicht rosa hinterlegt, kein Modal nötig. Ist errorMessage null oder leer, entfällt die zweite Zeile.
6
Keine Danger-Zone. Sender-Modelle werden programmatisch durch SenderModelService angelegt und gelöscht. Die Detailseite bietet bewusst keinen manuellen Lösch-Button. Beim globalen Modell fehlt der „→ Person"-Link, da personId === null.

4 — Modell-Detail: Mobile (320px)

Die vier Metric-Cards arrangieren sich auf Mobile in einem 2×2-Raster. Aktions-Buttons nehmen die volle Breite ein. Die Trainingshistorie zeigt auf kleinen Bildschirmen nur Status, Datum und Genauigkeit — ZFR, Blöcke und Epochs entfallen.

320px — sender_anna_raddatz
09:41●●●●
← OCR
sender_anna_raddatz
Anna Raddatz
98,3 %
Genauigkeit
↑ von 97,1 %
1,7 %
ZFR
↓ von 2,2 %
128
Blöcke
letzter Lauf
50
Epochs
letzter Lauf
Jetzt neu trainieren Training-Daten exportieren → Anna Raddatz
Trainingshistorie
gerade jetzt · 128 Bl.
vor 2 Std. 98,3 %
vor 3 Tagen 97,1 %
vor 1 Woche 96,4 %
vor 3 Wochen · Timeout

5 — Implementation Reference

Exakte Tailwind-Klassen und Pixelwerte für beide Seiten. Neue Dateien sind mit Neu markiert.

ElementTailwind-KlassenReal px / WertHinweis
Routen & Dateien
Übersicht src/routes/admin/ocr/+page.svelte
src/routes/admin/ocr/+page.server.ts
GET /api/ocr/training-info Neu
Global-Detail src/routes/admin/ocr/global/+page.svelte GET /api/ocr/training-info (gefiltert: personId === null) Neu
Sender-Detail src/routes/admin/ocr/[personId]/+page.svelte GET /api/ocr/training-info (gefiltert nach personId) Neu
EntityNav-Eintrag Vorhandene EntityNav-Komponente um OCR-Eintrag ergänzen Neue Sektion „System" mit Separator davor Bestehende Datei ändern
Seitenstruktur (beide Seiten)
OCR Content Area flex-1 flex flex-col overflow-hidden min-w-0 bg-surface Kein Tree-Panel, kein Edit-Panel — volle Breite nach EntityNav OCR ist kein Entity-Editor; enthält kein Split-Layout
Page Header Bar flex items-center gap-2 px-4 py-2.5 border-b border-line bg-white shrink-0 h-10 h: 40px Enthält Back-Link (nur Detail), Titel, optionale Status-Pill
Scrollbarer Seiteninhalt flex-1 overflow-y-auto p-4 flex flex-col gap-3 gap: 12px zwischen Sektionen
Back-Link (Detail) text-[11px] text-gray-400 hover:text-ink transition-colors shrink-0 goto('/admin/ocr') oder <a href="/admin/ocr">
Health Bar (Übersicht)
Health Bar Container flex items-center gap-3 px-4 py-2 bg-white border border-line rounded-sm h: 36px Neu
Service-Pill (online) inline-flex items-center gap-1 px-2 py-0.5 rounded-sm text-[10px] font-bold uppercase tracking-wide bg-green-50 text-green-700 border border-green-200 Offline: bg-red-50 text-red-700 border-red-200
Running-Pill bg-amber-50 text-amber-700 border border-amber-200 (gleiche Basis) Nur sichtbar wenn status === 'RUNNING'. Icon ⟳ via animate-spin
Queued-Badge text-[10px] text-amber-800 bg-amber-100 border border-amber-200 px-2 py-0.5 rounded-sm font-bold Nur sichtbar wenn mind. 1 Lauf QUEUED. Text: „⏳ N in Warteschlange"
Stat Cards (Übersicht)
Grid (Desktop) grid grid-cols-1 sm:grid-cols-3 gap-3 Mobile: 1 Spalte; ab 640px: 3 Spalten Neu
Stat Card bg-white border border-line rounded-sm px-4 py-3 padding: 12px 16px · kein Hover (nicht klickbar)
Stat-Zahl font-serif text-3xl font-bold text-ink leading-none 30px, Merriweather · deutsche Tausend-Trennung via n.toLocaleString('de-DE')
Stat-Label text-[10px] font-bold uppercase tracking-widest text-gray-400 mt-1 10px
Stat-Subtext text-[9px] text-gray-300 mt-0.5 9px · optional
Modell-Tabelle (Übersicht)
Tabellen-Container bg-white border border-line rounded-sm overflow-hidden Neu — kein <table>, sondern CSS-Grid-Rows
Tabellenkopf bg-ink grid px-4 py-2 grid-cols-[2fr_80px_80px_80px_80px_100px] Kopfzellen: text-[9px] font-bold uppercase tracking-wide text-brand-mint
Tabellenzeile grid px-4 py-2.5 border-b border-line items-center cursor-pointer hover:bg-surface transition-colors grid-cols-[2fr_80px_80px_80px_80px_100px] Klick → goto('/admin/ocr/{id}') Mobile: Tabelle horizontal scrollbar (overflow-x-auto) oder vereinfachte 2-Spalten-Liste
Global-Zeile Zusätzlich bg-[#F8F8FC] Immer erste Zeile (personId === null)
Sender-Name text-sm font-medium text-gray-700 14px · darunter modelName: text-[10px] text-gray-400 mt-0.5 Name aus personNames[run.personId] des training-info-Endpoints
Metrik-Wert (gut) text-green-700 font-semibold Accuracy ≥ 95 % oder niedrigste CER
Metrik-Wert (Fehler) text-red-600 font-semibold Zeigt „—" bei fehlenden Werten (FAILED/RUNNING)
Status Pills (alle Seiten)
Basis-Klassen inline-flex items-center gap-1 px-2 py-0.5 rounded-sm text-[10px] font-bold uppercase tracking-wide border Icon als Textzeichen vor Label (✓ ⟳ ✕ ⏳)
DONE bg-green-50 text-green-700 border-green-200
RUNNING bg-amber-50 text-amber-700 border-amber-200 Icon ⟳ in eigenem <span class="animate-spin">
FAILED bg-red-50 text-red-700 border-red-200
QUEUED bg-yellow-50 text-yellow-800 border-yellow-200
Metric Cards (Detail)
Grid grid grid-cols-2 sm:grid-cols-4 gap-3 Mobile: 2×2 · Desktop: 4×1 Neu
Metric Card bg-white border border-line rounded-sm px-4 py-3 text-center
Zahl (positiv) font-serif text-3xl font-bold leading-none text-green-700 Accuracy ≥ 95 %
Zahl (neutral) font-serif text-3xl font-bold leading-none text-ink Standard
Delta-Zeile text-[10px] mt-1 + text-green-600 / text-red-600 / text-gray-400 10px Format: „↑ von 94,8 % (vorher)". Entfällt bei < 2 DONE-Läufen.
Trainingshistorie (Detail)
Tabellen-Container bg-white border border-line rounded-sm overflow-hidden
Tabellenkopf bg-ink grid px-4 py-2 grid-cols-[100px_1fr_80px_80px_80px_80px] Mobile: grid-cols-[80px_1fr_80px] (Status · Datum · Genauigkeit)
RUNNING-Zeile bg-amber-50 zusätzlich Leere Metrik-Zellen zeigen „—"
FAILED-Zeile bg-red-50 (sehr hell, ~#fff8f8) Fehlertext folgt als zweite Sub-Zeile: text-[11px] text-red-600 px-4 pb-2 col-span-full
Buttons & Aktionen
Primär-Button inline-flex items-center h-9 px-4 bg-ink text-white rounded-sm text-xs font-bold uppercase tracking-wide hover:opacity-90 transition-opacity h: 36px (44px auf Mobile) Disabled wenn Lauf aktiv: opacity-50 cursor-not-allowed pointer-events-none
Outline-Button inline-flex items-center h-9 px-4 border border-ink text-ink rounded-sm text-xs font-bold uppercase tracking-wide hover:bg-surface transition-colors Export: window.location.href = '/api/ocr/training-data/export'
Personen-Link text-sm text-ink underline underline-offset-2 hover:text-brand-mint transition-colors Nur auf Sender-Detailseite. Ziel: /persons/{personId}. Entfällt bei personId === null.
API-Aufrufe
Übersicht laden GET /api/ocr/training-info Felder: availableBlocks · totalOcrBlocks · availableDocuments · availableSegBlocks · ocrServiceAvailable · runs · personNames Im +page.server.ts laden; SenderModel-Liste zusätzlich via eigenem Endpunkt oder aus runs aggregieren
Training starten POST /api/ocr/train / POST /api/ocr/segtrain Response: OcrTrainingRun Sofort in Health-Bar und Tabelle anzeigen; SSE-Kanal öffnen
Live-Updates EventSource('/api/ocr/jobs/{jobId}/progress') Server-Sent Events Health-Bar + Status-Pills live aktualisieren; onDestroy schließen