diff --git a/docs/test-bugs.md b/docs/test-bugs.md index 94635a4..6ae4b7d 100644 --- a/docs/test-bugs.md +++ b/docs/test-bugs.md @@ -792,3 +792,191 @@ Playwright E2E: 10 passed, 24 failed (BUG-011/012/013 — Mock-Daten und data-te - **Tatsächlich:** 4 failed, 4 passed - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt + +--- + +## Architektur-Fehler (Code-Review) + +### ARCH-001: Plugin Activate/Deactivate Reihenfolge fehlerhaft +- **Datei:** app/services/plugin_service.py:94, app/plugins/registry.py:612 +- **Problem:** registry.activate() ruft on_activate() auf und setzt record.active=True BEVOR plugin_service.py Permissions registriert (Zeile 99-114). Bei Fehlern ist Plugin aktiv ohne Permissions. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-002: Plugin on_activate() wird pro Tenant mehrfach aufgerufen +- **Datei:** app/main.py:292-302 +- **Problem:** `for tenant_id in all_tenant_ids: plugin.on_activate(plugin_db, container, event_bus)` — dieselbe Plugin-Instanz bekommt on_activate() pro Tenant. Event-Handler werden doppelt registriert. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-003: /plugins/active-manifests hängt an plugins:read +- **Datei:** app/routes/plugins.py:95 +- **Problem:** Normaler User ohne plugins:read bekommt keine Plugin-Menüs/Routes. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-004: Workspace/Sidebar is_visible nicht konsistent +- **Datei:** frontend/src/store/workspaceStore.ts:100 +- **Problem:** `if (!ctx?.workspace_id || !ctx?.modules?.length) return true` — wenn kein Workspace-Kontext, werden ALLE Module sichtbar. visibleModuleKeys() gibt alle Module zurück. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-005: Contacts ist Core UND Plugin (Doppelarchitektur) +- **Datei:** app/main.py:44,549 + app/plugins/builtins/contacts/ +- **Problem:** Contacts wird als Core-Route registriert (main.py:549) UND existiert als Plugin. Core behandelt Contacts als Sonderfall. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-006: Frontend hat statische UND dynamische Routes (Doppelarchitektur) +- **Datei:** frontend/src/routes/index.tsx:1,249-256 +- **Problem:** TODO-Kommentar: 'Replace hardcoded plugin routes with dynamic PluginRouteRenderer'. Statische Routes für /calendar, /dms, /mail, /reports existieren parallel zu PluginRouteRenderer. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-007: PluginRouteRenderer hat keine Permission-Prüfung +- **Datei:** frontend/src/components/plugins/PluginRouteRenderer.tsx:18-50 +- **Problem:** Rendert jede Plugin-Seite ohne Permission-Check. Statische Routes verwenden PermissionRoute, dynamische nicht. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-008: Permission-Namen inkonsistent +- **Datei:** app/plugins/builtins/kommunikation/plugin.py:44, app/routes/dashboard.py:23 +- **Problem:** kommunikation verwendet 'comm:read', dashboard verwendet 'dashboard:read'. Andere Plugins verwenden 'pluginname:read'. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-009: Default-Rollen core:*:read matcht nicht Plugin-Permissions +- **Datei:** alembic/versions/0019_rbac_groups.py:80, app/core/permissions.py:46-50 +- **Problem:** `core:*:read` (3 Segmente) matcht nicht `contacts:read` (2 Segmente) wegen `len(g_parts) != len(r_parts)` Prüfung. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-010: Cross-Plugin-Checker scannt nur builtins standardmäßig +- **Datei:** scripts/check_cross_plugin_imports.py:233 +- **Problem:** `default=BUILTINS_DIR` — ohne --path wird nur app/plugins/builtins/ gescannt, nicht Core. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-011: 27 Core→Plugin direkte Imports +- **Dateien:** app/ai/ (8), app/core/ (7), app/routes/ (2), app/workflows/ (7), app/services/ (1), app/main.py (2) +- **Problem:** Core-Code importiert direkt von Plugins. Core darf nicht von Plugins abhängen. +- **Details:** + - app/ai/agent_loop.py:53,396,397 + - app/ai/agent_permissions.py:64 + - app/ai/context_builder.py:224 + - app/ai/integration_tools.py:16,102,131 + - app/ai/llm_client.py:292,320 + - app/core/notifications.py:41 + - app/core/trigger_dispatcher.py:123,186,253 + - app/core/worker.py:168,175,290,460 + - app/routes/compliance.py:22 + - app/routes/errors.py:124 + - app/routes/dashboard.py:15 + - app/services/attachment_service.py:30 + - app/workflows/engine.py:94,95 + - app/workflows/step_handlers.py:221,261,306,351,394 + - app/main.py:150,172 +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-012: Knowledge/Wiki Lifecycle — on_deactivate unvollständig +- **Datei:** app/plugins/base.py:65-81, app/plugins/builtins/knowledge/plugin.py +- **Problem:** on_deactivate() deregistriert nur Handler aus _event_handlers. Wenn Plugin in Override zusätzliche Handler registriert, werden diese nicht deregistriert. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-013: Self-Improvement → Kommunikation Fallback unsauber +- **Datei:** app/plugins/builtins/self_improvement/services.py:586-588 +- **Problem:** Contract-Lookup, dann Fallback-Import. Breite try/except verstecken Fehler. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-014: Contract Registry Lazy-Load nach unregister() +- **Datei:** app/plugins/builtins/contracts.py:88-89 +- **Problem:** get_contract() macht _try_lazy_load() auch nach unregister(). Deaktivierte Plugins werden wieder sichtbar. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-015: Notification-Type Lifecycle — Sync-Reihenfolge +- **Datei:** app/plugins/registry.py:181-244,622-623 +- **Problem:** sync_notification_types() läuft bei Aktivierung. Bei Deaktivierung werden Types gelöscht, aber nur wenn on_deactivate() nicht fehlschlägt. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-016: Entity-Permission-Liste statisch +- **Datei:** app/services/entity_permission_service.py:54, app/routes/entity_permissions.py:252 +- **Problem:** ENTITY_MODELS ist statisch. Neue Plugin-Entities werden dynamisch registriert, aber entity_permissions.py hat eine statische Liste. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-017: Custom Fields an Contacts-Permission gekoppelt +- **Datei:** app/routes/custom_field_definitions.py:25,42 +- **Problem:** Verwendet contacts:read/write statt generischer Entity-Permissions. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-018: Notification/Communication und AI-Chat doppelt +- **Datei:** app/plugins/builtins/system_notif/plugin.py, app/plugins/builtins/kommunikation/ +- **Problem:** Legacy Notifications und Communication laufen parallel. AI-Chat läuft über kommunikation mit conversation_type='ai'. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-019: Frontend PluginLoader @vite-ignore im Production-Build +- **Datei:** frontend/src/components/plugins/PluginLoader.tsx:108 +- **Problem:** `import(/* @vite-ignore */ importPath)` funktioniert im Dev-Modus, kann aber im Production-Build Probleme machen. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-020: EventBus subscribe() prüft nicht auf Duplikate +- **Datei:** app/core/event_bus.py:38 +- **Problem:** `self._handlers[event_name].append(handler)` — gleicher Handler kann mehrfach registriert werden. +- **Schweregrad:** High +- **Status:** ⏳ Nicht gefixt + +### ARCH-021: Sidebar.tsx statische UND dynamische Menüs +- **Datei:** frontend/src/components/layout/Sidebar.tsx:54-60 +- **Problem:** singleItems ist hardcoded (dashboard, contacts, system-dashboard). Plugin-Menüs kommen via usePluginStore. Doppelarchitektur. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-022: deps.py _WRITE_PERMISSIONS statisch +- **Datei:** app/deps.py:22-35 +- **Problem:** Hardcoded Liste mit 12 Einträgen. Neue Plugin-Write-Permissions fehlen. +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-023: service_container.py initialize() unvollständig +- **Datei:** app/core/service_container.py:36-37 +- **Problem:** Registriert nur cache und event_bus. comm_websocket und andere Services werden woanders registriert. +- **Schweregrad:** Low +- **Status:** ⏳ Nicht gefixt + +### ARCH-024: App.tsx hardcoded deutsche Strings ohne i18n +- **Datei:** frontend/src/App.tsx:49,61,79 +- **Problem:** 'Sie sind offline', 'Ihre Sitzung ist abgelaufen', 'Zum Hauptinhalt springen' — ohne t(). +- **Schweregrad:** Low +- **Status:** ⏳ Nicht gefixt + +### ARCH-025: ProtectedRoute.tsx hardcoded deutscher Pfad +- **Datei:** frontend/src/components/common/ProtectedRoute.tsx:18 +- **Problem:** `` — hardcoded deutscher Pfad. +- **Schweregrad:** Low +- **Status:** ⏳ Nicht gefixt + +### ARCH-026: Plugin dependencies nicht deklariert +- **Dateien:** app/plugins/builtins/tasks/plugin.py, wiki/plugin.py, self_improvement/plugin.py +- **Problem:** tasks importiert von kommunikation (dependencies=[]), wiki importiert von unified_search (dependencies=[]), self_improvement importiert von kommunikation (dependencies=[]). +- **Schweregrad:** Medium +- **Status:** ⏳ Nicht gefixt + +### ARCH-027: config.py Default SECRET_KEY hardcoded +- **Datei:** app/config.py:63 +- **Problem:** `secret_key: str = "change-me-in-production-use-a-secure-random-string"` — hardcoded Default im Code. +- **Schweregrad:** Low +- **Status:** ⏳ Nicht gefixt + +### ARCH-028: PluginRouteRenderer 'Page Not Found' hardcoded englisch +- **Datei:** frontend/src/components/plugins/PluginRouteRenderer.tsx:65-70 +- **Problem:** 'Page Not Found' und 'The page ... was not found' — hardcoded englisch ohne i18n. +- **Schweregrad:** Low +- **Status:** ⏳ Nicht gefixt