From a914280a4e40aa4dc425dcbf1c1d1e30b85d58e0 Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Thu, 23 Jul 2026 23:45:19 +0200 Subject: [PATCH] docs: update PROGRESS.md with Phase 5 Batch 6a summary (Tasks 5.20-5.22) --- PROGRESS.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/PROGRESS.md b/PROGRESS.md index 4e10a9d..cc51284 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -464,3 +464,83 @@ LeoCRM-Agenten können externe MCP-Server nutzen (Web-Search, Code-Execution, ex - Bestehende Patterns verwendet (apiClient, React Query hooks, lazy-loaded pages) **Phase 5 Batch 5 Gesamt: ✅ Complete** + +--- + +## Phase 5 Batch 6a (Tasks 5.20-5.22) — ✅ Complete + +### Task 5.20: Custom Fields — Plugin-Felder in UI (6h) + +**Backend:** +- `app/plugins/manifest.py` — `CustomFieldDefinition` model (name, label, label_key, field_type, options, default_value, required, entity) + `custom_fields` field on `PluginManifest` +- `app/routes/custom_fields.py` — `GET/PATCH /api/v1/contacts/{id}/custom-fields` routes + - Merges plugin-defined field definitions with stored values from `contacts.custom` JSONB + - Validates required fields, select/multiselect options + - RBAC: `contacts:read` / `contacts:write` +- `app/plugins/registry.py` — `get_active_manifests` now includes `custom_fields` in response + +**Frontend:** +- `frontend/src/api/customFields.ts` — `useCustomFields`, `useUpdateCustomFields` React Query hooks +- `frontend/src/components/contacts/CustomFieldRenderer.tsx` — renders fields by type (text/number/date/select/multiselect/boolean) in read + edit modes +- Integrated into `ContactDetail` (read-only) and `ContactEditModal` (editable with save logic) +- `frontend/src/store/pluginStore.ts` — `PluginCustomFieldDefinition` interface + `getCustomFieldsForEntity` selector + +**Tests:** +- `tests/test_custom_fields.py` — 9 tests (GET/PATCH/manifest validation) +- `frontend/src/__tests__/CustomFieldRenderer.test.tsx` — 5 tests (read/edit/multiselect/empty) + +### Task 5.21: Tasks-Plugin (12h) + +**Backend:** +- New plugin `app/plugins/builtins/tasks/` with full structure: + - `plugin.py` — PluginManifest (name='tasks', dependencies=['permissions'], permissions=['tasks:read/write/delete']) + - `models.py` — Task model with TenantMixin (title, description, status, priority, due_date, assigned_to, contact_id) + - `schemas.py` — Pydantic schemas for CRUD + assign + status + - `routes.py` — CRUD endpoints: GET/POST /tasks, GET/PATCH/DELETE /tasks/{id}, POST /tasks/{id}/assign, POST /tasks/{id}/status + - `services.py` — Business logic with filtering, pagination, soft-delete + - `migrations/0001_initial.sql` — Creates tasks table with indexes + - `jobs.py` — ARQ `tasks_due_reminder` cron job (daily 8:00) sends notifications for due tasks +- Registered in `app/core/worker.py` (functions + cron_jobs) +- Registered in `tests/conftest.py` + +**Frontend:** +- `frontend/src/api/tasks.ts` — Full React Query hooks (useTasks, useTask, useCreateTask, useUpdateTask, useDeleteTask, useAssignTask, useUpdateTaskStatus) +- `frontend/src/pages/Tasks.tsx` — Task list with filter (status/priority/search), create/edit modal, detail modal, pagination +- Route `/tasks` in `routes/index.tsx` (lazy-loaded) +- Sidebar entry via plugin manifest menu_items +- i18n keys for `nav.tasks` and `tasks.*` in de.json and en.json + +**Tests:** +- `tests/test_tasks.py` — 11 tests (list/create/update/status/delete + auth + validation) +- `frontend/src/__tests__/Tasks.test.tsx` — 3 tests (render/list/create modal) + +### Task 5.22: Saved Searches / Smart Lists (6h) + +**Backend:** +- `app/models/saved_filter.py` — SavedFilter model with TenantMixin (name, entity_type, filter_criteria JSONB, user_id) +- `app/routes/saved_filters.py` — GET/POST /saved-filters, DELETE /saved-filters/{id} with RBAC +- `alembic/versions/0029_saved_filters.py` — Migration creates saved_filters table +- Registered in `app/main.py` and `tests/conftest.py` + +**Frontend:** +- `frontend/src/api/savedFilters.ts` — useSavedFilters, useCreateSavedFilter, useDeleteSavedFilter hooks +- `frontend/src/components/SavedFilters.tsx` — Filter-builder UI with save button, load saved filters as tabs, delete +- Integrated into `ContactsListPage` as example (saves search/type/sort criteria) +- i18n keys for `savedFilters.*` in de.json and en.json + +**Tests:** +- `tests/test_saved_filters.py` — 9 tests (list/create/delete + auth + validation + duplicate) +- `frontend/src/__tests__/SavedFilters.test.tsx` — 3 tests (render/save modal/load filter) + +### Verifikation +- TSC: 0 neue Errors (2 pre-existing Dms.tsx errors) +- 3 Commits mit klaren Messages +- Mindestens 3 Tests pro Task (9+11+9 backend, 5+3+3 frontend) +- RBAC (require_permission) auf allen API-Routes +- TenantMixin auf allen neuen DB-Models +- i18n (de.json, en.json) aktualisiert +- Keine .env committet +- Bestehende Patterns verwendet (apiClient, React Query hooks, lazy-loaded pages, Zustand stores) +- Plugins automatisch via pkgutil entdeckt + +**Phase 5 Batch 6a Gesamt: ✅ Complete**