feat(PROJ-17): Admin Dashboard Systemauslastung immer anzeigen

- Systemauslastungs-Sektion wird immer gerendert (nicht nur bei Erfolg)
- Fehlermeldung wenn /api/admin/system/stats nicht erreichbar ist
- Feature-Status auf In Review gesetzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-03-14 11:43:19 +01:00
parent a893084a88
commit d360c9a5ba
68 changed files with 11938 additions and 435 deletions
+146
View File
@@ -0,0 +1,146 @@
# PROJ-2: E-Mail-Import: EML/MBOX Upload
## Status: In Progress
**Created:** 2026-03-12
**Last Updated:** 2026-03-12
## Dependencies
- Requires: PROJ-1 (Authentifizierung) nur eingeloggte Admins dürfen importieren
- Requires: PROJ-5 (Speicherung & Indexierung) importierte E-Mails werden gespeichert
## User Stories
- Als Admin möchte ich EML-Dateien per Drag-and-Drop hochladen, damit ich einzelne E-Mails archivieren kann.
- Als Admin möchte ich MBOX-Dateien importieren, damit ich ganze Postfach-Exporte auf einmal archivieren kann.
- Als Admin möchte ich den Fortschritt eines laufenden Imports sehen, damit ich weiß wie weit der Import ist.
- Als Admin möchte ich nach dem Import eine Zusammenfassung sehen (importiert, übersprungen, Fehler), damit ich Probleme nachvollziehen kann.
- Als System möchte ich Duplikate erkennen und überspringen, damit E-Mails nicht doppelt archiviert werden.
## Acceptance Criteria
- [ ] Upload-Interface akzeptiert .eml und .mbox Dateien (auch mehrere gleichzeitig)
- [ ] Maximale Dateigröße konfigurierbar (Standard: 500 MB pro Upload)
- [ ] EML-Parser liest Envelope-Header (From, To, CC, BCC, Date, Subject, Message-ID)
- [ ] MBOX-Parser iteriert über alle enthaltenen E-Mails in der Datei
- [ ] Anhänge werden extrahiert und getrennt gespeichert
- [ ] Fortschrittsanzeige während des Imports (Anzahl verarbeitet / gesamt)
- [ ] Duplikate (gleiche Message-ID) werden erkannt und übersprungen
- [ ] Import-Zusammenfassung: Anzahl importiert, übersprungen, fehlerhaft
- [ ] Fehlerhafte E-Mails (korrupte Dateien) werden geloggt und übersprungen, brechen Import nicht ab
## Edge Cases
- MBOX-Datei mit 100.000+ E-Mails → chunked processing, kein Timeout
- EML-Datei ohne Message-ID → synthetische ID generieren (Hash des Inhalts)
- E-Mail mit verschachtelten MIME-Teilen (multipart/mixed, multipart/alternative)
- Encoding-Probleme (ISO-8859-1, Windows-1252) → automatische Konvertierung zu UTF-8
- Upload wird unterbrochen → partiell importierte Daten bereinigen
## Technical Requirements
- Streaming-Upload für große Dateien (kein komplettes In-Memory-Laden)
- MBOX-Parsing als Background-Job mit Statusrückmeldung via WebSocket oder Polling
- Maximale Anhang-Größe pro E-Mail konfigurierbar
---
## Tech Design (Solution Architect)
### Komponentenstruktur
**Next.js Frontend (Admin-Bereich):**
```
/admin/upload
├── DropZone ← Drag-and-Drop + Datei-Dialog
│ ├── akzeptiert: .eml, .mbox
│ └── Mehrfachauswahl möglich
├── Upload-Queue ← Liste der hochgeladenen Dateien
│ └── FileItem (pro Datei)
│ ├── Dateiname + Größe
│ ├── Typ-Badge (EML / MBOX)
│ └── Status (wartend / läuft / fertig / Fehler)
├── Fortschrittsanzeige (pro Datei)
│ ├── Fortschrittsbalken (X von Y Mails verarbeitet)
│ └── Aktueller Status
└── Abschlussbericht
├── Importiert: X
├── Übersprungen (Duplikate): Y
└── Fehler: Z (mit Liste der fehlerhaften Mails)
```
**Go Backend:**
```
POST /api/admin/upload
├── Session Middleware (Admin)
├── Multipart-Stream-Handler ← Datei wird nicht komplett in RAM geladen
├── Dateityp-Erkennung (.eml / .mbox)
└── Import-Worker starten (Hintergrund-Goroutine)
Import-Worker
├── EML-Modus
│ └── Einzelne Mail direkt parsen → Storage Coordinator
├── MBOX-Modus
│ ├── MBOX-Parser (iteriert über "From "-Trennzeilen)
│ ├── Für jede Mail:
│ │ ├── Duplikat-Check (Message-ID)
│ │ └── → Storage Coordinator (PROJ-5)
│ └── Fortschritt in DB schreiben
└── Encoding-Normalisierer
└── ISO-8859-1 / Windows-1252 → UTF-8
GET /api/admin/upload/{job_id}/progress ← Polling alle 2 Sek.
```
### Upload- und Importfluss
```
Admin zieht Datei in DropZone
│ POST /api/admin/upload (multipart/form-data, streaming)
Go Backend empfängt Stream
├── .eml? → direkt parsen → Storage Coordinator → fertig
└── .mbox? → Import-Worker (Hintergrund)
MBOX-Parser liest zeilenweise
Trenner: Zeilen die mit "From " beginnen
└── Pro Mail:
Encoding-Erkennung + UTF-8-Normalisierung
Message-ID vorhanden?
Nein → SHA-256(Inhalt) als ID
Duplikat? → überspringen
→ Storage Coordinator (PROJ-5)
Fortschritt in DB aktualisieren
Abschlussbericht in DB speichern
Next.js pollt GET /progress alle 2 Sek.
→ Fortschrittsbalken aktualisieren
→ Bei status:"done" → Abschlussbericht anzeigen
```
### Technische Entscheidungen
| Entscheidung | Begründung |
|---|---|
| **Streaming-Upload** | 500 MB MBOX nie komplett in RAM Go liest den HTTP-Body als Stream direkt in den Parser |
| **MBOX zeilenweises Parsen** | MBOX-Format trennt Mails durch `From `Zeilen kein vollständiges Einlesen der Datei nötig |
| **Background-Worker + Polling** | MBOX mit 100k+ Mails dauert Minuten HTTP-Request darf nicht so lange offen bleiben |
| **Encoding-Normalisierung** | E-Mail-Exporte aus Outlook/Thunderbird kommen oft als ISO-8859-1 Index und DB erwarten UTF-8 |
| **Fehler überspringen, nicht abbrechen** | Eine korrupte Mail soll nicht den gesamten Import einer 50k-MBOX-Datei stoppen |
| **Synthetische Message-ID** | EML-Dateien ohne Message-ID (selten aber möglich) bekommen SHA-256(Inhalt) Duplikatschutz bleibt konsistent |
### Abhängigkeiten
| Paket | Zweck |
|---|---|
| `golang.org/x/text/encoding` | ISO-8859-1 / Windows-1252 → UTF-8 Konvertierung |
| `mime`, `mime/multipart` | EML + MBOX MIME-Parsing (Stdlib) |
## QA Test Results
_To be added by /qa_
## Deployment
_To be added by /deploy_