feat: T04 fixes - i18n, auth tests, contact/vehicle test cleanup, status updates
This commit is contained in:
+33
-25
@@ -1,30 +1,38 @@
|
||||
# Current Status
|
||||
# Current Status – ERP Nutzfahrzeuge
|
||||
|
||||
**Task**: T04 – Kontakt-/Kundenverwaltung + Contact UI
|
||||
**Status**: COMPLETED
|
||||
**Date**: 2026-07-14
|
||||
## Phase: Implementation (Phase 3)
|
||||
## Plan-Mode: implementation_allowed
|
||||
|
||||
## Summary
|
||||
Contact management backend (CRUD, search, filter, pagination, soft-delete, contact persons, USt-IdNr. validation) and frontend (ContactList, ContactForm, ContactDetail with EU/Inland toggle) implemented.
|
||||
## Completed Tasks
|
||||
- **T01** ✅ Auth + User Management + RBAC + Base Frontend + i18n (re-implemented, 50 backend + 16 frontend tests)
|
||||
- **T02** ✅ Vehicle Management + mobile.de Push + Vehicle UI (commit 74b5e6a)
|
||||
- **T04** ✅ Contact Management + USt-IdNr. Validation + Contact UI (commit 2cf433a)
|
||||
|
||||
## Backend (COMPLETED)
|
||||
- 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
|
||||
## Test Results Summary
|
||||
| Task | Backend Tests | Frontend Tests | Coverage |
|
||||
|------|--------------|--------------|----------|
|
||||
| T01 | 50 passed | 16 passed | 93% (auth_service 95%, routers 98%) |
|
||||
| T02 | 73 passed | 16 passed | 82% |
|
||||
| T04 | 73 passed | 20 passed | 91% |
|
||||
|
||||
## Frontend (COMPLETED)
|
||||
- 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
|
||||
## Current Task: T03 – OCR-Erfassung via OpenRouter Vision
|
||||
- Dependencies: T01, T02 (both completed)
|
||||
- OCRResult model, ocr_service, OCR router, async processing
|
||||
- Frontend: OCR Upload (drag-and-drop), OCR Results view
|
||||
|
||||
## Test Evidence
|
||||
- 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 acceptance criteria verified and documented
|
||||
## Git Status
|
||||
- Branch: main
|
||||
- Working tree: has uncommitted T01 changes
|
||||
|
||||
## Known Risks
|
||||
- PostgreSQL must be running for backend tests
|
||||
- Redis not installed (refresh tokens JWT-based, no async queue yet)
|
||||
- No Alembic migrations yet (tables via Base.metadata.create_all)
|
||||
- mobile.de push is synchronous (returns 202 but executes inline)
|
||||
|
||||
## Next Steps
|
||||
1. Commit T01 changes
|
||||
2. T03: OCR-Erfassung (ZB I/II) via OpenRouter Qwen2.5-VL
|
||||
3. T05: Sales + Legal/Compliance
|
||||
4. T06: KI Copilot
|
||||
5. T08: Bildretusche
|
||||
|
||||
+10
-7
@@ -1,9 +1,12 @@
|
||||
# Next Steps
|
||||
|
||||
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)
|
||||
1. Commit T01 re-implementation changes
|
||||
2. T03: OCR-Erfassung via OpenRouter Vision (Backend + Frontend)
|
||||
3. T05: Sales + Legal/Compliance
|
||||
4. T06: KI Copilot
|
||||
5. T08: Bildretusche
|
||||
6. Alembic Migration Setup für DB Schema
|
||||
7. Docker-Compose für dev/prod erstellen
|
||||
8. Redis Integration für Token-Refresh-Storage
|
||||
9. Frontend: Dashboard-Page nach Login
|
||||
10. Frontend: User Management UI (Admin)
|
||||
|
||||
@@ -93,3 +93,53 @@
|
||||
- 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
|
||||
|
||||
---
|
||||
## T01 Re-Implementation (2026-07-14)
|
||||
|
||||
### Backend
|
||||
- app/config.py: Pydantic BaseSettings with DATABASE_URL, REDIS_URL, JWT_SECRET, JWT_ALGORITHM, JWT_ACCESS_TTL_MINUTES=15, JWT_REFRESH_TTL_DAYS=7, CORS_ORIGINS, UPLOAD_DIR
|
||||
- app/database.py: Async SQLAlchemy engine, session factory, Base declarative, get_db dependency, init_db/drop_db helpers
|
||||
- app/models/user.py: User model with UUID PK, email(unique), password_hash, full_name, role(enum admin/verkaeufer/buchhaltung), language(default de), is_active(default true), created_at, updated_at
|
||||
- app/schemas/user.py: LoginRequest, TokenResponse, RefreshRequest, UserBase/Create/Update/Response/ListResponse, ErrorResponse, HealthResponse
|
||||
- app/utils/jwt.py: create_access_token, create_refresh_token, decode_token, verify_access_token, verify_refresh_token (HS256, type claim separation)
|
||||
- app/services/auth_service.py: hash_password (bcrypt), verify_password, get_user_by_email/id, authenticate_user, generate_token_pair, refresh_access_token, create_user, list_users (paginated), update_user, deactivate_user (soft delete)
|
||||
- app/dependencies.py: get_pagination, get_current_user (JWT bearer extraction), require_role (RBAC factory)
|
||||
- app/routers/auth.py: POST /login, POST /refresh, GET /me
|
||||
- app/routers/users.py: GET / (admin only, paginated), POST / (admin only), PUT /:id (admin only), DELETE /:id (admin only, soft delete)
|
||||
- app/main.py: FastAPI app with CORS, /api/v1 prefix, health endpoint, router registration
|
||||
- tests/conftest.py: Function-scoped async engine, session, admin/verkaeufer/inactive user fixtures, token fixtures, HTTP client fixtures
|
||||
- tests/test_health.py: 3 tests
|
||||
- tests/test_auth.py: 12 tests (login valid/invalid/inactive/nonexistent/email-format, refresh valid/invalid/access-rejected, me with/without/invalid/refresh token)
|
||||
- tests/test_users.py: 15 tests (list admin/non-admin/no-auth, pagination, create admin/non-admin/duplicate/short-pw, update admin/nonexistent, delete soft/nonexistent/non-admin, password hash exclusion)
|
||||
- tests/test_auth_service.py: 20 direct service unit tests
|
||||
- .env.example: All required env vars documented
|
||||
- requirements.txt: fastapi, uvicorn, sqlalchemy[asyncio], asyncpg, pydantic-settings, python-jose, passlib[bcrypt], redis, python-multipart, pytest, pytest-asyncio, httpx, pytest-cov
|
||||
|
||||
### Frontend
|
||||
- package.json: Next.js 14, React 18, next-intl, Tailwind, Vitest, Testing Library
|
||||
- tsconfig.json, next.config.js, tailwind.config.ts, postcss.config.js, vitest.config.ts
|
||||
- app/globals.css: Design tokens as CSS vars (primary, secondary, background, surface, text, error, success, border)
|
||||
- app/layout.tsx: Root layout
|
||||
- app/page.tsx: Redirect to /login
|
||||
- app/(auth)/login/page.tsx: Login form with email/password, validation, Toast on error, i18n integration
|
||||
- lib/api.ts: Fetch wrapper with auth header injection, token refresh, login, getCurrentUser, listUsers, createUser, deleteUser, healthCheck
|
||||
- lib/auth.ts: useAuth hook (login, logout, fetchUser), useRequireAuth hook
|
||||
- lib/i18n.tsx: I18nProvider, useI18n hook, locale switching, parameter interpolation
|
||||
- components/ui/Button.tsx: Primary/secondary/danger/ghost variants, loading spinner
|
||||
- components/ui/Input.tsx: Label, error display, forwardRef
|
||||
- components/ui/Card.tsx: Title + children container
|
||||
- components/ui/Table.tsx: Generic table with columns + data
|
||||
- components/ui/Modal.tsx: Overlay modal with close button
|
||||
- components/ui/Toast.tsx: ToastProvider, useToast hook, success/error/info/warning types
|
||||
- messages/de.json: 28 keys (login, nav, common, user.role)
|
||||
- messages/en.json: 28 keys (matching de.json)
|
||||
- tests/setup.ts: localStorage mock, next/navigation mock
|
||||
- tests/auth.test.tsx: 10 tests (Button, Input, Card, Toast, i18n DE/EN/switch)
|
||||
- tests/i18n.test.tsx: 6 tests (key count ≥20, matching keys, translation, interpolation, fallback)
|
||||
|
||||
### Test Results
|
||||
- Backend: 50/50 pytest passed, 93% total coverage (auth_service 95%, routers 98%)
|
||||
- Frontend: 16/16 vitest passed
|
||||
- TypeScript: tsc --noEmit exit 0
|
||||
- test_report.md created
|
||||
|
||||
Reference in New Issue
Block a user