From 34f06c9aa684dc975d576c5ff980ad2543c49704 Mon Sep 17 00:00:00 2001 From: Schalli Date: Fri, 26 Jun 2026 14:22:34 +0200 Subject: [PATCH] docs(07): capture phase context for DKV Fleet Module --- .planning/ROADMAP.md | 23 ++- .../phases/07-dkv-fleet-module/07-CONTEXT.md | 134 ++++++++++++++++++ .../07-dkv-fleet-module/07-DISCUSSION-LOG.md | 97 +++++++++++++ 3 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 .planning/phases/07-dkv-fleet-module/07-CONTEXT.md create mode 100644 .planning/phases/07-dkv-fleet-module/07-DISCUSSION-LOG.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index ab4ba0d..371c594 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -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 | - | diff --git a/.planning/phases/07-dkv-fleet-module/07-CONTEXT.md b/.planning/phases/07-dkv-fleet-module/07-CONTEXT.md new file mode 100644 index 0000000..0eb32b6 --- /dev/null +++ b/.planning/phases/07-dkv-fleet-module/07-CONTEXT.md @@ -0,0 +1,134 @@ +# Phase 7: DKV Fleet Module - Context + +**Gathered:** 2026-06-26 +**Status:** Ready for planning + + +## 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. + + + + +## 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_.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) + + + + +## 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 + + + + +## 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 + + + + +## 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. + + + + +## Deferred Ideas + +None — discussion stayed within phase scope. + + + +--- + +*Phase: 7-DKV Fleet Module* +*Context gathered: 2026-06-26* diff --git a/.planning/phases/07-dkv-fleet-module/07-DISCUSSION-LOG.md b/.planning/phases/07-dkv-fleet-module/07-DISCUSSION-LOG.md new file mode 100644 index 0000000..7624237 --- /dev/null +++ b/.planning/phases/07-dkv-fleet-module/07-DISCUSSION-LOG.md @@ -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_.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.