feat(T06): Verkaufsmodul + Rechtsdokumente + DATEV-Export + Sales UI

This commit is contained in:
2026-07-17 01:58:34 +02:00
parent a38d340ddc
commit 6603e411e9
33 changed files with 3481 additions and 107 deletions
+135 -25
View File
@@ -12,7 +12,16 @@
"description": "Komplettes Auth-System: JWT login/refresh, User CRUD (admin only), RBAC Middleware (admin/verkaeufer/buchhaltung). Backend: User Model, auth_service, auth router, users router, JWT utils, RBAC dependency. Frontend: Root layout, Login page, Auth context/hooks, i18n setup (next-intl oder react-i18next), de.json + en.json Basistranslationen, API client (fetch wrapper mit Auth-Header), Base UI components (Button, Input, Card, Table, Modal, Toast). Health endpoint /api/health. Config via Pydantic BaseSettings (DB URL, Redis URL, JWT Secret, OpenRouter Key, mobile.de credentials).",
"assigned_subagent": "implementation_engineer",
"dependencies": [],
"requirement_ids": ["M6-F1", "M6-F2", "AUTH-1", "AUTH-2", "AUTH-3", "AUTH-4", "I18N-1", "I18N-2"],
"requirement_ids": [
"M6-F1",
"M6-F2",
"AUTH-1",
"AUTH-2",
"AUTH-3",
"AUTH-4",
"I18N-1",
"I18N-2"
],
"estimated_effort": "L",
"estimated_lines": 600,
"acceptance_criteria": [
@@ -88,8 +97,18 @@
"category": "vehicle",
"description": "Komplettes Fahrzeug-Modul: Vehicle Model (LKW, Baumaschine, PKW, Stapler, Transporter), vehicle_service mit CRUD + filter/sort/paginate, vehicles router mit allen Endpoints. mobile.de Seller API Integration (Push only): mobilede_service, mobilede_push background task, Ad-Format Mapping, Retry-Queue via Redis. Frontend: Vehicle List page mit Filter (type, status, brand) + Pagination + Sort, Vehicle Detail page, Vehicle Create/Edit form, mobile.de Push Button + Status indicator. Soft-Delete Implementierung (status='deleted').",
"assigned_subagent": "implementation_engineer",
"dependencies": ["T01"],
"requirement_ids": ["M1-F1", "M1-F2", "M1-F3", "M1-F4", "M1-F5", "M1-F6", "M1-F7"],
"dependencies": [
"T01"
],
"requirement_ids": [
"M1-F1",
"M1-F2",
"M1-F3",
"M1-F4",
"M1-F5",
"M1-F6",
"M1-F7"
],
"estimated_effort": "L",
"estimated_lines": 700,
"acceptance_criteria": [
@@ -152,8 +171,17 @@
"status": "completed",
"description": "Komplettes OCR-Modul: OCRResult Model, ocr_service mit OpenRouter Qwen2.5-VL Integration, OCR router (upload, get results, apply to vehicle). Async OCR processing via Redis Queue. Prompt-Engineering für ZB I/II: structured JSON output (brand, model, vin, first_registration, mileage, power_kw, fuel_type). Confidence-Score Berechnung. Manual Review bei confidence < 0.7. Response-Caching für identische Scans. Frontend: OCR Upload page (drag-and-drop), OCR Results view mit side-by-side Original Scan + Extracted Data, Apply-to-Vehicle Button.",
"assigned_subagent": "implementation_engineer",
"dependencies": ["T01", "T02"],
"requirement_ids": ["M2-F1", "M2-F2", "M2-F3", "M2-F4", "M2-F5"],
"dependencies": [
"T01",
"T02"
],
"requirement_ids": [
"M2-F1",
"M2-F2",
"M2-F3",
"M2-F4",
"M2-F5"
],
"estimated_effort": "L",
"estimated_lines": 600,
"acceptance_criteria": [
@@ -205,8 +233,17 @@
"category": "contact",
"description": "Komplettes Kontakt-Modul: Contact Model (Kunde/Lieferant/Beide, EU/Inland, USt-IdNr.), contact_service mit CRUD + search + filter (type, eu/inland), contacts router. USt-IdNr.-Feld mit Format-Validierung (DE + EU Formate). Contact-Search (name, company, city, email). Frontend: Contact List mit Search + Filter, Contact Detail page, Contact Create/Edit form. EU/Inland Toggle. USt-IdNr. input mit Format-Validierung frontend-seitig.",
"assigned_subagent": "implementation_engineer",
"dependencies": ["T01"],
"requirement_ids": ["M3-F1", "M3-F2", "M3-F3", "M3-F4", "M3-F5", "M3-F6"],
"dependencies": [
"T01"
],
"requirement_ids": [
"M3-F1",
"M3-F2",
"M3-F3",
"M3-F4",
"M3-F5",
"M3-F6"
],
"estimated_effort": "M",
"estimated_lines": 500,
"acceptance_criteria": [
@@ -260,8 +297,17 @@
"category": "file",
"description": "Komplettes Dateiablage-Modul: File Model, file_service mit Upload/Download/Delete, files router. MIME-Type-Validierung (images: jpg/png/webp, documents: pdf/doc/docx, scans: jpg/png). Max 20MB pro Datei. Dateien gespeichert im uploads_data Volume. Thumbnail-Generierung für Images. Frontend: File Upload Component (Drag-and-Drop, multi-file), File List mit Thumbnails, File Download, File Delete mit Confirm. Gallery view für Fahrzeug-Bilder.",
"assigned_subagent": "implementation_engineer",
"dependencies": ["T01", "T02"],
"requirement_ids": ["M4-F1", "M4-F2", "M4-F3", "M4-F4", "M4-F5"],
"dependencies": [
"T01",
"T02"
],
"requirement_ids": [
"M4-F1",
"M4-F2",
"M4-F3",
"M4-F4",
"M4-F5"
],
"estimated_effort": "M",
"estimated_lines": 500,
"acceptance_criteria": [
@@ -311,8 +357,21 @@
"category": "sales",
"description": "Komplettes Verkaufsmodul: Sale Model, sale_service mit CRUD, sales router. Contract PDF Generierung (Verkaufvertrag mit Vehicle + Contact Daten, GwG-Klausel, USt-IdNr. Feld). DATEV-Export: datev_service, DATEV CSV Format (Buchungsstapel: Datum, Konto, Gegenkonto, Betrag, Belegfeld, Buchungstext). GwG-Logik: Sofortabzug bei <= 800EUR (§6 Abs. 2 EStG). USt-IdNr.-Prüfung: BZSt API endpoint (Feature-Flag bzst_api_enabled, aktuell disabled → manual review). DATEVExport Model + router. Frontend: Sales List, Sale Detail mit Contract Preview, Sale Create form (Vehicle select, Contact select, Price, GwG toggle), DATEV Export page (Zeitraum wählen, Download CSV).",
"assigned_subagent": "implementation_engineer",
"dependencies": ["T02", "T04"],
"requirement_ids": ["M5-F1", "M5-F2", "M5-F3", "M5-F4", "M5-F5", "M5-F6", "M5-F7", "M5-F8", "M5-F9"],
"dependencies": [
"T02",
"T04"
],
"requirement_ids": [
"M5-F1",
"M5-F2",
"M5-F3",
"M5-F4",
"M5-F5",
"M5-F6",
"M5-F7",
"M5-F8",
"M5-F9"
],
"estimated_effort": "XL",
"estimated_lines": 800,
"acceptance_criteria": [
@@ -376,7 +435,8 @@
"frontend/components/sales/DatevExport.tsx",
"frontend/tests/sales.test.tsx",
"frontend/tests/datev.test.tsx"
]
],
"status": "completed"
},
{
"id": "T07",
@@ -384,8 +444,19 @@
"category": "copilot",
"description": "Komplettes KI-Copilot-Modul: Copilot chat_service mit OpenRouter (Claude/GPT-4), copilot router (chat, voice, history, action). System-Prompt mit ERP-Kontext (verfügbare Aktionen: vehicle search/create, contact search, sale overview). Action-System: Copilot kann strukturierte Actions ausführen (GET /api/vehicles, POST /api/contacts, etc.) via function-calling. Voice Input: STT via Browser Web Speech API → text → chat. Chat History (paginated, pro User). Frontend: Copilot Chat Interface (message list, input, send), Voice Input Button (microphone), Action Preview (zeigt was Copilot tun will vor Ausführung), Chat History sidebar.",
"assigned_subagent": "implementation_engineer",
"dependencies": ["T01", "T02"],
"requirement_ids": ["M7-F1", "M7-F2", "M7-F3", "M7-F4", "M7-F5", "M7-F6", "M7-F7"],
"dependencies": [
"T01",
"T02"
],
"requirement_ids": [
"M7-F1",
"M7-F2",
"M7-F3",
"M7-F4",
"M7-F5",
"M7-F6",
"M7-F7"
],
"estimated_effort": "L",
"estimated_lines": 700,
"acceptance_criteria": [
@@ -441,8 +512,18 @@
"category": "retouch",
"description": "Komplettes Bildretusche-Modul: Retouch service mit OpenRouter Flux.1-Pro, retouch router (process, get result, price-compare). Bild-Verarbeitung: Upload → Flux.1-Pro Retusche (Hintergrund entfernen/verbessern, Spiegelungen, Farbkorrektur) → retouched image gespeichert. Preisvergleich: mobile.de Listings Scraper/API → comparable vehicles (brand, model, year, price) → Durchschnittspreis berechnet. Frontend: Retouch Upload page (Bild wählen, Retusche starten), Before/After Vergleich (slider), Preisvergleich view (Tabelle mit comparable listings + Durchschnittspreis).",
"assigned_subagent": "implementation_engineer",
"dependencies": ["T01", "T02", "T05"],
"requirement_ids": ["M8-F1", "M8-F2", "M8-F3", "M8-F4", "M8-F5"],
"dependencies": [
"T01",
"T02",
"T05"
],
"requirement_ids": [
"M8-F1",
"M8-F2",
"M8-F3",
"M8-F4",
"M8-F5"
],
"estimated_effort": "L",
"estimated_lines": 600,
"acceptance_criteria": [
@@ -490,15 +571,44 @@
],
"dependency_graph": {
"T01": [],
"T02": ["T01"],
"T03": ["T01", "T02"],
"T04": ["T01"],
"T05": ["T01", "T02"],
"T06": ["T02", "T04"],
"T07": ["T01", "T02"],
"T08": ["T01", "T02", "T05"]
"T02": [
"T01"
],
"T03": [
"T01",
"T02"
],
"T04": [
"T01"
],
"T05": [
"T01",
"T02"
],
"T06": [
"T02",
"T04"
],
"T07": [
"T01",
"T02"
],
"T08": [
"T01",
"T02",
"T05"
]
},
"execution_order": ["T01", "T02", "T04", "T03", "T05", "T06", "T07", "T08"],
"execution_order": [
"T01",
"T02",
"T04",
"T03",
"T05",
"T06",
"T07",
"T08"
],
"summary": {
"total_tasks": 8,
"tasks_with_test_spec": 8,
@@ -509,4 +619,4 @@
"total_files_to_create": 120,
"estimated_total_lines": 5000
}
}
}