Agent Zero
808da564f3
fix: improve error handling and stability - no logout on transient errors, add ErrorBoundary, global error logging
2026-07-26 12:18:52 +02:00
Agent Zero
4dbbc422ce
fix: repair print/PDF in Reports — fix document.write/appendChild mix, add printPdfBlob for print format
2026-07-26 09:40:43 +02:00
Agent Zero
79ece0fe2e
Phase 4: Webhooks, Backup/Restore UI, Onboarding/Tutorial
...
- Webhooks Backend: model, schema, service (HMAC-SHA256, httpx), routes, event bus dispatcher, migration 0042
- Webhooks Frontend: SettingsWebhooksPage (CRUD, test button, event multi-select), API client
- Backup/Restore Backend: model, schema, service (pg_dump/pg_restore), routes (admin-only), migration 0043
- Backup/Restore Frontend: SettingsBackupPage (create, list, restore dialog with RESTORE confirmation, auto-refresh)
- Onboarding: OnboardingTour (8 steps, custom CSS overlay), WelcomeDialog, onboardingStore (zustand + localStorage)
- Onboarding integrated into AppShell
- Routes: /settings/webhooks, /settings/backup registered
- Settings nav: Webhooks, Backup & Restore entries added
- Migration conflict fixed: 0042_webhooks → 0043_backups chain
2026-07-26 03:17:40 +02:00
Agent Zero
10dcc8ae90
Phase 3: Saved Filters UI, Entity History UI, Activity Timeline, API Docs Link
...
- Saved Filters: SavedFilterBar (dropdown, apply, delete), SaveFilterDialog (name + save)
- Entity History: EntityHistoryPanel (timeline, restore, undo), HistoryDiff (field changes visual)
- Activity Timeline: ActivityTimelinePage (grouped by day, pagination), ActivityFilter (user/entity/action/date)
- API Docs Link: TopBar user menu entry, SettingsSystem Entwickler section (Swagger, ReDoc, OpenAPI)
- Routes: /activity registered
- Menu items: Aktivitäten added to automation plugin manifest
2026-07-26 03:08:26 +02:00
Agent Zero
a7e3890634
Phase 2: Tags UI, Custom Fields UI, Notifications Bell
...
- Tags UI: TagsPage (CRUD, color picker), TagBadge, TagSelector (multi-select, inline creation)
- Custom Fields Backend: model, schema, service, routes, migration 0041
- Custom Fields Frontend: CustomFieldsPage (definitions CRUD), CustomFieldRenderer (dynamic field rendering)
- Custom Fields: _collect_custom_field_definitions() extended to merge DB definitions with plugin definitions
- Notifications Bell: NotificationBell (30s polling, unread badge), NotificationDropdown, NotificationItem
- NotificationBell integrated into TopBar
- Routes: /tags, /settings/custom-fields registered
- Settings nav: Custom Fields entry added
- Menu items: Tags added to automation plugin manifest
2026-07-26 03:02:25 +02:00
Agent Zero
a3a5a10514
Phase 1: Workflows UI, Dedup/Merge UI, Import/Export UI, Print/PDF
...
- Workflows UI: full page with definitions/instances tabs, step editor, instance detail with approve/reject
- Dedup/Merge UI: duplicate detection, side-by-side comparison, field-level merge dialog, merge history
- Import/Export UI: import wizard (dry-run preview), export panel (CSV/XLSX), backend export route added
- Print/PDF: PrintButton component, print.css, integrated in Contacts/Calendar/Reports/ContactDetail
- Backend: GET /api/v1/export endpoint, export_companies_csv() service function
- Routes: /workflows, /contacts/dedup, /import-export registered
- Menu items: Workflows, Import/Export, Duplikate added to automation plugin manifest
- IMPLEMENTATION_PLAN.md: audit-corrected plan for all 14 remaining features
2026-07-26 02:35:44 +02:00
Agent Zero
6d484ed747
Fix: handle paginated responses (items wrapper) for dms/automation/agents/ai hooks
2026-07-26 01:35:03 +02:00
Agent Zero
15a6c9b6c6
Fix: useReportPresets handle paginated response (items wrapper)
2026-07-26 01:33:04 +02:00
Agent Zero
90a6a1b929
Fix: useContactFolders handle paginated response (items wrapper)
2026-07-26 01:23:47 +02:00
Agent Zero
727d86614e
Security fixes: P0-P2 complete (22 fixes)
...
P0 (7): Auth-bypass removed, migrations fixed, plugin-upload disabled, RLS FORCE+WITH CHECK, plugin double-registration fixed, persistent volume, domain removed
P1 (11): User/tenant model, Redis centralized, worker separated, transactional outbox, XSS fixed, DMS chunked streaming, permissions unified, password reset, metrics secured, config/docs fixed, cross-tenant FK
P2 (4): Contact model normalized, cross-imports reduced 94%, commands+state machines for contacts/dms/mail/calendar, SPA path-traversal
8 new migrations, 99 unit tests, 13 commands, 8 contracts, 72 files changed
2026-07-25 21:03:46 +02:00
Agent Zero
aaa7406929
perf: Fix all 7 code analysis issues
...
HIGH (Performance):
- Replace 8 sync file operations with aiofiles in async context (storage, mail,
report_generator, dms_bridge, ai_assistant)
- Frontend bundle splitting: manualChunks for react-vendor, ui-components, tanstack,
markdown, icons, utils, i18n (ui chunk 936K → ~19K)
MEDIUM (Architecture):
- Worker circular deps: Replace direct plugin imports with job_registry.py pattern
(register_job/get_all_jobs, importlib-based lazy loading)
- App-wide ErrorBoundary: New ErrorBoundary.tsx component, wrapped in AppShell
and all standalone routes
LOW (Code Quality):
- N+1 query fix: selectinload(Contact.contact_persons) in list_contacts()
- O(n²) dedup fix: SQL GROUP BY for email/phone duplicates, Dict-based name grouping
- Response format standardization: 7 routes converted from plain arrays to
{items: [...], total: N} format
2026-07-25 09:19:32 +02:00
Agent Zero
3e7abd4518
feat: Mini-Apps registry, Stammdaten backend persistence, bank accounts
...
- Register 6 mini-apps in kommunikation plugin (contact_picker, file_share,
calendar_invite, mail_forward, ai_search, task_create)
- Connect AdressenTab to backend API (GET/POST/PATCH/DELETE /addresses)
- Create BankAccount model, schema, service, routes + migration 0033
- Connect KontenTab to backend API (GET/POST/PATCH/DELETE /bank-accounts)
- AI tools already working: 7 tools registered (hybrid_search, get_contact_mails, etc.)
2026-07-25 02:11:29 +02:00
Agent Zero
382f500f39
fix: Add Communication page as explicit route in router
...
- Add /communication route at top level (not inside /settings)
- Add CommunicationPage lazy import alongside other pages
- This ensures the page is properly code-split and loaded in production
2026-07-25 01:43:07 +02:00
Agent Zero
5d5bfb4b38
fix: Communication page, search field mapping, type compatibility
...
- Create Communication.tsx page with tree structure (System, KI, Kollegen)
- Chat window with messages, reactions, attachments, mini-apps
- WebSocket real-time updates
- AI streaming integration for AI conversations
- Fix search.ts: map backend fields (entity_type/entity_id/title/snippet)
to frontend format (type/id/name/description/url)
- Fix hooks.ts: import SearchResult from search.ts instead of redefining
- Fix JSX syntax error in Communication.tsx title attribute
2026-07-25 01:32:20 +02:00
Agent Zero
868bb274ef
feat: standalone buttons for all plugin pages + window system for modals
...
Standalone buttons:
- Add ExternalLink button to Dms, Calendar, Mail, ContactsList toolbars
- Create standalone pages for each (no sidebar, full screen)
- Add standalone routes outside ProtectedRoute
Window system for modals:
- AppointmentModal -> AppointmentEditForm + openWindow()
- ComposeModal -> MailComposeForm + openWindow()
- FilePreviewModal -> FilePreviewContent + openWindow()
- Calendar, Mail, Dms use openWindow() instead of modal state
2026-07-25 00:21:37 +02:00
Agent Zero
2f6c3175a3
feat: add standalone AI assistant window button
...
- Add ExternalLink button to AI assistant toolbar
- New route /ai-assistant-standalone renders AIAssistantPage without sidebar
- Opens in new browser window via window.open
2026-07-24 23:55:18 +02:00
Agent Zero
35e87b5d51
feat: window management system with minimize, fullscreen, and AI chat split
...
- Window manager store (Zustand) for managing open/minimized/fullscreen windows
- Window component with header controls: KI-Chat toggle, fullscreen, minimize, close
- AI chat panel with streaming chat via existing /ai/sessions API
- WindowContainer renders all non-minimized windows
- TopBar shows minimized windows as clickable pills
- ContactEditForm extracted from ContactEditModal for window rendering
- ContactsList and ContactDetailPage use openWindow() instead of modal state
- Draggable windows with z-index management
2026-07-24 23:42:53 +02:00
Agent Zero
c1d49e4dfe
feat: consolidate AI settings into one page with tabs
...
- New SettingsAI page with 3 tabs: KI Assistent, Proaktive KI, MCP
- Remove individual AI/proactive/mcp from settings nav
- Settings nav now 6 items: Stammdaten, Nutzerverwaltung, System, Mail, KI Einstellungen, Benachrichtigungen
2026-07-24 22:46:53 +02:00
Agent Zero
8b3873d676
feat: restructure settings menu + add automation/agents to topbar
...
TopBar:
- Add Automation and Agenten to user dropdown menu
Settings restructure:
- Stammdaten: Firmendaten, Adressen (CRUD), Konten (CRUD), Sonstige Daten
- Nutzerverwaltung: Benutzer, Rollen, Gruppen as tabs
- System: Menü, Theme, Plugins as tabs
- Reduce nav items from 15+ to 8
- Add end prop to all settings NavLinks
2026-07-24 22:35:35 +02:00
Agent Zero
b4121082f7
fix: add end prop to all NavLinks to prevent prefix-matching activation
2026-07-24 22:13:53 +02:00
Agent Zero
046f00e464
fix: remove mail settings, automation/agents from sidebar + settings from bottom
...
- Remove Einstellungen from E-Mail group (accessible via Settings page)
- Remove Automation and Agenten from sidebar (accessible via Topbar profile menu)
- Remove Settings from sidebar bottom items
2026-07-24 22:04:45 +02:00
Agent Zero
e017da9d12
feat: navigation restructure + drag-and-drop menu ordering
...
Navigation:
- Remove Plugins header from sidebar
- Merge static items and plugin items into unified sorted list
- Group related menu items (Dateien, E-Mail, Kalender, Automation)
- German labels for all menu items
- Sort by order field, alphabetical fallback for ties
Drag-and-Drop Menu:
- New backend endpoints: GET/PUT /api/v1/users/me/menu-order
- Store menu order in user preferences JSONB field
- New SettingsMenuOrder page with @dnd-kit drag-and-drop
- New Settings tab: Menu ordering
- Sidebar reads saved menu order and sorts accordingly
- Reset to default option
2026-07-24 21:46:27 +02:00
Agent Zero
4b9cb5a098
fix: Zustand selector anti-pattern causing infinite re-render + plugin loader path
...
- Fix usePluginStore(s => s.getAll*()) selectors that returned new arrays
on every call, causing infinite re-render loops and permanent spinner
- Affected: Sidebar, Settings, ContactDetail, ContactEditModal, PluginRouteRenderer
- Use usePluginStore(s => s.manifests) + useMemo instead
- Fix PluginRouteRenderer: show spinner instead of null when manifests loading
- Fix PluginLoader: @/ path replacement ../ -> ../../ for correct dynamic imports
2026-07-24 19:29:48 +02:00
Agent Zero
2fd4bd123d
fix: restore API response formats + ai-ui-control ws + profile fields
...
- Restore {plugins: [...], total: N} for /plugins and /plugins/active-manifests
(flat array broke frontend PluginRegistry → no menu items → empty UI)
- Restore {count: N} for /notifications/unread-count
(scalar broke frontend notification badge)
- Fix ai_ui_control: on_install → on_activate for WS manager registration
(WS 403 on every reconnect after container restart)
- Fix double /api/v1 prefix in useAIContext.ts and SuggestionBadge.tsx
- Add first_name, last_name, avatar_url to User model + migration 0032
- Extend UserUpdate schema with profile + password change fields
- Extend user_service.update_user with profile fields + password change
- Extend frontend UserResponse/UserUpdate types
2026-07-24 17:17:53 +02:00
Agent Zero
7b4a2c0791
fix: embedding migration, worker error handling, path traversal security, response mismatches (unread-count, plugins, manifests), frontend type safety
2026-07-24 14:23:28 +02:00
Agent Zero
ecab11c19a
fix(dms): add onRangeSelect prop to FileExplorerProps to fix TSC errors
2026-07-24 10:23:23 +02:00
Agent Zero
924d28cbf2
fix: resolve menu duplicates, route prefix conflicts, API path bugs, permissions.deleted_at, remove test plugin from production
2026-07-24 08:19:45 +02:00
Agent Zero
0e5ef789b7
test(7.7): add tests for authStore, uiStore, commStore, pluginToolbarStore, calendarStore
2026-07-24 01:29:49 +02:00
Agent Zero
43c4b623c2
test(7.6): add tests for comm block components (BlockRenderer + all block types)
2026-07-24 01:28:06 +02:00
Agent Zero
2b1dd5f655
test(7.5): add tests for Contact sub-components
...
- ContactDetail: display name, edit/delete buttons, persons, tags, loading/empty states
(stub-based due to OOM from lucide-react namespace import in source)
- ContactEditModal: modal open/close, type select, name input, submit/cancel, edit vs create
(stub-based due to OOM from lucide-react namespace import in source)
- ContactFolderTree: folder tree, all contacts, tags, click handlers, contact counts
All 27 contact sub-component tests passing.
2026-07-24 01:21:24 +02:00
Agent Zero
4f2fa62ffa
test(7.4): add tests for DMS sub-components
...
- FileExplorer: list/table/icons views, file rows, loading/empty states, click handler
- SourceTree: folder tree, loading state, folder/source selection
- FileGrid: file cards, checkboxes, loading/empty states, click handler
- FileDetails: metadata display, preview/share/delete buttons, close handler
- BulkActions: selection bar, move/delete/cancel buttons, file count
All 36 DMS sub-component tests passing.
2026-07-24 00:55:40 +02:00
Agent Zero
6c3ca5bef7
test(7.3): add tests for Calendar pages
...
- CalendarPage: page render, tree/view/detail panes, MonthView default, mobile panes
- CalendarKanban: page render, kanban board, task columns, error handling
All 13 calendar tests passing.
2026-07-24 00:54:16 +02:00
Agent Zero
02024d32b8
test(7.2): add tests for AI components
...
- ChatWindow: messages, input, send button, streaming, error display
- SessionList: sessions, folders, click handler, loading/error states
- SuggestionSidebar: suggestions list, filters, dismiss, close button
- AISettings: tabs (providers, presets, agents, tools), provider list
- ProactiveAISettings: toggle, categories, confidence, rate limit, model
All 40 AI tests passing.
2026-07-24 00:52:34 +02:00
Agent Zero
62127c6544
test(7.1): add tests for untested settings pages
...
- SettingsGroups: page render, create/edit buttons, group list
- SettingsCurrencies: page render, form, API calls, error display
- SettingsTaxes: page render, form, API calls, error display
- SettingsSequences: page render, form, API calls, error display
- SettingsNotifications: page render, notification types, toggles
- SettingsPlugins: page render, install/activate/deactivate buttons
- SettingsSystem: page render, form fields, save button
All 82 settings tests passing.
2026-07-24 00:49:22 +02:00
Agent Zero
761f8d88dc
Phase 6.6: Mail-Settings-Forms on RHF + Zod
...
- MailSettings account form: RHF+Zod (email valid, password required, imap/smtp host required, ports numeric)
- SignatureManager: RHF+Zod (name required, body_html, is_default)
- RuleEditor: RHF+Zod (name required, priority numeric)
- LabelManager: RHF+Zod (name required, color optional)
- VacationResponder: RHF+Zod (enabled, dates with end>start validation, subject, body)
- Error display under each field
- Preserved all existing functionality: CRUD, templates, variables
- Added 2 validation tests for MailSettings account form
2026-07-24 00:38:40 +02:00
Agent Zero
3e8038b75e
Phase 6.5: Tag-Forms on RHF + Zod
...
- TagPicker create-tag form: RHF+Zod (name required, color optional with default)
- Error display under name field
- Color picker uses setTagValue from RHF
- Preserved all existing functionality: search, assign, unassign
- Added 2 validation tests (empty name, valid submit)
2026-07-24 00:33:57 +02:00
Agent Zero
eb2f37b2bc
Phase 6.4: DMS-Forms on RHF + Zod
...
- Dms.tsx folder-create: RHF+Zod (name required)
- ShareDialog add-share: RHF+Zod (shareId required, shareType/permission kept as useState)
- Error display under each field
- Preserved all existing functionality: folder tree, file grid, share links
- Added 2 validation tests for ShareDialog (empty shareId, valid submit)
2026-07-24 00:32:00 +02:00
Agent Zero
c334d02989
Phase 6.3: SettingsForms on RHF + Zod
...
- SettingsCurrencies: RHF+Zod (code required max 3, name required, symbol required max 5)
- SettingsTaxes: RHF+Zod (name required, rate numeric 0-100, country max 2)
- SettingsSequences: RHF+Zod (name required, padding numeric 1-10)
- SettingsUsers: RHF+Zod (name required, email valid, password min 8)
- SettingsRoles: RHF+Zod for create form (name required)
- SettingsGroups: RHF+Zod for create form (name required, description optional)
- Error display under each field
- Preserved all existing functionality: CRUD, permissions, members
- Added 2 validation tests for SettingsCurrencies
2026-07-24 00:28:11 +02:00
Agent Zero
2931a850c0
Phase 6.2: AppointmentModal on RHF + Zod
...
- Migrated AppointmentModal from useState to React Hook Form + Zod
- Zod schema: title (required), calendar_id (required), start_at/end_at (required, end > start)
- Object-level superRefine for date validation (end must be after start)
- Error display via Input error prop and summary error div
- Preserved all existing functionality: create, edit, delete, prefill
- Added 3 validation tests (empty title, end before start, valid submit)
2026-07-24 00:22:31 +02:00
Agent Zero
d4aa661164
Phase 6.1: ComposeModal on RHF + Zod
...
- Migrated ComposeModal from useState to React Hook Form + Zod
- Zod schema: to (required, email list), cc/bcc (optional, email list), subject (required), body
- Object-level superRefine for comma-separated email validation
- Error display under each field via Input error prop
- Preserved all existing functionality: attachments, signatures, templates, drafts
- Added 4 validation tests (empty to, invalid email, empty subject, valid submit)
2026-07-24 00:21:09 +02:00
Agent Zero
036e87a9ed
Task 5.25: Dashboard-System — GET /api/v1/dashboard/widgets, DashboardWidgetLoader, DashboardGrid with drag-and-drop, 3 example widgets (RecentContacts, TasksSummary, CalendarUpcoming), updated Dashboard.tsx, i18n, 6 tests
2026-07-24 00:09:26 +02:00
Agent Zero
96e183bab2
Task 5.24: PWA — vite-plugin-pwa with autoUpdate, manifest, workbox caching, PWAInstallPrompt component, notification helper, SVG icons, 6 tests
2026-07-24 00:01:53 +02:00
Agent Zero
d54a87cf84
Task 5.23: Deduplication / Merge — ContactMergeHistory model, dedup service, API routes (duplicates/merge/merge-history), DedupDialog frontend, i18n, 5 tests
2026-07-23 23:58:45 +02:00
Agent Zero
182af355d1
feat(5.22): Saved Searches / Smart Lists — reusable filters for list views
...
- SavedFilter model with TenantMixin (name, entity_type, filter_criteria JSONB, user_id)
- Routes: GET/POST /saved-filters, DELETE /saved-filters/{id} with RBAC
- Alembic migration 0029_saved_filters creates saved_filters table
- Frontend: SavedFilters.tsx component with save/load/delete UI
- Frontend: api/savedFilters.ts with React Query hooks
- Integrated into ContactsListPage as example
- i18n keys for savedFilters.* in de.json and en.json
- Tests: test_saved_filters.py (9 tests) + SavedFilters.test.tsx (3 tests)
- Registered SavedFilter in conftest.py
2026-07-23 23:44:50 +02:00
Agent Zero
2c9e74776e
feat(5.21): Tasks Plugin — activities with status, priority, due dates, ARQ reminders
...
- New builtin plugin app/plugins/builtins/tasks/ with full CRUD
- Task model with TenantMixin (title, description, status, priority, due_date, assigned_to, contact_id)
- Routes: GET/POST /tasks, GET/PATCH/DELETE /tasks/{id}, POST /tasks/{id}/assign, POST /tasks/{id}/status
- All routes RBAC-protected (tasks:read, tasks:write, tasks:delete)
- ARQ cron job tasks_due_reminder (daily 8:00) sends notifications for due tasks
- Migration 0001_initial.sql creates tasks table with indexes
- Frontend: Tasks.tsx page with list, filter, create/edit modal, detail modal
- Frontend: api/tasks.ts with React Query hooks
- Route /tasks in routes/index.tsx, sidebar entry via plugin manifest
- i18n keys for nav.tasks and tasks.* in de.json and en.json
- Tests: test_tasks.py (11 tests) + Tasks.test.tsx (3 tests)
- Registered TasksPlugin in conftest.py and worker.py
2026-07-23 23:41:34 +02:00
Agent Zero
bdad91a649
feat(5.20): Custom Fields — plugin-defined fields in Contact UI
...
- Add CustomFieldDefinition to PluginManifest (text/number/date/select/multiselect/boolean)
- Add GET/PATCH /api/v1/contacts/{id}/custom-fields routes
- Merge plugin definitions with stored values in contacts.custom JSONB
- Add CustomFieldRenderer component (read + edit modes)
- Integrate into ContactDetail (read-only) and ContactEditModal (editable)
- Add custom_fields to pluginStore and active manifests API
- Add useCustomFields/useUpdateCustomFields React Query hooks
- Tests: test_custom_fields.py (9 tests) + CustomFieldRenderer.test.tsx (5 tests)
- i18n keys already present (contacts.customFields)
2026-07-23 23:35:35 +02:00
Agent Zero
0ec8502fd4
Phase 5 Batch 5 Task 5.19: Report Generator Frontend-Oberfläche
...
- Created frontend/src/api/reports.ts: React Query hooks for templates, presets, generate
- Created frontend/src/pages/Reports.tsx: 3-column layout (template list, editor, generate)
- Preset quick-action buttons with format selection (PDF/Print/CSV/Excel)
- Template editor with Jinja2 code textarea, name, output format selector
- JSON data input for report parameters
- Download history tracking
- Route /reports registered in index.tsx (lazy-loaded)
- i18n keys added to de.json and en.json (reports section + nav.reports)
- 5 frontend tests: page render, template list, new template, select template, download history
- TSC: 0 new errors (2 pre-existing Dms.tsx errors only)
2026-07-23 23:26:40 +02:00
Agent Zero
317d5c81f8
feat: MCP Client plugin (Task 5.17) - integrate external MCP servers for AI agents
...
- New plugin app/plugins/builtins/mcp_client/ with server config CRUD
- Models: McpServerConfig with TenantMixin (name, url, api_token, enabled)
- Routes: GET/POST/PATCH/DELETE /api/v1/mcp-client/servers
- Routes: GET /servers/{id}/tools, POST /servers/{id}/execute
- client.py: async MCP client using httpx for external server calls
- tool_registry_integration.py: registers external MCP tools in AI tool registry
- Migration: 0001_initial.sql for mcp_server_configs table
- Frontend: mcpClient.ts API client with React Query hooks
- Frontend: MCP Client settings UI in SettingsMcp.tsx (server CRUD, tool viewing)
- Tests: 8 tests covering CRUD, auth, tool registry integration
2026-07-23 23:02:07 +02:00
Agent Zero
9d4f701a25
feat: MCP Server plugin (Task 5.16) - expose LeoCRM tools to external AI clients
...
- New plugin app/plugins/builtins/mcp_server/ with 9 MCP tools
- Tools: search_contacts, get_contact, create_contact, list_calendar_entries,
create_calendar_entry, list_emails, send_email, list_files, upload_file
- Routes: GET /api/v1/mcp/tools, POST /api/v1/mcp/tools/{name}/execute, GET /api/v1/mcp/config
- API-token auth via session + RBAC (mcp:read, mcp:write)
- Frontend: mcp.ts API client with React Query hooks
- Frontend: SettingsMcp.tsx settings page with tool listing and execution
- i18n: de.json and en.json updated with MCP entries
- Tests: 7 tests covering tool listing, config, execution, auth, schema validation
2026-07-23 23:01:59 +02:00
Agent Zero
75a7063bff
feat(5.2): add User Preferences API with full-stack implementation
...
Backend:
- Create app/models/user_preference.py with TenantMixin (user_id, key, value JSONB)
- Create app/routes/user_preferences.py with GET/PUT/DELETE endpoints + RBAC
- Add user_preferences:read/write to CORE_PERMISSIONS
- Add user_preferences to legacy role permissions (admin/editor/viewer)
- Register route in app/main.py and app/routes/__init__.py
- Create alembic migration 0028_user_preferences
- Add UserPreference model to conftest.py for test schema
- Fix pre-existing conftest seed (Contact industry field removed in migration 0027)
Frontend:
- Create frontend/src/api/userPreferences.ts with React Query hooks
- Create frontend/src/hooks/useUserPreferences.ts syncing with uiStore
- Add i18n entries for de.json and en.json
Tests:
- 13 tests covering CRUD, tenant isolation, CSRF, unauthenticated access
- All tests passing
2026-07-23 20:39:42 +02:00