diff --git a/PROGRESS.md b/PROGRESS.md index cc51284..6babf11 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -544,3 +544,83 @@ LeoCRM-Agenten können externe MCP-Server nutzen (Web-Search, Code-Execution, ex - Plugins automatisch via pkgutil entdeckt **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**