Update PROGRESS.md with Phase 5 Batch 6b summary (Tasks 5.23-5.25)
This commit is contained in:
+80
@@ -544,3 +544,83 @@ LeoCRM-Agenten können externe MCP-Server nutzen (Web-Search, Code-Execution, ex
|
|||||||
- Plugins automatisch via pkgutil entdeckt
|
- Plugins automatisch via pkgutil entdeckt
|
||||||
|
|
||||||
**Phase 5 Batch 6a Gesamt: ✅ Complete**
|
**Phase 5 Batch 6a Gesamt: ✅ Complete**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 5 Batch 6b: Tasks 5.23–5.25 (Final Batch)
|
||||||
|
|
||||||
|
### Task 5.23: Deduplication / Merge (6h)
|
||||||
|
|
||||||
|
**Backend:**
|
||||||
|
- `app/models/contact_merge.py` — ContactMergeHistory model with TenantMixin (source_contact_id, target_contact_id, merged_fields JSONB, merged_by, note)
|
||||||
|
- `app/services/dedup_service.py` — Dedup service with find_duplicates (email/phone/name similarity), merge_contacts (field overrides, auto-merge, entity_links/tag_assignments re-pointing, soft-delete source), get_merge_history
|
||||||
|
- `app/routes/contacts.py` — Added endpoints:
|
||||||
|
- `POST /api/v1/contacts/duplicates` — find duplicates (RBAC: contacts:read)
|
||||||
|
- `POST /api/v1/contacts/merge` — merge two contacts (RBAC: contacts:write)
|
||||||
|
- `GET /api/v1/contacts/merge-history` — paginated merge history (RBAC: contacts:read)
|
||||||
|
- `alembic/versions/0030_contact_merge_history.py` — Migration creates contact_merge_history table
|
||||||
|
- Registered in `app/models/__init__.py` and `tests/conftest.py`
|
||||||
|
|
||||||
|
**Frontend:**
|
||||||
|
- `frontend/src/api/dedup.ts` — useFindDuplicates, useMergeContacts, useMergeHistory hooks
|
||||||
|
- `frontend/src/components/contacts/DedupDialog.tsx` — UI for comparing and merging duplicate contacts with field selection
|
||||||
|
- i18n keys for `dedup.*` in de.json and en.json
|
||||||
|
|
||||||
|
**Tests:**
|
||||||
|
- `tests/test_dedup.py` — 5 tests (find by email, find empty, merge success, merge same fails, merge history)
|
||||||
|
|
||||||
|
### Task 5.24: PWA (Progressive Web App) (6h)
|
||||||
|
|
||||||
|
**Setup:**
|
||||||
|
- `vite-plugin-pwa` installed in frontend
|
||||||
|
- `frontend/vite.config.ts` — VitePWA plugin with autoUpdate strategy, manifest (name, icons, theme_color), workbox config (static asset caching, font caching, StaleWhileRevalidate)
|
||||||
|
|
||||||
|
**Assets:**
|
||||||
|
- `frontend/public/favicon.svg` — SVG favicon (blue rounded square with "L")
|
||||||
|
- `frontend/public/icon-192.svg` — 192x192 PWA icon
|
||||||
|
- `frontend/public/icon-512.svg` — 512x512 PWA icon
|
||||||
|
|
||||||
|
**Frontend:**
|
||||||
|
- `frontend/src/components/PWAInstallPrompt.tsx` — Install prompt component with beforeinstallprompt event handling, dismiss/accept buttons, localStorage persistence
|
||||||
|
- `frontend/src/utils/notifications.ts` — Notification permission helper (getNotificationPermission, requestNotificationPermission, showNotification, isPWAInstalled)
|
||||||
|
- i18n keys for `pwa.*` in de.json and en.json
|
||||||
|
|
||||||
|
**Tests:**
|
||||||
|
- `frontend/src/__tests__/PWAInstallPrompt.test.tsx` — 6 tests (no prompt, show prompt, dismiss, already dismissed, notification unsupported, isPWAInstalled)
|
||||||
|
|
||||||
|
### Task 5.25: Dashboard-System ausbauen (8h)
|
||||||
|
|
||||||
|
**Backend:**
|
||||||
|
- `app/routes/dashboard.py` — `GET /api/v1/dashboard/widgets` lists all dashboard widgets from active plugins (RBAC: dashboard:read)
|
||||||
|
- Uses existing `get_active_manifests()` from plugin registry which already includes `dashboard_widgets`
|
||||||
|
- Registered in `app/main.py` and `app/routes/__init__.py`
|
||||||
|
|
||||||
|
**Frontend:**
|
||||||
|
- `frontend/src/api/dashboard.ts` — useDashboardWidgets hook
|
||||||
|
- `frontend/src/components/dashboard/DashboardWidgetLoader.tsx` — Dynamically loads widget components via lazy loading with fallback
|
||||||
|
- `frontend/src/components/dashboard/DashboardGrid.tsx` — CSS Grid layout with native HTML5 drag-and-drop widget reordering
|
||||||
|
- `frontend/src/pages/Dashboard.tsx` — Updated to include dynamic widget loading section
|
||||||
|
- 3 Example widgets:
|
||||||
|
- `RecentContactsWidget` — shows last 5 contacts
|
||||||
|
- `TasksSummaryWidget` — shows open/overdue/high-priority task counts
|
||||||
|
- `CalendarUpcomingWidget` — shows next 3 upcoming calendar entries
|
||||||
|
- i18n keys for dashboard widgets in de.json and en.json
|
||||||
|
|
||||||
|
**Tests:**
|
||||||
|
- `tests/test_dashboard.py` — 3 backend tests (list widgets, auth required, plugin_name field)
|
||||||
|
- `frontend/src/__tests__/Dashboard.test.tsx` — 3 frontend tests (grid render, empty state, widget labels)
|
||||||
|
|
||||||
|
### Verifikation
|
||||||
|
- TSC: 0 neue Errors (nur pre-existing Dms.tsx + FileExplorer errors)
|
||||||
|
- 3 Commits mit klaren Messages
|
||||||
|
- Mindestens 3 Tests pro Task (5+6+3 backend, 6+3 frontend)
|
||||||
|
- RBAC (require_permission) auf allen API-Routes
|
||||||
|
- TenantMixin auf allen neuen DB-Models (ContactMergeHistory)
|
||||||
|
- i18n (de.json, en.json) aktualisiert für alle Tasks
|
||||||
|
- Keine .env committet
|
||||||
|
- Bestehende Patterns verwendet (apiClient, React Query hooks, lazy loading)
|
||||||
|
- Plugins automatisch via pkgutil entdeckt
|
||||||
|
- dashboard_widgets bereits in PluginManifest (Phase 3) — genutzt in Task 5.25
|
||||||
|
|
||||||
|
**Phase 5 Batch 6b Gesamt: ✅ Complete**
|
||||||
|
**Phase 5 Gesamt: ✅ Complete**
|
||||||
|
|||||||
Reference in New Issue
Block a user