# LeoCRM — Master Plan: Umbau & Vollendung **Erstellt:** 2026-07-22 **Status:** Draft — zur Freigabe **Letzte Revision:** 2026-07-22 (gründliche Überprüfung nach Code-Tiefenanalyse) --- ## Ausgangslage ### Was bereits gut ist - Backend: ~35.800 Zeilen, 12 Plugins, Multi-Tenant mit RLS, Rate Limiting, Audit Log - Unified Contact Model: **BEREITS implementiert** (Migration 0021) — Contact mit type='company'|'person', ContactPerson als 1:N child (wie Rentman) - Frontend: ~30.000 Zeilen, 27 Pages, 70 Components, i18n DE/EN, TanStack Query, TipTap - Tests: ~17.300 Zeilen Backend-Tests, 38 Vitest-Dateien - Docker: Multi-Stage-Build (Frontend+Backend in einem Container) - Datenbank: PostgreSQL 16 als separater docker-compose Service - WebSocket-Infrastruktur: Bereits im `kommunikation` Plugin vorhanden (`/api/v1/comm/ws`) — kann als Referenz für KI-UI-Steuerung dienen ### Was fehlt oder nicht stimmt - Frontend nutzt unified Contact Model nicht vollständig (keine Contact-Detail-Route, ContactPerson-Verwaltung fehlt in UI) - **'company' als entity_type ist in 6 Plugins verankert** — muss zu 'contact' vereinheitlicht werden - Plugin-UI-System fehlt (hartkodierte Routes statt dynamische Registry) - Code-Splitting fehlt (alle 27 Pages im Main Bundle) - E2E Tests fehlen komplett - KI-UI-Steuerung fehlt - Virtual Scrolling fehlt - React Hook Form + Zod nicht überall - hooks.ts ist Monolith (1.298 Zeilen) - Fehlende Dependencies (lucide-react, date-fns) - Plugin-Richtlinien fehlen ### Wichtige Unterscheidung: 'company' hat zwei Bedeutungen 1. **entity_type='company'** in Plugins (entity_links, calendar, tags, mail) → referenziert eine Firma als Entität → **MUSS zu 'contact' werden** 2. **system_settings.company_*** Felder (company_name, company_street etc.) → CRM-Besitzer-Firmeninfo für Rechnungen → **BLEIBT wie es ist** 3. **CalendarType='company'** → Kalender-Typ (Firmenkalender) → kann bleiben oder zu 'organization' umbenannt werden (kosmetisch) --- ## Architektur-Entscheidungen (freigegeben 2026-07-22) 1. **KI-UI-Steuerung:** Keine Mausbewegung nötig. KI muss zu Kontakten springen und einen Kontakt öffnen können. Die UI muss das Ergebnis zeigen — Kontaktliste und spezieller Kontakt ausgewählt. Implementierungsweg (WebSocket, postMessage, etc.) ist offen, Hauptsache das Ergebnis wird in der UI sichtbar. 2. **Company-Routes:** Komplett entfernen. Keine deprecated-Routes, keine Redirects. Kontakte wie in Rentman — ein unified Contact-Modell, kein separates Company-Modell mehr. **Alle Plugin-Referenzen auf entity_type='company' müssen zu 'contact' migriert werden.** 3. **PostgreSQL:** Aktuell egal (Coolify-managed oder docker-compose). Reine Docker-Lösung soll später möglich sein. Keine Code-Änderung nötig — nur Konfiguration. 4. **S3-Storage:** Provider egal. Wichtig ist nur dass die Architektur es später ermöglicht. Bereits vorbereitet in config.py (STORAGE_BACKEND=s3). --- ## Phasen-Plan ### PHASE 0: Vorbereitung & Cleanup **Ziel:** Codebasis bereinigen, Dependencies installieren, veraltete Dokumente aktualisieren | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 0.1 | Veraltete Planungsdokumente aktualisieren | 2h | `codebase-vs-requirements.md` neu schreiben (beschreibt alten Stand), `architecture.md` um Implementation-Status erweitern, `security-review-phase2.md` um 'Resolved' Markierungen ergänzen | | 0.2 | `lucide-react` installieren + Icons migrieren | 4h | Inline SVGs durch lucide-react Icons ersetzen. Konsistente Icon-Bibliothek. | | 0.3 | `date-fns` installieren + Datum-Formatierung | 3h | Alle `toLocaleDateString()` etc. durch date-fns ersetzen. Konsistente Datum-Formatierung. | | 0.4 | `hooks.ts` aufteilen | 3h | 1.298 Zeilen aufteilen in `api/auth.ts`, `api/contacts.ts`, `api/settings.ts` etc. Generische Hooks bleiben in `hooks.ts`. Company-Hooks werden in Phase 1 entfernt, nicht aufgeteilt. | | 0.5 | Store-Verzeichnis konsolidieren | 1h | `store/` und `stores/` zusammenführen. | | 0.6 | Frontend-Bestandsanalyse als Dokument speichern | 1h | `frontend-gap-analysis.md` mit vollständiger Analyse. | | 0.7 | UI-Design-Richtlinien erstellen | 6h | `docs/ui-design-guidelines.md` basierend auf bestehenden Plugin-Patterns (siehe unten). | | 0.8 | Theme-Customization Backend | 4h | `system_settings` um Theme-Felder erweitern (primary_color, accent_color, font_family, border_radius). Neue Alembic-Migration. API-Endpoints zum Lesen/Schreiben der Theme-Settings. | | 0.9 | Theme-Customization Frontend | 6h | `SettingsTheme.tsx` Seite mit Color-Picker, Font-Auswahl, Live-Preview. Tailwind-CSS-Variablen dynamisch aus API-Settings überschreiben. Dark-Mode-Toggle. Theme wird beim App-Start geladen und angewendet. | | 0.10 | RBAC-Audit & Plugin-Permissions nachrüsten | 6h | 4 Plugins haben `permissions=[]` (calendar, dms, entity_links, tags) → keine Rechte-Prüfung! Pro Plugin passende Permissions definieren und in Manifest eintragen. Routes mit `require_permission()` absichern. Siehe Details unten. | | 0.11 | LiteLLM-Cleanup & alte llm_client.py migrieren | 3h | LiteLLM ist **BEREITS** in ai_assistant und ai_proactive integriert (`litellm.acompletion()`). Nur die alte `llm_client.py` (Copilot) nutzt noch httpx direkt. Diese auf LiteLLM umstellen oder entfernen. System-Prompt in llm_client.py referenziert noch `/api/v1/companies` → auf Contacts umstellen. | | 0.12 | KI-Agent-Framework in Plugin-Richtlinien dokumentieren | 2h | PydanticAI + tool_registry existieren bereits. In `docs/plugin-development-guide.md` dokumentieren: Wie Plugins KI-Agenten, Tools und LLM-Funktionen nutzen. Plugin-Manifest um `agent_capabilities` Feld erweitern. | | 0.13 | Heartbeat konfigurierbar machen | 3h | Heartbeat-Intervall, Aktivierung, Ziel-Room in ProactiveSettings (DB) speichern. Settings-UI für Heartbeat-Konfiguration. | | 0.14 | Unified Search: Field-Level RBAC nachrüsten | 4h | Search-Provider prüfen aktuell KEINE Feld-Level-Permissions. Nutzer mit `search:read` sieht alle Felder. Provider müssen `resolved_perms` prüfen und `hidden` Felder ausblenden. `to_search_result()` um Permission-Filter ergänzen. | | 0.15 | Undo/History-System für CRUD-Operationen | 8h | Globale Undo-History: Jede CRUD-Aktion (Create/Update/Delete) wird mit Snapshot in `entity_history` Tabelle gespeichert. User kann Änderungen rückgängig machen oder zu früherer Version zurückkehren. Nutzt bestehenden Audit-Log als Basis. Frontend: Undo-Button + History-Viewer pro Entity. | | 0.16 | Storage Backend implementieren (S3-Support) | 8h | Architecture.md beschreibt abstract StorageBackend (local/S3), aber **existiert NICHT im Code**. Attachments nutzen hardcoded `/data/uploads`. Storage-Klasse erstellen: `LocalStorage` + `S3Storage`. Config um `STORAGE_BACKEND`, `S3_ENDPOINT`, `S3_BUCKET`, `S3_ACCESS_KEY`, `S3_SECRET_KEY` erweitern. DMS und Attachments auf Storage-Backend umstellen. .env.example um S3-Variablen ergänzen. | | 0.17 | Import/Export an unified Contact Model anpassen | 4h | Import/Export nutzt alte Feldnamen (`first_name`, `last_name`, `mobile`, `position`, `department`). Auf unified Contact-Felder umstellen (`firstname`, `surname`, `phone_1`, `email_1`, etc.). Company-Import auf Contact mit type='company' umstellen. | | 0.18 | .gitignore & Config-Cleanup | 2h | `.gitignore` hat `webui/` statt `frontend/` — frontend/node_modules und frontend/dist werden nicht ignoriert! Korrigieren. `python-jose` (JWT) aus requirements.txt entfernen — Code nutzt Session-Auth. `pyproject.toml` Python-Version auf 3.12 aktualisieren. `.env.docker.example` JWT-Variablen entfernen. **.env aus Git entfernen** (ist committet aber sollte nicht sein). `dump.rdb` und `test.txt` aus Repo löschen. `frontend/dist/` aus Git entfernen (sollte nicht committet sein). | | 0.19 | Mail-Salt Security-Fix | 2h | `mail/services.py` hat hardcoded salt `b"leocrm-mail-salt"` für Passwort-Verschlüsselung. Salt sollte random pro Account sein. Fix: Random salt generieren und mit encrypted_password zusammen speichern. DB-Migration für bestehende Accounts. | | 0.20 | AGPL-Lizenzen durch kommerziell nutzbare Alternativen ersetzen | 6h | **PyMuPDF** (AGPL-3.0) → ersetzen durch `pypdf` (BSD). Text-Extraktion in unified_search anpassen. **OnlyOffice** (AGPL-3.0) → ersetzen durch **Collabora Online** (LGPL/MPL). DMS Edit-Sessions auf Collabora umstellen. `requirements.txt`, `Dockerfile`, `docker-compose.yml`, `architecture.md` aktualisieren. DMS Plugin `OnlyOfficeConfig` → `CollaboraConfig`. Frontend DMS-Komponenten anpassen. Lizenz-Datei (`LICENSE`) und `THIRD_PARTY_LICENSES.md` erstellen. | **Phase 0 Gesamt: ~77h** ### UI-Design-Richtlinien (Task 0.7) Basierend auf Analyse der bestehenden Plugins (Calendar, Mail, DMS, Contacts): **Layout-Patterns:** - **3-Spalten-Explorer-Layout** (Tree | Liste/Explorer | Detail) — verwendet von Calendar, Mail, DMS - **ResizablePanel** für drag-to-resize Spalten — bereits implementiert - **PluginToolbar** für Plugin-Aktionen (oben) — bereits implementiert - **Modal** für Formulare (Create/Edit/Delete-Bestätigung) — bereits implementiert - **EmptyState** für leere Listen — bereits implementiert - **LoadingState/Skeleton** für Lade-Zustände — bereits implementiert **Farbsystem (Tailwind Design Tokens):** - `primary` (Blau #2563eb) — Hauptaktionen, aktive Zustände - `secondary` (Slate #64748b) — Text, Borders, Hintergründe - `accent` (Fuchsia #d946ef) — Hervorhebungen, Info-Badges - `danger` (Rot #dc2626) — Löschen, Fehler - `warning` (Amber #f59e0b) — Warnungen - `success` (Grün #16a34a) — Erfolg, Bestätigungen - Jede Farbe mit 50-900 Schattierungen - **Dark Mode** via `darkMode: 'class'` — CSS-Variablen in `:root` und `.dark` **Typografie:** - Font: `Inter` (system-ui fallback) - Mono: `JetBrains Mono` für Code/Daten - Größen: xs (0.75rem) bis 4xl (2.25rem) - Zeilenhöhen definiert pro Größe **Komponenten-Konventionen:** - **Button**: 4 Varianten (primary/secondary/danger/ghost), 3 Größen (sm/md/lg), `min-h-touch` (44px), `focus-visible:ring-2` - **Card**: Titel + Beschreibung + Actions (header), Body, optional Footer (bg-secondary-50) - **Badge**: 7 Varianten (default/primary/success/warning/danger/info/secondary), optional dot - **Input/Select**: `focus-ring` Klasse, `border-secondary-200`, `rounded-md` - **Modal**: `size` prop (sm/md/lg/xl), `ConfirmDialog` für Bestätigungen - **Table/DataGrid**: TanStack Table, ARIA-labels auf sortierbare Headers - **Toast**: `useToast()` Hook für Benachrichtigungen **Spacing & Layout:** - Standard-Padding: `px-6 py-4` (Card body), `p-4` (Panel) - Gap: `gap-2` (Buttons), `gap-4` (Sections), `gap-6` (Columns) - Border-Radius: `rounded-md` (0.5rem) Standard, `rounded-lg` (0.75rem) für Cards - Shadow: `shadow-sm` (Cards), `shadow-md` (Dropdowns), `shadow-lg` (Modals) **Accessibility (bereits implementiert):** - `focus-ring` Klasse: `focus-visible:ring-2 focus-visible:ring-primary-500` - `btn-touch` Klasse: `min-h-touch min-w-touch` (44px) - `sr-only` und `sr-only-focusable` Klassen - `prefers-reduced-motion` Media Query - `aria-hidden="true"` auf dekorativen SVGs - `aria-label` auf interaktiven Elementen ohne sichtbaren Text **Plugin-UI-Patterns (für neue Plugins):** - Jede Plugin-Seite folgt dem 3-Spalten-Layout (wenn anwendbar) - PluginToolbar für Aktionen (Create, Import, Export, etc.) - Plugin-Settings als eigene Settings-Sub-Seite - Plugin-Detail-Tabs (z.B. "Dateien" bei Contact-Detail) - Konsistente EmptyState-Komponente wenn keine Daten - Konsistente LoadingState/Skeleton-Komponente beim Laden - Toast für Erfolg/Fehler-Meldungen nach Aktionen - ConfirmDialog vor destruktiven Aktionen **Was im Design-Guide dokumentiert wird:** 1. Farbsystem mit Verwendungsregeln (wann welche Farbe) 2. Typografie-Hierarchie (Überschriften, Body-Text, Labels) 3. Layout-Patterns (3-Spalten, Modal, Settings-Tree) 4. Komponenten-Verwendung (welche Komponente für was) 5. Spacing & Sizing Konventionen 6. Accessibility-Regeln 7. Dark-Mode-Regeln 8. Plugin-UI-Patterns für neue Plugins 9. Do's & Don'ts 10. Code-Beispiele aus bestehenden Plugins ### RBAC-Audit & Plugin-Permissions (Task 0.10) **Problem:** 4 Plugins haben `permissions=[]` im Manifest → keine Rechte-Prüfung auf ihren Routes: | Plugin | Aktuell | Muss definiert werden | |---|---|---| | **calendar** | `permissions=[]` | `calendar:read`, `calendar:write`, `calendar:delete`, `calendar:share`, `calendar:admin` | | **dms** | `permissions=[]` | `dms:read`, `dms:write`, `dms:delete`, `dms:share`, `dms:admin` | | **entity_links** | `permissions=[]` | `entity_links:read`, `entity_links:write`, `entity_links:delete` | | **tags** | `permissions=[]` | `tags:read`, `tags:write`, `tags:delete`, `tags:admin` | **Was zu tun ist:** 1. Pro Plugin passende Permissions im Manifest definieren 2. Alle Plugin-Routes mit `require_permission()` absichern 3. Permission-Registry registriert Plugin-Permissions automatisch beim Aktivieren 4. Admin kann Permissions in Rollen-Editor zuweisen 5. Tests: User ohne Permission → 403, User mit Permission → 200 **Zusätzlich in Phase 1 (Permission-Registry-Cleanup):** - `companies:read/write/delete` aus `CORE_PERMISSIONS` entfernen (wird zu `contacts:read/write/delete`) - `CORE_FIELD_DEFINITIONS` aktualisieren: alte Felder (`first_name`, `last_name`, `mobile`, `position`, `department`, `linkedin_url`) durch unified Contact-Felder ersetzen (`firstname`, `surname`, `phone_1`, `email_1`, etc.) - `companies` Field-Definitions entfernen ### LiteLLM-Integration (Task 0.11) **Problem:** Aktuelle `llm_client.py` spricht nur OpenAI-compatible API direkt via httpx. Keine Unterstützung für Anthropic, Google, lokale Modelle etc. **Lösung:** LiteLLM als unified LLM-Interface integrieren. **Was LiteLLM bietet:** - 100+ LLM-Provider über eine einheitliche API (OpenAI, Anthropic, Google, Azure, AWS Bedrock, Ollama, etc.) - Konsistente Request/Response-Formate - Streaming-Support - Fallback/Routing-Regeln - Cost-Tracking - Rate-Limiting **Was zu tun ist:** 1. `litellm` als Python-Dependency hinzufügen 2. `llm_client.py` auf LiteLLM umstellen: `litellm.acompletion()` statt direktem httpx-Call 3. Konfiguration via Env-Vars: `AI_MODEL`, `AI_API_KEY`, `AI_API_BASE` (bleiben gleich), plus `AI_PROVIDER` (neu: openai/anthropic/google/ollama/etc.) 4. AI Assistant Plugin nutzt LiteLLM für Multi-Provider-Support 5. AI Proactive Plugin nutzt LiteLLM für Suggestions 6. Zukünftige Plugins können LiteLLM einfach nutzen — einheitliches Interface 7. Mock-Mode für Tests beibehalten (wenn kein API-Key gesetzt) 8. Plugin-Entwickler-Richtlinien: Wie man LiteLLM in neuen Plugins nutzt **Architektur:** ``` Plugin (ai_assistant, ai_proactive, zukünftige) ↓ LiteLLM (unified LLM interface) ↓ Provider (OpenAI, Anthropic, Google, Ollama, ...) ``` **Vorteil für zukünftige Plugins:** - Ein Plugin kann LLM-Funktionen nutzen ohne sich um den Provider zu kümmern - Admin kann Provider in Settings konfigurieren - KI-Modelle können ausgetauscht werden ohne Code-Änderung --- ### PHASE 1: Unified Contact Model — Vollendung (Backend + Frontend) **Ziel:** 'company' als separates Konzept komplett entfernen. Alles ist 'contact' mit type='company'|'person'. Wie Rentman. #### 1A: Backend — Company-Routes & Services entfernen | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 1.1 | `app/routes/companies.py` entfernen | 1h | 303 Zeilen. Router aus `main.py`/`routes/__init__.py` austragen. | | 1.2 | `app/services/company_service.py` entfernen | 1h | 273 Zeilen. Importe aus `services/__init__.py` entfernen. | | 1.3 | `app/models/company.py` entfernen | 1h | Backward-compat shim. Importe überall auf `Contact` umstellen. | | 1.4 | `app/schemas/company.py` entfernen | 1h | CompanyCreate, CompanyUpdate, CompanyResponse etc. | | 1.5 | `app/ai/action_mapper.py` aktualisieren | 3h | Company-Intents (create_company, delete_company, update_company, list_company) auf Contact-API umstellen. Regex-Patterns anpassen. | | 1.6 | `app/workflows/engine.py` aktualisieren | 1h | Event `company.created` → `contact.created`. Workflow-Trigger anpassen. | | 1.7 | `app/core/worker.py` aktualisieren | 1h | `index_company` Referenzen → `index_contact`. | | 1.8 | `app/core/seeds.py` prüfen/aktualisieren | 1h | Falls Company-Seed-Daten existieren, auf Contact mit type='company' umstellen. | **1A Gesamt: ~10h** #### 1B: Backend — Plugins von entity_type='company' befreien | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 1.9 | **entity_links Plugin** aktualisieren | 4h | `entity_type` Pattern von `^(company|contact)$` → `^contact$`. `company_router` entfernen. `on_company_deleted` → `on_contact_deleted`. Event `company.deleted` → `contact.deleted`. DB-Migration: bestehende EntityLinks mit entity_type='company' auf 'contact' migrieren. | | 1.10 | **unified_search Plugin** aktualisieren | 6h | `CompanySearchProvider` → wird zu `ContactSearchProvider` oder bleibt als Provider für type='company' Kontakte. `index_company` → `index_contact`. Events `company.created/updated` → `contact.created/updated`. `search_engine.py` Mapping `"company" → "contacts"` anpassen. `jobs.py` aktualisieren. | | 1.11 | **calendar Plugin** aktualisieren | 3h | `entity_type` Pattern von `^(company|contact)$` → `^contact$`. CalendarEntryLink entity_type anpassen. DB-Migration: bestehende Links migrieren. CalendarType='company' kann bleiben (Kalender-Typ, nicht Entity-Referenz). | | 1.12 | **tags Plugin** aktualisieren | 3h | `entity_type` Pattern von `^(company|contact|file|folder)$` → `^(contact|file|folder)$`. DB-Migration: bestehende Tag-Assignments mit entity_type='company' auf 'contact' migrieren. | | 1.13 | **mail Plugin** aktualisieren | 4h | `mail.company_id` Spalte → `mail.contact_id` (DB-Migration). Routes, Schemas, Services aktualisieren. `company_id` Referenzen in Frontend-API-Modul. | | 1.14 | **test_sample Plugin** aktualisieren | 1h | `company.created` Event → `contact.created`. Test-Plugin ist Referenz für Plugin-Entwicklung. | | 1.15 | **Event-Namen vereinheitlichen** | 2h | Alle `company.created/updated/deleted` Events → `contact.created/updated/deleted`. Event-Publisher in contact_service.py prüfen. | | 1.16 | **DB-Migration: entity_type 'company' → 'contact'** | 3h | Alembic-Migration: UPDATE entity_links SET entity_type='contact' WHERE entity_type='company'. UPDATE tag_assignments SET entity_type='contact' WHERE entity_type='company'. UPDATE calendar_entry_links SET entity_type='contact' WHERE entity_type='company'. ALTER TABLE mails RENAME COLUMN company_id TO contact_id. | | 1.17 | **Backend-Tests aktualisieren** | 4h | Alle Tests die Company-Routes oder entity_type='company' referenzieren umstellen. `test_companies.py` entfernen oder zu Contact-Tests umschreiben. | | 1.18 | **Permission-Registry-Cleanup** | 3h | `companies:read/write/delete` aus `CORE_PERMISSIONS` entfernen. `CORE_FIELD_DEFINITIONS` aktualisieren: alte Felder durch unified Contact-Felder ersetzen. `companies` Field-Definitions entfernen. | | 1.19 | **Addresses entity_type='company' → 'contact'** | 2h | `address_service.py` `VALID_ENTITY_TYPES` von `{"company", "contact"}` → `{"contact"}`. `address.py` Model anpassen. DB-Migration: bestehende Adressen mit entity_type='company' auf 'contact' migrieren. | | 1.20 | **conftest.py aktualisieren** | 2h | `conftest.py` importiert `Company` und `CompanyContact` aus alten Modellen. Auf unified Contact Model umstellen. Test-Fixtures anpassen. | **1B Gesamt: ~33h** #### 1C: Frontend — Unified Contact UI | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 1.18 | Contact-Detail-Route hinzufügen | 2h | Route `/contacts/:id` in `routes/index.tsx`. `ContactDetail.tsx` (372 Zeilen) existiert bereits als Komponente. | | 1.19 | ContactList mit Type-Filter (company/person) | 4h | `ContactsList.tsx` (445 Zeilen) um Type-Filter erweitern. Tabs oder Toggle: "Alle | Firmen | Personen". | | 1.20 | ContactDetail um ContactPerson-Verwaltung erweitern | 8h | Bei type='company': Ansprechpartner-Liste, Ansprechpartner hinzufügen/bearbeiten/löschen. ContactPerson API-Hooks in Frontend. | | 1.21 | ContactEditModal für beide Types | 6h | Formular je nach type unterschiedlich: company → name, person → firstname/surname. Adressen (mailing/visit/invoice). | | 1.22 | Company-Hooks aus `hooks.ts` entfernen | 2h | `useCompanies`, `useCompany`, `useCreateCompany`, `useUpdateCompany`, `useDeleteCompany`, `useCompanyExport`, `useCompanyImport` entfernen. Company-Interface entfernen. | | 1.23 | Frontend Type-Definitions aktualisieren | 2h | `calendar.ts`: entity_type 'company' → 'contact'. `tags.ts`: EntityType 'company' entfernen. `search.ts`: type 'company' → 'contact'. `mail.ts`: company_id → contact_id. | | 1.24 | Dashboard.tsx aktualisieren | 1h | `useUnifiedContacts(1, 1, undefined, 'company')` → `useUnifiedContacts(1, 1, undefined, 'company')` (type-Filter bleibt, ist jetzt Contact type nicht Company entity). | | 1.25 | GlobalSearchResults.tsx aktualisieren | 2h | Search result type 'company' → 'contact'. Grouping, Icons, Labels anpassen. | | 1.26 | ContactFolderTree in ContactList integrieren | 4h | Ordner-Baum links, Kontaktliste rechts. Drag & Drop Kontakte in Ordner. | | 1.27 | React Hook Form + Zod in ContactEditModal | 3h | Strukturierte Validierung für alle Contact-Felder. | | 1.28 | Frontend-Tests aktualisieren | 4h | Tests für Contact-Detail, ContactEditModal, ContactPerson-Verwaltung. Company-Test-Referenzen entfernen. | **1C Gesamt: ~38h** **Phase 1 Gesamt: ~81h** (vorher 33h — unterschätzt um 48h!) --- ### PHASE 2: Code-Splitting & Performance **Ziel:** Frontend lädt nur was nötig ist. Virtual Scrolling überall. | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 2.1 | React.lazy + Suspense für alle Routes | 4h | Alle Page-Imports in `routes/index.tsx` auf `React.lazy()` umstellen. `` mit Loading-Fallback. | | 2.2 | `@tanstack/react-virtual` installieren | 1h | Dependency hinzufügen. | | 2.3 | Virtual Scrolling in DataGrid | 6h | `DataGrid.tsx` um Virtual Scrolling erweitern. Nur sichtbare Zeilen rendern. | | 2.4 | Virtual Scrolling in MailList | 4h | `MailList.tsx` um Virtual Scrolling erweitern. | | 2.5 | Virtual Scrolling in ContactList | 4h | `ContactList.tsx` um Virtual Scrolling erweitern. | | 2.6 | Virtual Scrolling in allen anderen Listen | 4h | AuditLog, Calendar Entries, DMS FileGrid, etc. | | 2.7 | Bundle-Analyse & Optimierung | 2h | `vite-bundle-visualizer` prüfen, manuelle Chunks für große Dependencies. | **Phase 2 Gesamt: ~25h** --- ### PHASE 3: Plugin-UI-System (WordPress-Style) **Ziel:** Dynamisches Plugin-UI-Loading. Plugins registrieren sich selbst. | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 3.1 | Plugin-Manifest-Frontend-Endpoint | 4h | Backend-Endpoint `GET /api/v1/plugins/active-manifests` liefert alle aktiven Plugin-Manifeste mit UI-Definitionen (routes, menu_items, detail_tabs, settings_pages, dashboard_widgets). | | 3.2 | `PluginRegistry.tsx` erstellen | 8h | Fetcht aktive Plugin-Manifeste beim App-Start. Registriert Routes, Menu-Items, Detail-Tabs, Settings-Pages dynamisch. | | 3.3 | `PluginLoader.tsx` erstellen | 6h | Lazy-loaded Plugin-Komponenten via `React.lazy()`. Suspense-Boundaries pro Plugin. Error-Boundary falls Plugin nicht lädt. | | 3.4 | Sidebar dynamisch aus Plugin-Manifesten | 4h | Sidebar rendert Menu-Items aus Plugin-Registry statt hartkodierte Items. | | 3.5 | Settings-Baum dynamisch aus Plugin-Manifesten | 4h | Settings-Pages werden dynamisch aus Plugin-Manifesten generiert. | | 3.6 | Detail-Tabs dynamisch (Contact-Detail) | 4h | Plugin-Detail-Tabs (z.B. "Dateien", "E-Mails", "Kalender") werden dynamisch gerendert. | | 3.7 | Plugin-Routen aus hartkodiertem Router entfernen | 4h | Statische Plugin-Imports aus `routes/index.tsx` entfernen. Alles über PluginRegistry. | | 3.8 | Plugin-Entwickler-Richtlinien erstellen | 8h | `docs/plugin-development-guide.md`: Manifest-Format, Lifecycle, UI-Registrierung, Event-Bus, Migration-Runner, Service-Container, Beispiele, Do's & Don'ts, Testing-Guide. | | 3.9 | Plugin-Templates / Boilerplate | 4h | `templates/plugin-template/`: Minimal-Plugin als Startpunkt für neue Plugins. Mit Manifest, Routes, Models, Schemas, Migration, Tests. | | 3.10 | Tests für Plugin-UI-System | 4h | Vitest-Tests für PluginRegistry, PluginLoader, dynamische Sidebar/Settings. | | 3.10b | Plugin-Install-System | 8h | Plugins einfach installierbar machen: ZIP-Upload, URL-Install, Plugin-Marketplace-Integration. Plugin-Upload-Endpoint, Validierung (Manifest prüfen, tenant_id-Check, Security-Scan), automatische Migration bei Install. Install-UI in SettingsPlugins.tsx. | **Phase 3 Gesamt: ~58h** --- ### PHASE 3.5: Automation & Agents Plugin **Ziel:** Zentrale Oberfläche für Automatisierungen und selbst-arbeitende KI-Agenten. Plugins können Agenten und Automation-Templates mitbringen. **Architektur:** ``` ┌─────────────────────────────────────────────┐ │ Automation & Agents UI │ │ ┌─────────────┐ ┌─────────────────────┐ │ │ │ Automation │ │ Agent Builder │ │ │ │ Builder │ │ - Agent definieren │ │ │ │ - Trigger │ │ - Tools auswählen │ │ │ │ - Schedule │ │ - LLM-Modell wählen │ │ │ │ - Conditions │ │ - Heartbeat setzen │ │ │ │ - Actions │ │ - Proaktiv/Reaktiv │ │ │ └─────────────┘ └─────────────────────┘ │ ├─────────────────────────────────────────────┤ │ Cron-Scheduler │ Workflow-Timeouts │ HB │ ├─────────────────────────────────────────────┤ │ Plugins bringen mit: │ │ - agent_definitions (Agent-Templates) │ │ - automation_templates (Automation-Tpl) │ │ - cron_jobs (periodische Tasks) │ │ - heartbeat_configs │ └─────────────────────────────────────────────┘ ``` | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 3.11 | Plugin-Manifest um Agent/Automation-Felder erweitern | 4h | Manifest um `agent_definitions`, `automation_templates`, `cron_jobs`, `heartbeat_configs` erweitern. Plugins deklarieren was sie mitbringen. | | 3.12 | Cron-Scheduler Backend | 6h | ARQ-basierter Scheduler für periodische Tasks. Cron-Expressions (z.B. `0 8 * * *` = täglich 8 Uhr). Scheduler liest aktive Cron-Jobs aus DB und enqueued sie. Ersetzt hartkodierten Heartbeat. | | 3.13 | Workflow-Timeout-Worker | 4h | ARQ-Job der regelmäßig Workflow-Instanzen mit abgelaufenem `timeout_at` prüft. Bei Timeout: Status auf `cancelled`, Notification an Initiator. | | 3.14 | Agent Builder Backend | 8h | API für Agent-Definitionen: Name, Beschreibung, LLM-Modell, Tools (aus tool_registry), System-Prompt, Heartbeat-Intervall, Proaktiv/Reaktiv-Modus. Agent-Definitionen in DB gespeichert. | | 3.15 | Automation Builder Backend | 6h | API für Automation-Definitionen: Trigger (Event/Schedule/Manual), Conditions, Actions (API-Call/Notification/Workflow-Start). Automation-Definitionen in DB gespeichert. | | 3.16 | Automation Execution Engine | 6h | Engine die Automations ausführt: Event-Trigger → Conditions prüfen → Actions ausführen. Nutzt Event-Bus für Event-Trigger, Cron-Scheduler für Schedule-Trigger. | | 3.17 | Agent Runner | 8h | Führt Agenten aus: Proaktiv (Heartbeat-getriggert, sammelt Kontext, generiert Vorschläge) oder Reaktiv (auf Event/Message, reagiert). Nutzt LiteLLM + tool_registry + PydanticAI. | | 3.18 | Automation & Agents UI — Automation Builder | 8h | Visueller Builder für Automations: Trigger auswählen, Conditions definieren, Actions zusammenstellen. Drag & Drop oder Form-basiert. Live-Preview. | | 3.19 | Automation & Agents UI — Agent Builder | 8h | Visueller Builder für Agenten: Name, Modell, Tools, System-Prompt, Heartbeat. Test-Run Button. Agent-Liste mit Status (aktiv/inaktiv). | | 3.20 | Automation & Agents UI — Dashboard | 4h | Übersicht: Aktive Automations, Aktive Agenten, Letzte Ausführungen, Logs, Fehler. Heartbeat-Status pro Agent. | | 3.21 | Plugin-Beiträge registrieren | 4h | Wenn Plugin aktiviert wird: Agent-Definitionen, Automation-Templates, Cron-Jobs aus Manifest registrieren. Bei Deaktivierung: entfernen. | | 3.22 | Heartbeat-Verwaltung migrieren | 3h | Hartkodierten Heartbeat aus ai_proactive in Automation & Agents Plugin migrieren. Heartbeat wird zu einem konfigurierbaren Cron-Job. | | 3.23 | Settings für Automation & Agents | 3h | Einstellungen: Default-LLM-Modell für Agenten, Heartbeat-Default-Intervall, Max-Concurrent-Agents, Log-Level. | | 3.24 | Tests für Automation & Agents | 6h | Tests für Cron-Scheduler, Workflow-Timeouts, Agent Runner, Automation Engine, Plugin-Beiträge. | | 3.25 | Agent- & Automation-Logs | 4h | Jede Agent-Ausführung und Automation-Ausführung wird geloggt: Start, Ende, Status, Dauer, Ergebnis, Fehler. Log-Viewer in Dashboard UI. Historie pro Agent/Automation. | | 3.26 | RBAC für Automation & Agents | 3h | Permissions definieren: `automation:read`, `automation:write`, `automation:delete`, `automation:execute`, `agents:read`, `agents:write`, `agents:delete`, `agents:execute`. Nur Admin/Editor dürfen Agenten/Automations erstellen. | | 3.27 | Dry-Run / Test-Modus | 3h | Automations und Agenten können im Dry-Run getestet werden: Führt Conditions aus, zeigt was passieren würde, aber führt keine destruktiven Actions aus. Test-Button in Builder UI. | | 3.28 | Agent Rate-Limiting & Safety | 3h | Max-Ausführungen pro Agent pro Stunde. Max-Dauer pro Ausführung. Auto-Stop bei Endlosschleife (wenn Agent dieselbe Action 5x hintereinander ausführt). Budget-Limit pro Agent (LiteLLM Cost-Tracking). | | 3.29 | Plugin-Beitrags-Konfliktlösung | 2h | Wenn zwei Plugins denselben Agent-Namen/Templat-Namen mitbringen: Plugin-Name als Prefix (`mail.mail_sorter` statt `mail_sorter`). Dedup-Logik bei Registrierung. | | 3.30 | Agent-zu-Agent-Kommunikation | 8h | Agenten können Nachrichten an andere Agenten senden. Nutzt kommunikation Plugin-Infrastruktur (WebSocket, Rooms). Agent-Message-Router: Agent A sendet `{to: 'mail_sorter', message: 'Neuer Termin gefunden'}`. Empfänger-Agent reagiert. Agent-Chatrooms in Dashboard sichtbar. | | 3.31 | Versionshistorie für Agenten & Automations | 4h | Jede Änderung an Agent/Automation erstellt neue Version. Alte Versionen können wiederhergestellt werden. Versions-Diff in UI. `agent_versions` und `automation_versions` Tabellen. | | 3.32 | MiniApps: Plugin-MiniApps im Chat | 6h | **Bereits implementiert:** `MiniAppRegistry`, `MiniAppDef`, Routes (`GET /miniapps`, `POST /conversations/{id}/miniapps`), `MiniAppBlock.tsx` Frontend. **Was fehlt:** Plugin-Manifest um `miniapps` Feld erweitern (Plugins deklarieren welche MiniApps sie mitbringen). MiniApp-Builder UI (visuell MiniApps erstellen). MiniApp-Store in Settings. Dokumentation in Plugin-Entwickler-Richtlinien. | **Phase 3.5 Gesamt: ~105h** **Was Plugins mitbringen können:** - **Agent-Definitionen:** Ein Plugin kann vordefinierte Agenten mitbringen (z.B. Mail-Plugin bringt "E-Mail-Sortier-Agent" mit) - **Automation-Templates:** Ein Plugin kann Automation-Vorlagen mitbringen (z.B. Calendar-Plugin bringt "Terminerinnerung 24h vorher" mit) - **Cron-Jobs:** Ein Plugin kann periodische Tasks deklarieren (z.B. Mail-Plugin: "IMAP-Sync alle 15 Minuten") - **Heartbeat-Configs:** Ein Plugin kann Heartbeat-Konfigurationen mitbringen **Beispiel: Mail-Plugin bringt Agent mit** ```json { "agent_definitions": [{ "name": "mail_sorter", "display_name": "E-Mail-Sortier-Assistent", "description": "Sortiert eingehende E-Mails automatisch nach Regeln", "model": "ollama/deepseek-v4-flash", "tools": ["mail.read", "mail.move", "mail.label"], "system_prompt": "Du sortierst E-Mails...", "mode": "reactive", "trigger_event": "mail.received" }] } ``` **Beispiel: Calendar-Plugin bringt Automation mit** ```json { "automation_templates": [{ "name": "appointment_reminder", "display_name": "Terminerinnerung 24h vorher", "trigger": {"type": "schedule", "cron": "0 8 * * *"}, "conditions": [{"field": "entry.start_at", "operator": "lt", "value": "now + 24h"}], "actions": [{"type": "notification", "title": "Terminerinnerung", "body": "Morgen: ${entry.title}"}] }] } ``` --- ### PHASE 4: KI-UI-Steuerung **Ziel:** KI-Agent kann UI steuern — Kontakte öffnen, Filter setzen, navigieren. User sieht das Ergebnis in der UI. **Wichtig:** Bestehende WebSocket-Infrastruktur im `kommunikation` Plugin (`/api/v1/comm/ws`, `websocket_manager.py`) kann als Referenz dienen. | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 4.1 | UI-Command-Protokoll definieren | 4h | JSON-Protokoll für UI-Befehle: `{action: 'navigate', path: '/contacts/123'}`, `{action: 'filter', entity: 'contacts', filter: {type: 'company'}}`, `{action: 'open_contact', id: '...'}`. | | 4.2 | WebSocket-Endpoint für KI-UI-Steuerung | 6h | Backend-WebSocket `/ws/ai-ui-control`. Authentifiziert via Session. KI-Agent sendet Commands, Frontend empfängt. Basiert auf bewährter WebSocket-Infrastruktur aus kommunikation Plugin. | | 4.3 | Frontend `useAIUIControl` Hook | 6h | WebSocket-Client im Frontend. Empfängt Commands und führt sie aus. Nutzt React Router, TanStack Query, Zustand Stores. | | 4.4 | Command: Navigate | 2h | `useNavigate()` für Route-Wechsel. KI kann zu jeder Seite navigieren. | | 4.5 | Command: Filter setzen | 4h | URL-Search-Params setzen für Listen-Filter. KI kann Filter setzen (z.B. "Zeige nur Firmen in Berlin"). | | 4.6 | Command: Contact öffnen | 3h | Navigate zu `/contacts/:id` + Detail-Daten laden. KI kann Kontakt öffnen und User sieht ihn. | | 4.7 | Command: Modal öffnen/schließen | 3h | EditModal, CreateModal etc. per Command steuerbar. | | 4.8 | Command: Tab wechseln | 2h | Detail-Tabs (Dateien, E-Mails, Kalender) per Command wechseln. | | 4.9 | Command: Settings ändern | 3h | System-Settings, User-Preferences per UI-Command ändern. Wird in UI sichtbar. | | 4.10 | UI-Action-Feedback an KI | 4h | Frontend sendet Bestätigung zurück: `{action: 'navigate', status: 'success', current_path: '/contacts/123'}`. KI weiß, dass Command ausgeführt wurde. | | 4.11 | Visuelle KI-Indikation | 3h | Wenn KI eine Aktion ausführt: kurzer Highlight-Effekt oder Toast "KI führt Aktion aus...". User sieht dass KI agiert. | | 4.12 | Tests für KI-UI-Steuerung | 4h | Vitest-Tests für Command-Protokoll, useAIUIControl Hook, Command-Ausführung. | **Phase 4 Gesamt: ~44h** --- ### PHASE 5: API-Vollständigkeit & KI-Testbarkeit **Ziel:** App komplett per API steuerbar. KI kann selbstständig testen und Updates einspielen. | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 5.1 | API-Audit: Alle UI-Funktionen per API erreichbar | 8h | Systematische Prüfung: Jede UI-Aktion hat einen API-Endpoint. Fehlende Endpoints identifizieren und implementieren. Sidebar-Zustand, Tab-Auswahl, Filter-Zustand per API speichern/laden. | | 5.2 | User-Preferences-API erweitern | 4h | UI-Einstellungen (Sidebar collapsed, theme, language, active tab, sort preferences) per API speichern/laden. | | 5.3 | Workflow-API-Frontend-Modul | 4h | `api/workflows.ts` erstellen. Workflow-Definitions CRUD, Instances, Step-History. | | 5.4 | Playwright E2E-Tests: Setup | 4h | `@playwright/test` installieren. `playwright.config.ts`. Test-Helper für Login, API-Calls. | | 5.5 | Playwright: auth.spec.ts | 3h | Login → Logout E2E-Test. | | 5.6 | Playwright: contact-crud.spec.ts | 4h | Contact erstellen → bearbeiten → Ansprechpartner hinzufügen → löschen. | | 5.7 | Playwright: search.spec.ts | 3h | Globale Suche, Filter, Ergebnisse prüfen. | | 5.8 | Playwright: plugin-toggle.spec.ts | 3h | Plugin aktivieren/deaktivieren, UI-Änderung prüfen. | | 5.9 | Playwright: mail.spec.ts | 4h | Mail-Konto anlegen, Ordner anzeigen, Mail öffnen. | | 5.10 | Playwright: dms.spec.ts | 4h | Ordner erstellen, Datei hochladen, Vorschau, teilen. | | 5.11 | Playwright: calendar.spec.ts | 4h | Termin erstellen, Kalender wechseln, Kanban-View. | | 5.12 | API-Health-Check-Script für KI | 4h | `scripts/ai_health_check.py`: Prüft alle API-Endpunkte, gibt strukturierten Report. KI kann das vor/nach Updates laufen lassen. | | 5.13 | CI/CD-Pipeline für KI-Updates | 6h | `scripts/ai_deploy.py`: KI kann Build erstellen, Tests laufen, bei Erfolg deployen. Rollback bei Fehler. | | 5.14 | API-Dokumentation vervollständigen | 4h | OpenAPI/Swagger prüfen. Alle Endpoints dokumentiert. Beispiele für KI. | | 5.15 | Automatisiertes Backup-System | 8h | `pg_dump` + Storage-Backup als Cron-Job (nutzt Cron-Scheduler aus Phase 3.5). Backup-Konfiguration in Settings (Intervall, Aufbewahrung, Ziel: lokal/S3/Nextcloud). Restore-Script. Backup-Status in Dashboard. Notification bei Backup-Fehler. | | 5.16 | MCP-Server Integration | 10h | LeoCRM als MCP-Server: Externe Tools (Claude Desktop, andere KI-Clients) können auf LeoCRM-Daten zugreifen. MCP-Tools für Contacts, Calendar, Mail, DMS. Authentifiziert via API-Token. MCP-Config-Endpoint `GET /api/v1/mcp/tools`. | | 5.17 | MCP-Client Integration | 6h | LeoCRM-Agenten können externe MCP-Server nutzen (z.B. Web-Search, Code-Execution, externe Datenquellen). MCP-Client in tool_registry integriert. Admin kann MCP-Server in Settings konfigurieren. Agenten nutzen MCP-Tools wie native Tools. | | 5.18 | Report Generator: PDF-Support & Druck-Funktionen | 8h | Backend: WeasyPrint für PDF-Generierung aus Jinja2-Templates. Vorgefertigte Berichte: Kontaktliste, Kalender (Woche/Monat), Firmenliste, Audit-Log. Druck-Optimierte Templates (A4, Landscape). `output_format` um `pdf` und `print` erweitern. | | 5.19 | Report Generator: Frontend-Oberfläche | 10h | `Reports.tsx` Seite: Template-Liste, Template-Editor (Code-Editor für Jinja2), Report-Generierung mit Live-Preview, Download-History. Vorgefertigte Berichte als Buttons ("Kontakt-Liste drucken", "Kalender drucken"). Druck-Dialog mit Format-Auswahl (A4/A5/Landscape). | | 5.20 | Custom Fields: Plugin-Felder in UI | 6h | Plugins sollen Custom Fields mitbringen können. Plugin-Manifest um `custom_fields` Definition erweitern. Frontend: Dynamische Custom-Field-Renderer in Contact-Detail, ContactEditModal. Feld-Typen: text, number, date, select, multiselect, boolean. Felder werden in `contacts.custom` JSONB gespeichert. | | 5.21 | Tasks-Plugin | 12h | Eigenes Tasks-Plugin: Freie Aufgaben/Aktivitäten verwalten (Anruf protokollieren, Notiz, Besuch). Verknüpfung mit Kontakten. Tasks haben Status (open/in_progress/done), Priorität, Fälligkeitsdatum, Zuweisung an Nutzer. Tasks-Liste mit Filter. ARQ-Reminder für fällige Tasks. Plugin-Manifest, Models, Routes, Schemas, Frontend-Seite. | | 5.22 | Saved Searches / Smart Lists | 6h | Jede Listen-Ansicht (Contacts, Mail, Calendar, DMS) bekommt Filter-Funktionalität. Filter können gespeichert werden (Name, Filter-Kriterien). Gespeicherte Filter erscheinen als Tabs oder Sidebar-Einträge. `saved_filters` Tabelle (tenant-scoped, user-scoped). Frontend: Filter-Builder UI, Save-Button, Load-Gespeicherte-Filter. | | 5.23 | Deduplication / Merge (über KI/Automatisierung) | 6h | Contacts-Plugin bietet Dubletten-Erkennung: KI-gestützter Vergleich von Kontakten (Name, E-Mail, Telefon). Automation-Template: "Dubletten finden und zusammenführen". Merge-UI: Zwei Kontakte vergleichen, Felder auswählen, zusammenführen. `contact_merge_history` Tabelle. | | 5.24 | PWA (Progressive Web App) | 6h | Frontend als PWA planen: `manifest.json`, Service Worker, Offline-Caching für statische Assets, Add-to-Home-Screen, App-Icon. Vite PWA Plugin installieren. Push-Notifications vorbereiten (Notification API). | | 5.25 | Dashboard-System ausbauen | 8h | Plugins bringen Dashboard-Komponenten mit und melden diese an. Plugin-Manifest um `dashboard_widgets` erweitern (bereits in Architektur definiert aber nicht implementiert). Dashboard lädt Widgets dynamisch aus Plugin-Registry. Widget-Typen: Stat-Cards, Charts, Recent-Activity, Quick-Actions. Frontend: Dashboard-Grid mit drag-and-drop Widget-Positionierung. | **Phase 5 Gesamt: ~145h** --- ### PHASE 6: React Hook Form + Zod überall **Ziel:** Konsistente Form-Validierung in allen Formularen | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 6.1 | ComposeModal (Mail) auf RHF + Zod | 4h | E-Mail-Validierung, Pflichtfelder, CC/BCC. | | 6.2 | AppointmentModal (Calendar) auf RHF + Zod | 4h | Datum-Validierung, Pflichtfelder, Recurrence. | | 6.3 | SettingsForms auf RHF + Zod | 6h | SettingsUsers, SettingsRoles, SettingsGroups, SettingsCurrencies, SettingsTaxes, SettingsSequences, SettingsSystem. | | 6.4 | DMS-Forms (Folder create, Share) auf RHF + Zod | 3h | | | 6.5 | Tag-Forms auf RHF + Zod | 2h | | | 6.6 | Mail-Settings-Forms auf RHF + Zod | 4h | Account-Erstellung, Rules, Signatures, Templates. | **Phase 6 Gesamt: ~23h** --- ### PHASE 7: Test-Vollendung & Wartbarkeit **Ziel:** Vollständige Test-Abdeckung für KI-Wartbarkeit | # | Aufgabe | Aufwand | Details | |---|---|---|---| | 7.1 | Tests für ungetestete Settings-Pages | 6h | SettingsGroups, SettingsSystem, SettingsCurrencies, SettingsTaxes, SettingsSequences, SettingsNotifications, SettingsPlugins. | | 7.2 | Tests für AI-Komponenten | 4h | ChatWindow, SessionList, SuggestionSidebar, AISettings, ProactiveAISettings. | | 7.3 | Tests für Calendar-Page | 3h | Calendar.tsx (717 Zeilen), CalendarKanban.tsx. | | 7.4 | Tests für DMS-Sub-Komponenten | 4h | FileExplorer, SourceTree, FileGrid, FileDetails, BulkActions. | | 7.5 | Tests für Contact-Sub-Komponenten | 3h | ContactDetail, ContactEditModal, ContactFolderTree. | | 7.6 | Tests für Comm-Blocks | 3h | BlockRenderer und alle Block-Typen. | | 7.7 | Tests für Stores | 2h | authStore, uiStore, commStore, pluginToolbarStore, calendarStore. | | 7.8 | Backend-Test-Lücken schließen | 8h | Tests für fehlende Plugin-Routes, Edge-Cases, Multi-Tenant-Szenarien. | | 7.9 | Test-Runner-Script für KI | 3h | `scripts/ai_run_tests.py`: Führt alle Tests aus (Backend + Frontend + E2E), gibt strukturierten Report. | **Phase 7 Gesamt: ~36h** --- ## Zusammenfassung: Aufwandsschätzung (korrigiert) | Phase | Thema | Aufwand | Vorher | Änderung | |---|---|---|---|---| | 0 | Vorbereitung & Cleanup | ~77h | ~14h | **+63h** (Design, Theme, RBAC, LiteLLM, Search-RBAC, Undo, Storage, Import/Export, Config-Cleanup, Mail-Salt, PyMuPDF→pypdf, OnlyOffice→Collabora) | | 1 | Unified Contact (Backend+Frontend) | **~81h** | ~33h | **+48h** — Company-Referenzen in 6 Plugins + Permission-Registry + Addresses + conftest unterschätzt | | 2 | Code-Splitting & Performance | ~25h | ~25h | — | | 3 | Plugin-UI-System | ~58h | ~48h | +10h (Plugin-Install-System) | | 3.5 | Automation & Agents Plugin | ~105h | — | **NEU** — Agent Builder, Automation, Cron, Logs, Safety, Agent-zu-Agent, Versionshistorie, MiniApps | | 4 | KI-UI-Steuerung | ~44h | ~44h | — | | 5 | API, Testbarkeit, Backup, MCP, Reports, Custom Fields, Tasks, Saved Searches, Dedup, PWA, Dashboard | ~145h | ~57h | +88h | | 6 | React Hook Form + Zod | ~23h | ~23h | — | | 7 | Test-Vollendung | ~36h | ~36h | — | | | **GESAMT** | **~590h** | ~280h | **+310h** | --- ## Empfohlene Reihenfolge ``` Phase 0 (Vorbereitung & Cleanup) ↓ Phase 1 (Unified Contact — Backend+Frontend) ← Core-CRM-Feature, größte Phase ↓ Phase 2 (Code-Splitting & Performance) ↓ Phase 3 (Plugin-UI-System) ← WordPress-Style, nicht zu lange schieben ↓ Phase 3.5 (Automation & Agents Plugin) ← Agent Builder, Cron-Scheduler, Automation ↓ Phase 4 (KI-UI-Steuerung) ← Baut auf Plugin-System auf ↓ Phase 5 (API-Vollständigkeit & Testbarkeit) ← KI kann selbstständig testen ↓ Phase 6 (React Hook Form + Zod) ← Qualität ↓ Phase 7 (Test-Vollendung) ← Wartbarkeit für KI ``` **Begründung der Reihenfolge:** 1. Phase 0 zuerst: Dependencies und Cleanup als Fundament 2. Phase 1 als Nächstes: Core-CRM-Feature (Contacts) muss vollständig sein. Größte Phase (~74h) weil 'company' überall im Code verankert ist. 3. Phase 2: Code-Splitting ist schnell und bringt sofortige Performance-Verbesserung 4. Phase 3: Plugin-UI-System — je früher desto besser, sonst wird Umbau später schwieriger 5. Phase 4: KI-UI-Steuerung baut auf Plugin-System auf (dynamische Routes, Tabs etc.). Bestehende WebSocket-Infrastruktur aus kommunikation Plugin als Referenz. 6. Phase 5: API-Vollständigkeit und E2E-Tests für KI-Wartbarkeit 7. Phase 6+7: Qualität und Test-Vollendung --- ## Was bei der Überprüfung gefunden wurde ### Phase 1 Korrektur: +41h Aufwand Die ursprüngliche Schätzung von 33h für Phase 1 war **massiv unterschätzt**. Die gründliche Code-Analyse zeigte: **'company' als entity_type ist in 6 Plugins verankert:** - `entity_links`: entity_type Pattern, company_router, on_company_deleted Event-Handler - `unified_search`: CompanySearchProvider, index_company, company.created/updated Events, search_engine Mapping - `calendar`: entity_type Pattern für EntryLinks - `tags`: entity_type Pattern für Tag-Assignments - `mail`: company_id Spalte in mails Tabelle (DB-Migration nötig!) - `ai/action_mapper`: Company-Intents (create/delete/update/list) **Event-Namen müssen migriert werden:** - `company.created` → `contact.created` - `company.updated` → `contact.updated` - `company.deleted` → `contact.deleted` - Betroffen: unified_search, entity_links, workflows, test_sample, manifest.py **DB-Migration nötig:** - `entity_links.entity_type = 'company'` → `'contact'` - `tag_assignments.entity_type = 'company'` → `'contact'` - `calendar_entry_links.entity_type = 'company'` → `'contact'` - `mails.company_id` → `mails.contact_id` (Spalte umbenennen) **Was NICHT geändert wird:** - `system_settings.company_name`, `company_street` etc. → Das ist die CRM-Besitzer-Firmeninfo für Rechnungen. Bleibt wie es ist. - `CalendarType = 'company'` → Das ist ein Kalender-Typ (Firmenkalender), keine Entity-Referenz. Kann bleiben. ### Bestehende WebSocket-Infrastruktur Das `kommunikation` Plugin hat bereits eine vollständige WebSocket-Implementierung (`/api/v1/comm/ws`, `websocket_manager.py`). Diese kann als Referenz für die KI-UI-Steuerung (Phase 4) dienen — das spart Entwicklungszeit. --- ## KI-Wartbarkeit: Schlüssel-Anforderungen Damit ein KI-Agent die App selbstständig warten kann: 1. **Vollständige API-Abdeckung:** Jede UI-Funktion per API steuerbar (Phase 5) 2. **E2E-Tests:** Playwright-Tests die KI ausführen kann (Phase 5) 3. **API-Health-Check:** Script das alle Endpunkte prüft (Phase 5) 4. **Test-Runner:** Script das alle Tests ausführt und strukturiert reportet (Phase 7) 5. **Deploy-Script:** KI kann Build erstellen, testen, deployen, rollback (Phase 5) 6. **Plugin-Richtlinien:** Klare Vorgaben damit KI neue Plugins erstellen kann (Phase 3) 7. **Dokumentation:** Aktuelle Architektur-Doku, API-Doku, Plugin-Guide (Phase 0+3+5) --- ## Nächste Schritte 1. ✅ Nextcloud Backup erstellt (`/Backups/leocrm/leocrm-backup-20260722.bundle`) 2. ✅ Plan gründlich überprüft und korrigiert (+45h) 3. ⬜ Plan freigeben 4. ⬜ Phase 0 starten 5. ⬜ Planungsdokumente aktualisieren --- ## Test-Strategie (pro Phase) ### Phase 0: Vorbereitung & Cleanup - **Pro Task:** Unit-Test für geänderte Funktionalität (z.B. Test dass lucide-react Icons rendern, Test dass date-fns formatiert, Test dass Storage Backend local+S3 funktioniert) - **Regression:** Alle bestehenden Tests müssen weiterhin durchlaufen - **Lizenz-Test:** `pip-licenses` Script prüft dass keine AGPL-Packages mehr in requirements.txt ### Phase 1: Unified Contact Model - **Pro Task:** API-Integration-Test (httpx + pytest) für jeden geänderten Endpoint - **DB-Migration-Test:** Test dass Migration 0023 (entity_type company→contact) korrekt ausführt und rollbackbar ist - **Plugin-Test:** Pro Plugin (entity_links, unified_search, calendar, tags, mail) Test dass entity_type='contact' funktioniert - **Frontend-Test:** Vitest für ContactDetail, ContactEditModal, ContactPerson-Verwaltung - **Cross-Tenant-Test:** Test dass Tenant-Isolation nach Migration noch funktioniert ### Phase 2: Code-Splitting & Performance - **Bundle-Test:** Test dass Initial-Bundle < 300KB (vorher alle Pages im Bundle) - **Virtual Scrolling Test:** Test mit 10.000 Datensätzen — Rendering-Zeit < 500ms - **Lazy-Loading Test:** Test dass Plugin-Pages nicht im Initial-Bundle sind ### Phase 3: Plugin-UI-System - **PluginRegistry-Test:** Test dass Manifests korrekt geladen und gerendert werden - **PluginLoader-Test:** Test dass lazy-loaded Komponenten mit Suspense funktionieren - **Plugin-Install-Test:** Test dass ZIP-Upload validiert und installiert wird - **Error-Boundary-Test:** Test dass fehlerhaftes Plugin nicht die ganze App crashen lässt ### Phase 3.5: Automation & Agents - **Cron-Scheduler-Test:** Test dass Cron-Jobs zur richtigen Zeit enqueued werden - **Workflow-Timeout-Test:** Test dass abgelaufene Workflows cancelled werden - **Agent-Runner-Test:** Test dass Agent LLM-Call ausführt und Ergebnis zurückgibt (Mock-LLM) - **Automation-Engine-Test:** Test dass Event-Trigger → Conditions → Actions korrekt ausgeführt werden - **Agent-zu-Agent-Test:** Test dass Agent A Nachricht an Agent B sendet und B reagiert - **Rate-Limiting-Test:** Test dass Agent nach Max-Ausführungen gestoppt wird - **Dry-Run-Test:** Test dass Dry-Run keine destruktiven Actions ausführt ### Phase 4: KI-UI-Steuerung - **WebSocket-Test:** Test dass Commands korrekt gesendet und empfangen werden - **Command-Test:** Pro Command-Typ (navigate, filter, open_contact, modal, tab, settings) ein Test - **Feedback-Test:** Test dass Frontend Bestätigung an KI zurücksendet ### Phase 5: API-Vollständigkeit & Features - **E2E-Tests (Playwright):** auth, contact-crud, search, plugin-toggle, mail, dms, calendar (7 Specs) - **API-Health-Check-Test:** Test dass alle Endpoints erreichbar und korrekt responden - **Backup-Test:** Test dass Backup erstellt wird und Restore funktioniert - **MCP-Test:** Test dass MCP-Server Tools bereitstellt und MCP-Client Tools nutzt - **Report-Test:** Test dass PDF/CSV/Excel generiert wird und korrekt formatiert ist - **Custom-Fields-Test:** Test dass Plugin-Felder in UI gerendert und gespeichert werden - **Tasks-Plugin-Test:** Vollständige CRUD-Tests für Tasks - **Saved-Searches-Test:** Test dass Filter gespeichert und geladen werden - **Dedup-Test:** Test dass Dubletten erkannt und gemerged werden - **PWA-Test:** Test dass Service Worker registriert wird und Offline-Caching funktioniert - **Dashboard-Test:** Test dass Plugin-Widgets dynamisch gerendert werden ### Phase 6: React Hook Form + Zod - **Pro Form:** Test dass Validierung korrekt funktioniert (Pflichtfelder, E-Mail-Format, Datum-Range) - **Error-Display-Test:** Test dass Fehlermeldungen korrekt angezeigt werden ### Phase 7: Test-Vollendung - **Coverage-Target:** >80% Backend, >70% Frontend - **Test-Runner-Script:** `scripts/ai_run_tests.py` führt alle Tests aus und gibt strukturierten Report - **Multi-Tenant-Test:** Test mit 3 Tenants — Isolation, Cross-Tenant-Access → 404 - **Performance-Test:** 200k Contacts — List < 500ms, FTS < 500ms ### Test-Infrastruktur - **Backend:** pytest + httpx + pytest-asyncio + pytest-cov (bereits vorhanden) - **Frontend:** Vitest + @testing-library/react (bereits vorhanden) - **E2E:** Playwright (neu in Phase 5) - **Test-DB:** PostgreSQL mit `pytest-asyncio` fixture (bereits in conftest.py) - **Test-Redis:** Redis-Mock oder echte Redis-Instanz - **Mock-LLM:** LiteLLM mock mode für AI-Tests (bereits vorhanden) --- ## Agent-Anleitung: Wie ein KI-Agent diesen Plan umsetzt Dieser Plan ist so strukturiert dass ein KI-Agent (wie Agent Zero) ihn Task-für-Task umsetzen kann. ### Vorgehensweise pro Task 1. **Task lesen:** Jeder Task hat Nummer, Aufwand, Beschreibung und Details 2. **Code prüfen:** Vor der Umsetzung den aktuellen Code inspizieren (Dateien lesen, Abhängigkeiten prüfen) 3. **Minimal-invasiv arbeiten:** Nur das ändern was der Task verlangt. Keine Refactoring-Touren. 4. **Tests schreiben/aktualisieren:** Pro Task mindestens ein Test der die Änderung abdeckt 5. **Commit:** Pro Task ein Git-Commit mit klarer Message (z.B. `Phase 0.2: install lucide-react and migrate icons`) 6. **Verifizieren:** Nach jedem Task: Tests laufen, Build funktioniert, keine Regressionen ### Phasen-Reihenfolge ist verbindlich - Phase N+1 darf erst starten wenn Phase N abgeschlossen ist - Innerhalb einer Phase können Tasks parallel sein (z.B. 0.2 und 0.3 unabhängig) - Abhängigkeiten sind in den Task-Beschreibungen genannt ### Was ein Agent pro Task braucht - Dateipfade der zu ändernden Dateien (in Task-Beschreibung genannt) - Akzeptanzkriterien (in Task-Beschreibung genannt) - Test-Strategie (pro Task mindestens ein Test) - Git-Commit pro Task ### Plugin-Entwicklung Wenn ein Agent ein neues Plugin erstellt (z.B. Tasks-Plugin 5.21): 1. Plugin-Verzeichnis in `app/plugins/builtins//` erstellen 2. `plugin.py` mit Manifest (Name, Version, Dependencies, Routes, Permissions, Events) 3. `models.py` mit SQLAlchemy Models (TenantMixin!) 4. `schemas.py` mit Pydantic Schemas 5. `routes.py` mit FastAPI Router (require_permission!) 6. `services.py` mit Business-Logic 7. Migration in `migrations/` Verzeichnis 8. Frontend-Komponenten in `frontend/src/components//` 9. Frontend-Seite in `frontend/src/pages/.tsx` 10. API-Modul in `frontend/src/api/.ts` 11. Route in `frontend/src/routes/index.tsx` registrieren 12. i18n-Keys in `frontend/src/i18n/locales/de.json` und `en.json` 13. Tests in `tests/test_.py` und `frontend/src/__tests__//` ### Plugin-Manifest-Format (für neue Plugins) ```python manifest = PluginManifest( name="my_plugin", version="1.0.0", display_name="My Plugin", description="What it does", dependencies=["permissions"], # other plugins this depends on routes=[PluginRouteDef(path="/api/v1/my-plugin", module="...", router_attr="router")], events=["my.event"], # events this plugin listens to migrations=["0001_initial.sql"], permissions=["my_plugin:read", "my_plugin:write"], is_core=False, # Neue Felder (nach Phase 3+3.5): # agent_definitions=[...], # Agent-Templates # automation_templates=[...], # Automation-Vorlagen # cron_jobs=[...], # Periodische Tasks # custom_fields=[...], # Custom Field Definitionen # dashboard_widgets=[...], # Dashboard-Komponenten # miniapps=[...], # MiniApp-Definitionen ) ``` ### Wichtige Regeln für Agent-Updates 1. **Niemals Tests ändern** um sie grün zu bekommen — Code fixen nicht Tests anpassen 2. **Niemals .env committen** — Secrets gehören nicht ins Repo 3. **Jede DB-Änderung braucht Alembic-Migration** — keine manuellen SQL-Changes 4. **Jede API-Route braucht RBAC** — `require_permission()` auf jedem Endpoint 5. **Jedes Plugin-Model braucht TenantMixin** — tenant_id auf jeder Tabelle 6. **Frontend-Änderungen brauchen i18n** — alle Texte in de.json und en.json 7. **Pro Task ein Commit** — nicht mehrere Tasks in einem Commit 8. **Nach jedem Task: Tests + Build verifizieren** — keine Regressionen 9. **Nach jedem Task: Progress aktualisieren** — `PROGRESS.md` im Repo aktualisieren mit: Task-Nummer, Status (done/in-progress/blocked), Datum, was gemacht wurde, was als Nächstes ansteht. **Zwingend für jeden Agenten der am Plan arbeitet.**