feat(T07): KI-Copilot with OpenRouter chat, voice input, action system, chat history

This commit is contained in:
2026-07-17 02:28:41 +02:00
parent cb89e3ff1e
commit 5cc9f8e9a9
24 changed files with 2878 additions and 188 deletions
+36 -50
View File
@@ -1,55 +1,41 @@
# Worklog
## T06: Verkaufsmodul + Rechtsdokumente + DATEV-Export + Sales UI
## T07: KI-Copilot — 2026-07-17
**Date:** 2026-07-17
**Status:** COMPLETED
### Implemented
- Backend: CopilotSession + CopilotChat models with UUID PKs, user FK, JSONB actions
- Backend: Copilot service with OpenRouter chat completions, action proposal/execution system
- Backend: System prompt with ERP context (vehicle types, contact types, sales workflow) and 5 available actions
- Backend: Action registry — search_vehicles, search_contacts, get_sale_overview, create_vehicle, create_contact
- Backend: Voice endpoint with audio transcription (OpenRouter or stub fallback)
- Backend: Paginated chat history per user, filterable by session_id
- Backend: Router registered in main.py under /api/v1/copilot
- Frontend: Full chat interface with message list, text input, voice input, action preview, chat history sidebar
- Frontend: Web Speech API integration for voice recording via MediaRecorder
- Frontend: Action confirmation flow — Copilot proposes, user confirms/dismisses
### Files Created
### Test Evidence
- Backend: 48 tests passed, 90% coverage on copilot_service + copilot router
- Frontend: 24 tests passed covering all components
- OpenRouter fully mocked in all tests
#### Backend
- backend/app/models/sale.py - Sale model with UUID PK, vehicle/buyer/seller FKs, sale_price, status, is_gwg, contract_pdf_path
- backend/app/models/datev_export.py - DATEVExport model with start_date, end_date, file_path, total_amount
- backend/app/schemas/sale.py - SaleCreate, SaleUpdate, SaleResponse, SaleListResponse, ContractResponse, UstIdVerifyResponse
- backend/app/schemas/datev.py - DATEVExportCreate, DATEVExportResponse, DATEVExportListResponse
- backend/app/services/sale_service.py - Full CRUD + contract PDF + GwG logic + USt-IdNr. verification
- backend/app/services/datev_service.py - Export creation, listing, CSV download
- backend/app/utils/contract_pdf.py - HTML template with WeasyPrint, GwG-Klausel §6 Abs. 2 EStG, USt-IdNr. field
- backend/app/utils/datev.py - DATEV CSV Buchungsstapel format helper
- backend/app/routers/sales.py - Sales CRUD + contract + USt-IdNr. endpoints
- backend/app/routers/datev.py - DATEV export + list + download endpoints
- backend/tests/test_sales.py - 20 tests covering CRUD, contract PDF, GwG, vehicle status, USt-IdNr.
- backend/tests/test_datev.py - 14 tests covering export API, CSV format, validation
#### Frontend
- frontend/lib/sales.ts - Sales API client functions and types
- frontend/lib/datev.ts - DATEV API client functions and types
- frontend/components/sales/SaleList.tsx - Sales table with filters and pagination
- frontend/components/sales/SaleForm.tsx - Sale create form with GwG toggle
- frontend/components/sales/ContractPreview.tsx - PDF preview with regenerate/download
- frontend/components/sales/DatevExport.tsx - DATEV export page with date range picker
- frontend/app/[locale]/verkauf/page.tsx - Sales list page
- frontend/app/[locale]/verkauf/[id]/page.tsx - Sale detail with contract preview
- frontend/app/[locale]/verkauf/neu/page.tsx - Sale create page
- frontend/tests/sales.test.tsx - 11 frontend tests
- frontend/tests/datev.test.tsx - 5 frontend tests
### Files Modified
- backend/app/config.py - Added BZST_API_ENABLED=False, WEASYPRINT_OUTPUT_DIR
- backend/app/main.py - Registered sales + datev routers
- backend/app/models/__init__.py - Added sale + datev_export imports for Base.metadata registration
- backend/requirements.txt - Added weasyprint>=62.0
### Test Results
- Backend: 34/34 passed (11.42s)
- Frontend: 16/16 passed (1.85s)
- Total: 50/50 passed
### Smoke Test
- Backend: All endpoints respond correctly (200/201/404/422)
- GwG logic: Clause appears when is_gwg=true AND price <= 800 EUR (§6 Abs. 2 EStG)
- Vehicle status: Sale creation → 'sold', sale cancel → 'available'
- DATEV CSV: Correct headers, comma decimal separator, DD.MM.YYYY date format
- USt-IdNr. verify: Returns 'BZSt API not available' when feature flag disabled
- WeasyPrint: Installed, async PDF generation via asyncio.to_thread
- Frontend: All components render with mocked API, test IDs present
### Files Changed
- backend/app/models/copilot.py (new)
- backend/app/schemas/copilot.py (new)
- backend/app/routers/copilot.py (new)
- backend/app/services/copilot_service.py (new)
- backend/app/utils/copilot_actions.py (new)
- backend/app/utils/copilot_prompt.py (new)
- backend/app/main.py (modified — added copilot router import + registration)
- backend/tests/test_copilot.py (new)
- backend/tests/test_copilot_coverage.py (new)
- frontend/lib/copilot.ts (new)
- frontend/app/[locale]/ki-copilot/page.tsx (new)
- frontend/components/copilot/ChatInterface.tsx (new)
- frontend/components/copilot/MessageList.tsx (new)
- frontend/components/copilot/ChatInput.tsx (new)
- frontend/components/copilot/VoiceInput.tsx (new)
- frontend/components/copilot/ActionPreview.tsx (new)
- frontend/components/copilot/ChatHistory.tsx (new)
- frontend/tests/copilot.test.tsx (new)
- test_report.md (new)