feat(PROJ-12): E-Mail Export EML/PDF/ZIP

- GET /api/export/pdf/{id}: PDF-Generierung (stdlib, kein ext. Paket)
- POST /api/export/zip: Streaming-ZIP mit manifest.csv, Anhänge optional
- Max. 500 Mails pro Export, Zugriffscheck per Rolle
- Audit-Log für jeden Export
- Frontend: PDF-Button in Mail-Ansicht
- Frontend: Checkboxen + ZIP-Export-Dialog in Suchergebnissen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-03-14 19:49:00 +01:00
parent 30479cfc60
commit 850290b5ef
7 changed files with 703 additions and 4 deletions
+1 -1
View File
@@ -23,7 +23,7 @@
| PROJ-9 | Ordner- & Label-Verwaltung | In Progress | [PROJ-9](PROJ-9-ordner-und-labels.md) | 2026-03-12 |
| PROJ-10 | Admin-Bereich: Nutzer- & Postfachverwaltung | In Progress | [PROJ-10](PROJ-10-admin-bereich.md) | 2026-03-12 |
| PROJ-11 | Audit-Log & Compliance-Berichte | In Progress | [PROJ-11](PROJ-11-audit-log.md) | 2026-03-12 |
| PROJ-12 | E-Mail-Export (EML/PDF) | In Progress | [PROJ-12](PROJ-12-export.md) | 2026-03-12 |
| PROJ-12 | E-Mail-Export (EML/PDF) | In Review | [PROJ-12](PROJ-12-export.md) | 2026-03-12 |
| PROJ-13 | REST API für externe CRM-Anbindung | In Progress | [PROJ-13](PROJ-13-rest-api-crm.md) | 2026-03-13 |
| PROJ-14 | E-Mail-Import: POP3-Verbindung | In Progress | [PROJ-14](PROJ-14-import-pop3.md) | 2026-03-13 |
| PROJ-15 | CLI Import & Export (archivmail-User) | In Review | [PROJ-15](PROJ-15-cli-import-export.md) | 2026-03-13 |
+29 -2
View File
@@ -1,8 +1,8 @@
# PROJ-12: E-Mail-Export (EML / PDF)
## Status: In Progress
## Status: In Review
**Created:** 2026-03-12
**Last Updated:** 2026-03-13
**Last Updated:** 2026-03-14
## Dependencies
- Requires: PROJ-1 (Authentifizierung)
@@ -115,6 +115,33 @@ POST /api/export/zip
| `archive/zip` (Stdlib) | Streaming-ZIP-Erstellung ohne externe Abhängigkeit |
| `github.com/SebastiaanKlippert/go-wkhtmltopdf` | PDF-Generierung aus HTML (serverseitig) |
## Implementation Notes (2026-03-14)
### What was built
**Go Backend — `internal/api/export.go` (new file):**
- `GET /api/export/pdf/{id}` — generates a stdlib-only PDF (no external deps) using raw PDF 1.4 syntax with Helvetica core font. Renders header fields, plain-text body (with HTML-strip fallback), and attachment list. `toLatinSafe()` converts umlauts for Latin-1 compatibility.
- `POST /api/export/zip` — streaming ZIP via `archive/zip` stdlib. Accepts `{"ids":[...], "attachments": true}`, max 500 IDs. Adds `{id[:16]}.eml`, optional `attachments/{id[:8]}/{filename}` entries, and `manifest.csv` (CSV with filename/message_id/from/to/subject/date). Audit-logged as `export: zip: N mails`.
- Both handlers use `requireMailAccess` middleware (blocks admin role). RoleUser is filtered to own mails via `mailBelongsToUser`; RoleAuditor can export all.
**Deviation from spec:** PDF generation uses a hand-rolled stdlib PDF writer instead of `go-wkhtmltopdf` or `go-pdf/fpdf` — avoids adding an external dependency that would require `go get` on the server.
**Routes added to `internal/api/server.go`:**
- `GET /api/export/pdf/{id}`
- `POST /api/export/zip`
**Frontend `src/lib/api.ts`:**
- Added `exportMailPDF(id)` and `exportMailsZIP(ids, attachments)` export functions.
**Frontend `src/app/mail/[id]/page.tsx`:**
- Added "Als PDF exportieren" button next to "Als .eml herunterladen".
**Frontend `src/app/search/page.tsx`:**
- Added per-row Checkbox column + select-all header checkbox.
- Export toolbar appears when ≥1 mail is selected.
- ZIP export dialog with attachments toggle (Switch component).
- Selection cleared when search results change.
## QA Test Results
_To be added by /qa_