docs: update PROGRESS.md with Phase 5 Batch 6a summary (Tasks 5.20-5.22)
This commit is contained in:
+80
@@ -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)
|
- Bestehende Patterns verwendet (apiClient, React Query hooks, lazy-loaded pages)
|
||||||
|
|
||||||
**Phase 5 Batch 5 Gesamt: ✅ Complete**
|
**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**
|
||||||
|
|||||||
Reference in New Issue
Block a user