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:
@@ -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_
|
||||
Reference in New Issue
Block a user