feat(T04): contact management + USt-IdNr. validation + contact UI
- Contact model: company, role (kaeufer/verkaeufer/beide), soft-delete - ContactPerson model: 1:N relation with CASCADE delete - USt-IdNr. validation: DE + 10 EU countries - Contact CRUD: 7 API endpoints with RBAC, search/filter/paginate - Frontend: ContactList, ContactForm, ContactDetail with EU/Inland toggle - 73 backend tests (91% coverage), 20 frontend tests
This commit is contained in:
+17
-18
@@ -1,31 +1,30 @@
|
||||
# Current Status
|
||||
|
||||
**Task**: T02 – Vehicle Management + mobile.de Push + Vehicle UI
|
||||
**Task**: T04 – Kontakt-/Kundenverwaltung + Contact UI
|
||||
**Status**: COMPLETED
|
||||
**Date**: 2026-07-14
|
||||
|
||||
## Summary
|
||||
Vehicle CRUD API with pagination/filtering/sorting, mobile.de push integration, and full frontend UI implemented.
|
||||
Contact management backend (CRUD, search, filter, pagination, soft-delete, contact persons, USt-IdNr. validation) and frontend (ContactList, ContactForm, ContactDetail with EU/Inland toggle) implemented.
|
||||
|
||||
## Backend (COMPLETED)
|
||||
- Vehicle model: UUID PK, all fields per spec (make, model, fin CHECK len=17, year, first_registration, power_kw, power_hp computed, fuel_type, transmission, color, condition, location, availability, price, vehicle_type, lkw_type, machine_type, body_type, operating_hours, operating_hours_unit, mileage_km, description, timestamps, deleted_at soft-delete)
|
||||
- MobileDeListing model: vehicle_id FK, ad_id, sync_status, synced_at, error_log
|
||||
- 7 API endpoints: GET /vehicles (list+filter+sort+paginate), POST /vehicles (create), GET /vehicles/:id (detail), PUT /vehicles/:id (update), DELETE /vehicles/:id (soft-delete), POST /vehicles/:id/mobile-de/push (202 async), GET /vehicles/:id/mobile-de/status
|
||||
- mobile.de service: push_listing, update_listing, delete_listing, get_listing_status, retry_failed_listing (max 3 retries)
|
||||
- Field mapping: map_fields() converts Vehicle to mobile.de Ad format (vin, firstRegistration YYYY-MM, mileage, price EUR, power, category, bodyType, sellerLocation)
|
||||
- All endpoints require JWT Bearer auth
|
||||
- Config: MOBILE_DE_API_KEY, MOBILE_DE_SELLER_ID env vars added
|
||||
- Contact model: UUID PK, company_name, legal_form, address fields, address_country (ISO 3166-1 alpha-2), vat_id, phone, email, website, role (kaeufer/verkaeufer/beide), vat_id_status, is_private, timestamps, deleted_at soft-delete
|
||||
- ContactPerson model: UUID PK, contact_id FK CASCADE, name, function, phone, email, created_at
|
||||
- 7 API endpoints: GET /contacts (list+search+filter+sort+paginate), POST /contacts (create), GET /contacts/:id (detail+persons), PUT /contacts/:id (update), DELETE /contacts/:id (soft-delete), POST /contacts/:id/persons (add person), DELETE /contacts/:id/persons/:pid (remove person)
|
||||
- Contact service: list_contacts (search, role filter with beide inclusion, is_eu filter, is_private filter, sort, pagination), get_contact_by_id, create_contact (with nested persons), update_contact, soft_delete_contact, add_contact_person, remove_contact_person
|
||||
- USt-IdNr. validation: DE + 10 EU countries regex patterns, EU fallback, validate_vat_id, validate_vat_id_or_raise, get_country_code_from_vat_id
|
||||
- RBAC: all roles read, admin+verkaeufer write (require_role dependency)
|
||||
- Contacts router registered in main.py
|
||||
|
||||
## Frontend (COMPLETED)
|
||||
- VehicleList: Table with filters (search, type, availability, sort), pagination, error handling
|
||||
- VehicleForm: Create/edit form with validation (make, model, fin=17 chars, price>0, vehicle_type), conditional fields
|
||||
- VehicleDetail: All vehicle fields display, delete button, MobileDeStatus embedded
|
||||
- MobileDeStatus: Sync status badge, push button, ad_id, synced_at, error_log display
|
||||
- 3 pages: fahrzeuge list, fahrzeuge/neu create, fahrzeuge/[id] detail
|
||||
- ContactList: Table with filters (search, role, EU/Inland, sort), pagination, error handling, loading state
|
||||
- ContactForm: Create/edit form with USt-IdNr. validation, EU/Inland toggle (radio), country selector, role selector, legal form, address fields, contact info, is_private checkbox
|
||||
- ContactDetail: All contact fields display, delete button, contact persons section with add/remove via Modal
|
||||
- 3 pages: kontakte list, kontakte/neu create, kontakte/[id] detail
|
||||
- lib/contacts.ts: Full API client with typed interfaces + validateVatIdFormat frontend validation
|
||||
|
||||
## Test Evidence
|
||||
- Backend: 73/73 pytest passed, 82% total coverage (vehicle_service 99%, mobilede_service 80%, router 60%)
|
||||
- Frontend: 16/16 vitest passed
|
||||
- Backend: 73/73 pytest passed, 91% coverage on contact modules (service 99%, ust_validation 94%, models 93%, schemas 94%, router 67%)
|
||||
- Frontend: 20/20 vitest passed
|
||||
- test_report.md updated with full results
|
||||
- All mobile.de HTTP calls mocked in tests, no real API calls
|
||||
- Soft-delete verified: deleted_at set, vehicle excluded from list and detail queries
|
||||
- All acceptance criteria verified and documented
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
# Next Steps
|
||||
|
||||
1. T02: Vehicle CRUD + List/Filter/Pagination (Backend + Frontend)
|
||||
1. T05: Lagerverwaltung + Bestandsführung (Backend + Frontend)
|
||||
2. Alembic Migration Setup für DB Schema
|
||||
3. Docker-Compose für dev/prod erstellen
|
||||
4. Redis Integration für Token-Refresh-Storage
|
||||
5. Frontend: Dashboard-Page nach Login
|
||||
6. Frontend: User Management UI (Admin)
|
||||
7. Frontend: Kontakt-Bearbeiten Seite (kontakte/[id]/bearbeiten)
|
||||
|
||||
@@ -68,3 +68,28 @@
|
||||
- Backend: 73/73 pytest passed, 82% total coverage
|
||||
- Frontend: 16/16 vitest passed
|
||||
- test_report.md updated
|
||||
|
||||
---
|
||||
|
||||
## T04: Kontakt-/Kundenverwaltung + Contact UI (2026-07-14)
|
||||
|
||||
### Backend
|
||||
- models/contact.py: Contact + ContactPerson models with UUID PK, soft-delete, CHECK constraints for role/vat_id_status/country
|
||||
- schemas/contact.py: ContactCreate/Update/Response/ListResponse + ContactPersonCreate/Response with VAT ID field_validator
|
||||
- utils/ust_validation.py: DE + 10 EU country regex patterns, EU fallback, validate_vat_id, validate_vat_id_or_raise, get_country_code_from_vat_id
|
||||
- services/contact_service.py: list_contacts (search, role filter with beide inclusion, is_eu filter, is_private filter, sort, pagination), get_contact_by_id, create_contact (with nested persons), update_contact, soft_delete_contact, add_contact_person, remove_contact_person
|
||||
- routers/contacts.py: 7 endpoints (list, create, detail, update, delete, add person, remove person) with RBAC (all read, admin+verkaeufer write)
|
||||
- main.py: Registered contacts router
|
||||
|
||||
### Frontend
|
||||
- lib/contacts.ts: Full API client with typed interfaces + validateVatIdFormat frontend validation
|
||||
- components/contacts/ContactList.tsx: Table with search, role filter, EU/Inland filter, sort, pagination
|
||||
- components/contacts/ContactForm.tsx: Create/edit form with USt-IdNr. validation, EU/Inland toggle, country selector, role, legal form, address, contact info, is_private
|
||||
- components/contacts/ContactDetail.tsx: Detail view with contact persons management (add/remove via Modal)
|
||||
- app/[locale]/kontakte/: list page, neu (create) page, [id] detail page
|
||||
- tests/contacts.test.tsx: 20 tests
|
||||
|
||||
### Test Results
|
||||
- Backend: 73/73 pytest passed, 91% coverage on contact modules (service 99%, ust_validation 94%, models 93%, schemas 94%, router 67%)
|
||||
- Frontend: 20/20 vitest passed
|
||||
- test_report.md updated
|
||||
|
||||
Reference in New Issue
Block a user