docs(07): capture phase context for DKV Fleet Module
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
Tessera CI/CD / Lint & Type Check (push) Successful in 43s
Tessera CI/CD / Tests (push) Waiting to run

This commit is contained in:
2026-06-26 14:22:34 +02:00
parent c69c7b2900
commit 34f06c9aa6
3 changed files with 253 additions and 1 deletions
+22 -1
View File
@@ -19,6 +19,7 @@ Decimal phases appear between their surrounding integers in numeric order.
- [ ] **Phase 4: Marketplace & Portal Navigation** - Module catalog, licensing, activation, and sidebar integration
- [x] **Phase 5: Dashboard & Calendar** - Configurable widget grid with drag-and-drop, core widgets, and calendar integration (completed 2026-06-24)
- [ ] **Phase 6: Desktop Client & CI/CD** - Tauri wrapper for Windows/Linux and automated Gitea integration
- [ ] **Phase 7: DKV Fleet Module** - Automated DKV invoice processing via email monitoring, PDF parsing, and Excel export with driver mapping
## Phase Details
@@ -208,10 +209,29 @@ Decimal phases appear between their surrounding integers in numeric order.
- [ ] 06-02-PLAN.md -- Desktop native: tray + close-to-tray, window-state, autostart, notifications + version check, branded icon, AppImage+NSIS bundles, /health/version API (DESK-01/02)
### Phase 7: DKV Fleet Module
**Goal:** Administrators can automatically process DKV fuel card invoices by monitoring an email inbox, parsing PDF attachments, mapping license plates to drivers, and exporting structured Excel reports via SMTP.
**Mode:** mvp
**Depends on**: Phase 6
**Requirements**: DKV-01, DKV-02, DKV-03, DKV-04, DKV-05
**Success Criteria** (what must be TRUE):
1. System automatically detects DKV invoice PDFs from a configured email inbox (IMAP or Exchange)
2. All transactions are parsed per vehicle with: date, service station, km reading, product, quantity, unit, net/gross amounts
3. License plate → driver mapping is importable as CSV and manually editable in the UI
4. Processed data is exported as Excel file and sent to a configurable recipient via SMTP
5. SMTP settings are configurable in general settings (shared with other modules)
6. Module configuration (inbox, sender filter, folder, recipient) is editable in the module settings UI
**Plans**: TBD
**UI hint**: yes
## Progress
**Execution Order:**
Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6
Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7
| Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------|
@@ -221,3 +241,4 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6
| 4. Marketplace & Portal Navigation | 0/4 | Not started | - |
| 5. Dashboard & Calendar | 5/5 | Complete | 2026-06-24 |
| 6. Desktop Client & CI/CD | 2/3 | In Progress| |
| 7. DKV Fleet Module | 0/? | Not started | - |
@@ -0,0 +1,134 @@
# Phase 7: DKV Fleet Module - Context
**Gathered:** 2026-06-26
**Status:** Ready for planning
<domain>
## Phase Boundary
Build a Tessera module that monitors an email inbox for DKV fuel card invoices, parses the PDF attachments, maps license plates to drivers via a configurable vehicle master list, exports a 5-column Excel file, and delivers it via SMTP. Includes processing history and file storage for the last 10 exports.
</domain>
<decisions>
## Implementation Decisions
### Email Inbox Monitoring
- **D-01:** Support both IMAP and Exchange (EWS) as inbox protocols — selectable per module config
- **D-02:** Polling via configurable cron job (interval in minutes, set in module config) + manual "Jetzt prüfen" button in the UI
- **D-03:** Inbox config fields: Protocol (IMAP/Exchange), Host, Port, Username (optional), Password (optional), Encryption (None/STARTTLS/SSL-TLS), Folder, Sender filter (email address to watch for DKV invoices)
- **D-04:** Credentials stored encrypted (AES-256-GCM via existing `crypto.service.ts`)
### SMTP / Email Send
- **D-05:** SMTP settings live in **general settings** (shared, not per-module): Host, Port, Username (optional), Password (optional), Encryption (None/STARTTLS/SSL-TLS), Sender address
- **D-06:** Existing `mail` module (`apps/api/src/mail/`) must be extended to read SMTP config from DB instead of hardcoded env vars
- **D-07:** Export recipient address configured per module (not in general settings)
### PDF Parsing
- **D-08:** Parse DKV E-Rechnung PDF using `pdf-parse` (text extraction + regex) — DKV PDF structure is consistent across invoices
- **D-09:** Parsed data per vehicle block: Kennzeichen (from `VEHICLE: ...` header), per-transaction rows with Lieferdatum, Servicestation Ort, Kilometerstand, Produkt, Menge, Einheit
- **D-10:** On parse failure: 3 retries, then mark as failed in processing history with error message
### Export Format
- **D-11:** Output format: `.xlsx` (Excel), generated with `xlsx` (SheetJS)
- **D-12:** Filename: `DKV_YYYY-MM_<Rechnungsnummer>.xlsx` — example: `DKV_2026-04_26-651566449-001.xlsx`
- **D-13:** Exactly 5 columns in this order:
1. **Lieferdatum** — format `TT.MM.JJJJ` (e.g., `13.12.2020`)
2. **Fahrzeug** — format `{Marke}/{Modell}/{Kennzeichen}` (e.g., `Mercedes/GLC 300 de 4MATIC/GP-JL 728E`) — format string configurable in module
3. **Fahrer** — format `Vorname Nachname` (resolved from vehicle master data via Kennzeichen)
4. **Ort** — Servicestation Ort from PDF
5. **Kilometerstand** — numeric, no unit
- **D-14:** One Excel file per processed invoice (not cumulative)
- **D-15:** Last 10 export files stored in `user-files/` directory, downloadable from module UI
### SMTP Send (on export ready)
- **D-16:** On SMTP failure: 3 retries with exponential backoff, then mark as "Versand fehlgeschlagen" in history; export file remains locally available for manual download
### Vehicle Master Data
- **D-17:** Vehicle master data stored in DB per tenant; fields: Kennzeichen, Marke, Modell, Fahrer (Vorname Nachname)
- **D-18:** Importable as CSV (bulk replace or merge); also manually editable in module UI (CRUD table)
- **D-19:** Fahrzeug column format string is configurable (default: `{Marke}/{Modell}/{Kennzeichen}`)
### Processing History
- **D-20:** Processing history table in module UI: Datum/Zeit, Rechnungsnummer, Anzahl Fahrzeuge, Anzahl Transaktionen, Status (Verarbeitet / Fehler / Versand fehlgeschlagen), Export-Dateiname
- **D-21:** History stored in DB; entries kept indefinitely (no auto-purge in v1)
### Claude's Discretion
- DB schema design (vehicle_master, dkv_invoice_history, dkv_module_config tables)
- Cron job implementation (NestJS `@nestjs/schedule` ScheduleModule)
- EWS reuse from existing `ews-javascript-api` (already installed for calendar)
- IMAP library choice (`imapflow` recommended — modern, Promise-based)
- PDF parsing robustness (handle multi-page, multi-vehicle DKV format)
- Frontend component patterns (reuse existing admin table / settings patterns)
</decisions>
<canonical_refs>
## Canonical References
**Downstream agents MUST read these before planning or implementing.**
### Existing modules to extend/reuse
- `apps/api/src/mail/mail.service.ts` — existing mail service (uses @nestjs-modules/mailer, env-based — must be extended for DB SMTP config)
- `apps/api/src/calendar/crypto.service.ts` — AES-256-GCM credential encryption, use for inbox + SMTP passwords
- `apps/api/src/calendar/calendar.service.ts` — reference pattern for provider abstraction (IMAP vs Exchange mirrors CalDAV vs EWS)
- `apps/api/src/calendar/providers/` — EWS provider pattern to follow for Exchange inbox monitoring
### Reference data (user-provided)
- `user-files/invoice.pdf` — real DKV E-Rechnung (April 2026, 4 pages, 27 vehicles) — use as parse target for regex development
- `user-files/fahrzeuge_bereinigt.xlsx` — cleaned vehicle master data — use to understand CSV import schema
- `user-files/Bildschirmfoto 2026-06-24 um 13.27.56.png` — reference UI for the module view
### Installed dependencies (no new install needed)
- `ews-javascript-api@0.15.3` — Exchange inbox access (already in `apps/api/package.json`)
- `nodemailer@^9.0.1` — SMTP send (already in `apps/api/package.json`)
### New dependencies needed
- `imapflow` — IMAP client (modern, Promise-based)
- `pdf-parse` — PDF text extraction
- `xlsx` (SheetJS) — Excel file generation
</canonical_refs>
<code_context>
## Existing Code Insights
### Reusable Assets
- `apps/api/src/calendar/crypto.service.ts` — inject directly for encrypting inbox + SMTP credentials
- `apps/api/src/mail/mail.service.ts` — extend (not replace) for DB-driven SMTP config
- `apps/api/src/calendar/providers/` — provider abstraction pattern for IMAP vs Exchange
### Established Patterns
- NestJS module structure: `*.module.ts`, `*.service.ts`, `*.controller.ts`, `dto/` — follow same layout
- Prisma migrations for new tables
- `@nestjs/schedule` for cron (already in NestJS ecosystem)
- Tenant isolation via existing RLS / tenant context
### Integration Points
- `apps/api/src/mail/mail.module.ts` — add DB-SMTP config support here
- `apps/api/src/prisma/` — add new tables: `dkv_module_config`, `dkv_vehicle_master`, `dkv_invoice_history`
- `apps/web/src/app/(portal)/` — new module page follows existing portal route pattern
- `user-files/` directory — already exists, used for file storage
</code_context>
<specifics>
## Specific Ideas
- DKV PDF structure: each vehicle section starts with `VEHICLE: {Kennzeichen} CARD NO.: {CardNumber}`, followed by transaction rows; ends with `TOTAL:` row per vehicle. Regex anchors on these markers.
- The Fahrzeug column format `{Marke}/{Modell}/{Kennzeichen}` should use a configurable template string so admins can change it (e.g., `{Kennzeichen} - {Fahrer}` alternative).
- Screenshot reference shows card-style rows with vehicle thumbnail, driver avatar, km reading, amount — the actual Excel export is a flat table, the UI shows the same data in card style.
</specifics>
<deferred>
## Deferred Ideas
None — discussion stayed within phase scope.
</deferred>
---
*Phase: 7-DKV Fleet Module*
*Context gathered: 2026-06-26*
@@ -0,0 +1,97 @@
# Phase 7: DKV Fleet Module - Discussion Log
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
**Date:** 2026-06-26
**Phase:** 07-dkv-fleet-module
**Areas discussed:** Email-Polling, Verarbeitungshistorie, Export-Details, Fehlerbehandlung
---
## Email-Polling
| Option | Description | Selected |
|--------|-------------|----------|
| Automatisch + manuell | Konfigurierbarer Cron-Job + "Jetzt prüfen"-Button | ✓ |
| Nur manuell | Kein Hintergrundprozess | |
| Nur automatisch | Kein manueller Button | |
**User's choice:** Cron-Job (konfigurierbares Intervall) + manueller Button
**Notes:** Cron-Intervall in Minuten soll im Modul konfigurierbar sein
---
## Verarbeitungshistorie
| Option | Description | Selected |
|--------|-------------|----------|
| Verarbeitungshistorie | Strukturierte Liste mit Status | ✓ |
| Nur Status-Log | Simples Textlog | |
| Kein Verlauf | Nichts gespeichert | |
**User's choice:** Verarbeitungshistorie (strukturierte Liste)
**Notes:** Zusatz vom User: Letzte 10 Export-Dateien lokal in `user-files/` speichern und im Modul downloadbar machen
---
## Export-Details
### Dateiname
| Option | Description | Selected |
|--------|-------------|----------|
| DKV_YYYY-MM_Rechnungsnr.xlsx | Eindeutig mit Rechnungsnummer | ✓ |
| DKV_YYYY-MM.xlsx | Nur Jahr+Monat | |
| Konfigurierbar | User legt Schema fest | |
**User's choice:** `DKV_YYYY-MM_<Rechnungsnummer>.xlsx`
### Spalten
**User's choice (freetext):** Exakt 5 Spalten:
1. Lieferdatum (Format TT.MM.JJJJ)
2. Fahrzeug (Format Marke/Modell/Kennzeichen — konfigurierbar, automatisch generiert aus Fahrzeugstammdaten)
3. Fahrer (Format Vorname Nachname)
4. Ort (aus PDF, Servicestation Ort)
5. Kilometerstand (ohne Einheit, numerisch)
**Notes:** Keine Finanzspalten gewünscht. Fahrzeugformat-String soll konfigurierbar sein.
---
## Fehlerbehandlung
### PDF-Parsing-Fehler
| Option | Description | Selected |
|--------|-------------|----------|
| In Historie + Admin-Notification | Fehler-Eintrag + optionale E-Mail | |
| Nur in Historie markieren | Kein Alerting | |
| Retry + dann Fehler | 3 Versuche, dann Fehler | ✓ |
**User's choice:** 3 Retries, dann Fehler in Verarbeitungshistorie
### SMTP-Fehler
| Option | Description | Selected |
|--------|-------------|----------|
| 3 Retries + Fehler in Historie | Exponential backoff, lokale Datei bleibt | ✓ |
| Sofort als Fehler markieren | Kein Retry | |
**User's choice:** 3 Retries mit exponential backoff, dann "Versand fehlgeschlagen" in Historie
---
## Claude's Discretion
- DB-Schema-Design (Tabellen: dkv_module_config, dkv_vehicle_master, dkv_invoice_history)
- Cron-Job-Implementierung (@nestjs/schedule)
- EWS-Wiederverwendung aus Kalender-Modul
- IMAP-Library (imapflow empfohlen)
- PDF-Parse-Robustheit (Multi-Page, Multi-Vehicle)
- Frontend-Komponentenstruktur
## Deferred Ideas
Keine — Diskussion blieb im Phase-Scope.