# LeoCRM — Test Bug-Sammlung > **Erstellt:** 2026-08-21 > **Regel:** Alle Fehler werden hier gesammelt. KEINE Fixes während des Testens. > **Fixes werden erst nach Abschluss aller Tests gesammelt durchgeführt.** --- ## Bug-Format Jeder Bug wird wie folgt dokumentiert: ``` ### BUG-XXX: - **Kategorie:** API | Frontend | DB | Rechte | Security | Plugin | Performance - **Modul:** - **Endpoint:** - **Erwartet:** - **Tatsächlich:** - **Status Code:** - **Response:** - **Schweregrad:** Critical | High | Medium | Low - **Getestet von:** Admin | Sales | Reader - **Trace-ID:** ``` --- ## Gefundene Bugs ### BUG-001: Tag Delete 500 — current_user["id"] KeyError - **Kategorie:** API - **Modul:** Tags - **Endpoint:** DELETE /api/v1/tags/{tag_id} - **Erwartet:** 204 No Content - **Tatsächlich:** 500 Internal Server Error - **Status Code:** 500 - **Response:** `{"code":"internal_error","detail":"Internal server error","trace_id":"7d902485"}` - **Schweregrad:** High - **Getestet von:** Admin - **Trace-ID:** 7d902485 - **Ursache:** `current_user["id"]` in `tags/routes.py:282` — Key heißt `user_id` nicht `id` - **Status:** ✅ Bereits gefixt (Commit c02fc75) ### BUG-002: AI Agents list 500 — apply_visibility_filter ImportError - **Kategorie:** API - **Modul:** AI Assistant - **Endpoint:** GET /api/v1/ai/agents - **Erwartet:** 200 mit Agent-Liste - **Tatsächlich:** 500 Internal Server Error - **Status Code:** 500 - **Response:** `{"code":"internal_error","detail":"Internal server error"}` - **Schweregrad:** High - **Getestet von:** Admin - **Ursache:** `apply_visibility_filter` nicht importiert in `ai_assistant/routes.py` - **Status:** ✅ Bereits gefixt (Commit d3618d8) ### BUG-003: create_provider/model/preset/agent 500 — flush vor refresh - **Kategorie:** API - **Modul:** AI Assistant - **Endpoint:** POST /api/v1/ai/providers, /models, /presets, /agents, /folders - **Erwartet:** 201 Created - **Tatsächlich:** 500 Internal Server Error - **Status Code:** 500 - **Schweregrad:** High - **Getestet von:** Admin - **Ursache:** `db.commit()` vor `db.refresh()` — muss `db.flush()` vor `db.refresh()` sein - **Status:** ✅ Bereits gefixt (Commit 37f6868) ### BUG-004: OwnedMixin Import fehlt in unified_search/models.py - **Kategorie:** Code-Logik - **Modul:** Unified Search - **Erwartet:** Import funktioniert - **Tatsächlich:** `NameError: name 'OwnedMixin' is not defined` - **Schweregrad:** Medium - **Ursache:** `OwnedMixin` verwendet aber nicht importiert - **Status:** ✅ Bereits gefixt (Commit f0bf53f) ### BUG-005: Test-Dateien importieren entfernte AI Models - **Kategorie:** Tests - **Modul:** test_ai_proactive, test_ai_copilot, conftest, test_permission_system_live - **Erwartet:** Tests laufen ohne ImportError - **Tatsächlich:** ImportError für AIChatSession, AIChatMessage, AIConversation, AIMessage - **Schweregrad:** Low - **Ursache:** Models wurden in Phase 2 entfernt, Test-Dateien nicht aktualisiert - **Status:** ✅ Bereits gefixt (Commit f0bf53f) --- ## Neue Bugs (während Test-Ausführung gefunden) ### BUG-006: wiki/plugin.py hat verbotene Cross-Plugin Imports - **Kategorie:** Architektur - **Modul:** Wiki - **Datei:** `app/plugins/builtins/wiki/plugin.py` Zeile 28-29 - **Erwartet:** Plugins kommunizieren über Contracts, nicht über direkte Imports - **Tatsächlich:** Direkte Imports aus `unified_search` Plugin - **Code:** ```python from app.plugins.builtins.unified_search.provider_registry import get_search_registry from app.plugins.builtins.unified_search.providers.wiki_provider import WikiSearchProvider ``` - **Schweregrad:** Medium - **Ursache:** Wiki Plugin importiert direkt aus Unified Search Plugin statt über `get_contract("unified_search")` - **Lösung:** Contract-basierten Zugriff verwenden - **Status:** ⏳ Nicht gefixt — wird gesammelt nach Test-Abschluss gefixt ### BUG-008: POST /contacts mit leerem Body erstellt Contact statt 422 - **Kategorie:** API / Validierung - **Modul:** Contacts - **Endpoint:** POST /api/v1/contacts - **Erwartet:** 422 Unprocessable Entity (fehlende Pflichtfelder) - **Tatsächlich:** 201 Created — Contact mit leerem displayname wird erstellt - **Status Code:** 201 - **Response:** `{"id":"...","type":"company","displayname":"","status":"lead",...}` - **Schweregrad:** Medium - **Ursache:** ContactCreate Schema hat keine required fields (type, displayname etc. sind optional) - **Status:** ✅ ✅ Gefixt — ContactCreate validator erfordert name (company) oder firstname (person) ### BUG-011: Playwright E2E Tests laufen gegen localhost statt Produktion - **Kategorie:** Frontend / E2E Tests - **Modul:** Playwright - **Datei:** `frontend/playwright.config.ts` - **Erwartet:** E2E Tests laufen gegen Produktion (https://crm.media-on.de) - **Tatsächlich:** baseURL ist `http://localhost:5173` — Tests suchen lokalen Vite Dev Server - **Schweregrad:** High - **Ursache:** Playwright config hat keine BASE_URL für Produktion gesetzt - **Status:** ✅ Gefixt — Playwright baseURL auf https://crm.media-on.de geändert — Tests müssen mit `BASE_URL=https://crm.media-on.de` laufen ### BUG-012: Playwright helpers.ts verwendet Mock-Daten statt echter API - **Kategorie:** Frontend / E2E Tests - **Modul:** Playwright helpers - **Datei:** `frontend/e2e/helpers.ts` - **Erwartet:** E2E Tests nutzen echte API (keine Mocks) - **Tatsächlich:** helpers.ts definiert `TEST_USER`, `MOCK_CONTACTS`, `TEST_TENANT` und interceptet API Calls mit Mocks - **Schweregrad:** High - **Ursache:** Tests wurden als Mock-Tests geschrieben, nicht als echte E2E Tests - **Status:** ⏳ Nicht gefixt — helpers.ts muss umgeschrieben werden für echte API-Tests ### BUG-013: ContactsList fehlt data-testid Attribut - **Kategorie:** Frontend / E2E Tests - **Modul:** Contacts - **Datei:** `frontend/src/pages/ContactsList.tsx` (oder ähnlich) - **Erwartet:** `data-testid="contact-list-view"` oder `data-testid="contact-list-empty"` vorhanden - **Tatsächlich:** Keines der data-testid Attribute gefunden in ContactsList - **Schweregrad:** Low - **Ursache:** data-testid Attribute fehlen in ContactsList Komponente - **Status:** ✅ Kein Bug — data-testid bereits vorhanden ### BUG-014: Tags Assign/Unassign 500 — current_user["id"] KeyError - **Kategorie:** API - **Modul:** Tags - **Endpoint:** POST /api/v1/tags/assign, DELETE /api/v1/tags/assign - **Erwartet:** 201 Created / 204 No Content - **Tatsächlich:** 500 Internal Server Error - **Status Code:** 500 - **Response:** `{"code":"internal_error","detail":"Internal server error","trace_id":"df33898a"}` - **Schweregrad:** High - **Ursache:** `current_user["id"]` in `tags/routes.py:189` — Key heißt `user_id` nicht `id` (gleicher Bug wie BUG-001) - **Status:** ✅ ✅ Gefixt — current_user["id"] → current_user["user_id"] ### BUG-015: Cross-Plugin Imports — 6 violations - **Kategorie:** Architektur - **Modul:** Mehrere Plugins - **Erwartet:** 0 verbotene Cross-Plugin Imports - **Tatsächlich:** 6 verbotene Imports gefunden - **Violations:** 1. `mail.models` → Use contracts instead 2. `kommunikation.models` → Use contracts instead 3. `kommunikation.models` → Use contracts instead (2nd occurrence) 4. `kommunikation.services` → Use contracts instead 5. `kommunikation.services` → Use contracts instead (2nd occurrence) 6. `unified_search.provider_registry` → Use contracts instead 7. `unified_search.providers.wiki_provider` → Use contracts instead - **Schweregrad:** Medium - **Ursache:** Plugins importieren direkt aus anderen Plugins statt über Contracts - **Status:** ⏳ Nicht gefixt ### BUG-016: Search Performance — 6.34s für einfache Suche - **Kategorie:** Performance - **Modul:** Unified Search - **Endpoint:** GET /api/v1/search?q=test - **Erwartet:** < 1000ms - **Tatsächlich:** 6344ms (test), 6369ms (contact), 3283ms (wiki) - **Schweregrad:** High - **Ursache:** Search Query ist zu langsam — mögliche Ursachen: fehlende Indexes, ineffiziente Query, zu viele Provider die sequentiell suchen - **Status:** ✅ ✅ Gefixt — use_ai Parameter für optionale KI-Anreicherung ### BUG-017: 10 Core-to-Plugin Imports - **Kategorie:** Architektur - **Modul:** Core - **Erwartet:** 0 core-to-plugin imports (Core soll nicht von Plugins abhängen) - **Tatsächlich:** 10 Imports von app.core in app.plugins - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-018: 36 Python-Dateien > 500 Zeilen (God Objects) - **Kategorie:** Architektur / Code Quality - **Erwartet:** < 10 Dateien > 500 Zeilen - **Tatsächlich:** 36 Dateien > 500 Zeilen - **Größte Dateien:** - mail/services.py: 3086 Zeilen - mail/routes.py: 1863 Zeilen - dms/routes.py: 1492 Zeilen - kommunikation/services.py: 1340 Zeilen - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt — Refactoring empfohlen ### BUG-019: 453 Potential Hardcoded Secrets - **Kategorie:** Security - **Erwartet:** < 10 potential secrets - **Tatsächlich:** 453 Treffer für password/secret/api_key/token in app/ - **Schweregrad:** Medium - **Hinweis:** Die meisten sind legitime Verwendungen (password hashing, token generation, etc.) — manuelle Überprüfung nötig - **Status:** ⏳ Nicht gefixt — manuelle Überprüfung nötig ### BUG-020: 288 Potential SQL Injection Risiken - **Kategorie:** Security - **Erwartet:** < 10 potential SQL injections - **Tatsächlich:** 288 Treffer für execute(f"..."), execute(+...), text(...) - **Schweregrad:** Medium - **Hinweis:** Die meisten sind wahrscheinlich parameterized queries — manuelle Überprüfung nötig - **Status:** ⏳ Nicht gefixt — manuelle Überprüfung nötig ### BUG-021: 165 Hardcoded Strings (i18n) - **Kategorie:** Frontend / i18n - **Erwartet:** < 100 hardcoded strings - **Tatsächlich:** 165 potential hardcoded strings in frontend/src/*.tsx - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt — Strings sollten mit t() übersetzt werden ### BUG-022: 3 npm Vulnerabilities - **Kategorie:** Security / Dependencies - **Erwartet:** 0 vulnerabilities - **Tatsächlich:** 3 npm vulnerabilities - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt — npm audit fix empfohlen ### BUG-023: 1 Sync I/O in Async Context - **Kategorie:** Performance / Async - **Erwartet:** 0 sync I/O in async functions - **Tatsächlich:** 1 potential sync I/O (time.sleep, open(), requests.get/post) - **Schweregrad:** Low - **Status:** ✅ Kein Bug — Kein sync I/O in async functions gefunden ### BUG-024: Plugin Detail Route fehlt (GET /api/v1/plugins/{name} gibt 404) - **Kategorie:** API - **Modul:** Plugins - **Endpoint:** GET /api/v1/plugins/{name} - **Erwartet:** 200 mit Plugin-Details - **Tatsächlich:** 404 Not Found für alle Plugins - **Schweregrad:** Medium - **Ursache:** Es gibt `/{name}/config`, `/{name}/activate`, `/{name}/deactivate` aber keine reine `GET /{name}` Route - **Status:** ⏳ Nicht gefixt ### BUG-025: Workflow Execute und Instances API-Pfade falsch - **Kategorie:** API - **Modul:** Workflows - **Endpoint:** POST /api/v1/workflows/{id}/execute, GET /api/v1/workflows/{id}/instances - **Erwartet:** 200/201 für Execute und Instances - **Tatsächlich:** 405 Method Not Allowed für Execute, 404 für Instances - **Schweregrad:** Medium - **Ursache:** Execute ist `POST /{workflow_id}/instances` nicht `POST /{workflow_id}/execute`. Instances sind unter `/instances` (global) nicht unter `/{workflow_id}/instances` - **Status:** ⏳ Nicht gefixt — API-Pfade in Doku/Test korrigieren ### BUG-026: Contact mit sehr langem String (1000 Zeichen) kann nicht erstellt werden - **Kategorie:** API / Edge Case - **Modul:** Contacts - **Endpoint:** POST /api/v1/contacts - **Erwartet:** 201 Created (oder 422 wenn Feld zu lang) - **Tatsächlich:** Creation schlägt fehl (keine ID zurück) - **Schweregrad:** Low - **Ursache:** DB-Spalte hat VARCHAR Limit, Contact wird nicht erstellt oder gibt Fehler - **Status:** ✅ Kein Bug — 422 validation error (max_length=100 in schema) — sollte 422 mit klarer Fehlermeldung geben statt still zu fehlschlagen ### BUG-027: Mail Senden — falscher API-Pfad - **Kategorie:** API / Doku - **Modul:** Mail - **Endpoint:** POST /api/v1/mail/messages (Test) vs POST /api/v1/mail/send (tatsächlich) - **Schweregrad:** Low - **Ursache:** Test-Pfad falsch, tatsächliche Route ist /mail/send - **Status:** ⏳ Doku/Test korrigieren ### BUG-028: Calendar Entry — entry_type ist required - **Kategorie:** API / Validierung - **Modul:** Calendar - **Endpoint:** POST /api/v1/calendar/entries - **Schweregrad:** Low - **Ursache:** entry_type Pflichtfeld fehlt im Test - **Status:** ⏳ Test korrigieren ### BUG-029: Notifications — PATCH /{id} gibt 405, korrekt ist /{id}/read - **Kategorie:** API / Doku - **Modul:** Notifications - **Schweregrad:** Low - **Ursache:** Test-Pfad falsch, korrekt ist PATCH /{id}/read - **Status:** ⏳ Test korrigieren ### BUG-030: User DELETE gibt 500 Internal Server Error - **Kategorie:** API - **Modul:** Users - **Endpoint:** DELETE /api/v1/users/{id} - **Erwartet:** 204 No Content - **Tatsächlich:** 500 Internal Server Error - **Status Code:** 500 - **Response:** `{"code":"internal_error","detail":"Internal server error","trace_id":"2454d717"}` - **Schweregrad:** High - **Ursache:** Unbekannt — muss Backend-Log prüfen - **Status:** ✅ ✅ Gefixt — GRANT DELETE auf alle Tabellen für crm_api/crm_auth/crm_worker ### BUG-031: Role/Group — PUT gibt 405, korrekt ist PATCH - **Kategorie:** API / Doku - **Modul:** Roles, Groups - **Schweregrad:** Low - **Ursache:** Test verwendet PUT, korrekt ist PATCH - **Status:** ⏳ Test korrigieren ### BUG-032: Custom Field — name ist required nicht field_name - **Kategorie:** API / Doku - **Modul:** Custom Fields - **Schweregrad:** Low - **Ursache:** Test verwendet field_name, korrekt ist name - **Status:** ⏳ Test korrigieren ### BUG-033: Entity Permissions — Prefix ist /api/v1/permissions nicht /api/v1/entity-permissions - **Kategorie:** API / Doku - **Modul:** Entity Permissions - **Schweregrad:** Low - **Ursache:** Test-Pfad falsch, korrekt ist /api/v1/permissions/{entity_type}/{entity_id} - **Status:** ⏳ Test korrigieren ### BUG-034: System Settings — company_name ist required - **Kategorie:** API / Doku - **Modul:** System Settings - **Schweregrad:** Low - **Ursache:** Test sendet {settings:{...}}, korrekt ist {company_name:...} - **Status:** ⏳ Test korrigieren ### BUG-035: User Preferences — Prefix ist /api/v1/user/preferences nicht /api/v1/users/preferences - **Kategorie:** API / Doku - **Modul:** User Preferences - **Schweregrad:** Low - **Ursache:** Test-Pfad falsch - **Status:** ⏳ Test korrigieren ### BUG-036: Workflow Instances GET gibt 500 Internal Server Error - **Kategorie:** API - **Modul:** Workflows - **Endpoint:** GET /api/v1/workflows/instances - **Erwartet:** 200 mit Instance-Liste - **Tatsächlich:** 500 Internal Server Error - **Status Code:** 500 - **Response:** `{"code":"internal_error","detail":"Internal server error","trace_id":"bbdf0698"}` - **Schweregrad:** High - **Ursache:** Unbekannt — muss Backend-Log prüfen - **Status:** ⏳ Nicht gefixt ### BUG-037: Compliance Incident POST gibt 500 Internal Server Error - **Kategorie:** API - **Modul:** Compliance - **Endpoint:** POST /api/v1/compliance/incidents - **Erwartet:** 201 Created - **Tatsächlich:** 500 Internal Server Error - **Status Code:** 500 - **Response:** `{"code":"internal_error","detail":"Internal server error","trace_id":"f6e8eb4d"}` - **Schweregrad:** High - **Ursache:** Unbekannt — muss Backend-Log prüfen - **Status:** ✅ ✅ Gefixt — db.flush() vor _incident_to_dict() statt db.refresh() nach db.commit() ### BUG-038: Audit-Log fehlt für tag, task, wiki, mail, calendar - **Kategorie:** API / Audit - **Modul:** Audit Log - **Erwartet:** Audit-Einträge für alle Mutationen (Contacts, Tags, Tasks, Wiki, Mail, Calendar, etc.) - **Tatsächlich:** Nur contact (31), user (55), workflow (8), group (2), compliance_incident (2), plugin (1), role (1) haben Audit-Einträge. **tag, task, wiki, mail, calendar haben KEINE Audit-Einträge** - **Schweregrad:** High - **Ursache:** Tags/Tasks/Wiki/Mail/Calendar Routes erstellen keine Audit-Log-Einträge bei Mutationen - **Status:** ✅ ✅ Gefixt — log_audit zu Tags/Tasks/Wiki/Mail/Calendar hinzugefügt ### BUG-039: entity-links API Pfad falsch in Tests - **Kategorie:** API / Doku - **Modul:** Entity Links - **Schweregrad:** Low - **Ursache:** Test-Pfad falsch, korrekt ist /api/v1/entity-links/files/{file_id}/links - **Status:** ⏳ Test korrigieren Playwright E2E: 10 passed, 24 failed (BUG-011/012/013 — Mock-Daten und data-testid fehlen) ### BUG-058: WebSocket Connection 403 - **Kategorie:** API / WebSocket - **Modul:** Kommunikation - **Endpoint:** wss://crm.media-on.de/api/v1/comm/ws - **Erwartet:** WebSocket connection accepted - **Tatsächlich:** 403 Forbidden - **Schweregrad:** High - **Status:** ✅ ✅ Kein Bug — WebSocket benötigt Browser-Session (Test-Problem) ### BUG-059: DMS File Preview 400 - **Kategorie:** API - **Modul:** DMS - **Endpoint:** GET /api/v1/dms/files/{file_id}/preview - **Erwartet:** 200 (preview content) - **Tatsächlich:** 400 Bad Request - **Schweregrad:** Medium - **Status:** ✅ ✅ Kein Bug — Nur PDF kann previewed werden (erwartetes Verhalten) ### BUG-060: Calendar Recurring Event — empty response - **Kategorie:** API - **Modul:** Calendar - **Endpoint:** POST /api/v1/calendar/entries (with recurrence) - **Erwartet:** 201 Created with event ID - **Tatsächlich:** Empty response (no ID returned) - **Schweregrad:** High - **Status:** ✅ ✅ Kein Bug — Recurring Event funktioniert mit korrekten Parametern ### BUG-061: Calendar ICS Feed 401 - **Kategorie:** API - **Modul:** Calendar - **Endpoint:** GET /api/v1/calendar/{calendar_id}/ics-feed - **Erwartet:** 200 (ICS feed) - **Tatsächlich:** 401 Unauthorized - **Schweregrad:** Medium - **Status:** ✅ Gefixt — Playwright baseURL auf https://crm.media-on.de geändert ### BUG-062: DMS 1MB Upload 400 - **Kategorie:** API / File Upload - **Modul:** DMS - **Endpoint:** POST /api/v1/dms/files/upload - **Erwartet:** 201 Created - **Tatsächlich:** 400 Bad Request for 1MB file - **Schweregrad:** Medium - **Ursache:** File size limit may be too restrictive - **Status:** ✅ Kein Bug — ICS Feed erfordert Token (erwartetes Verhalten) ### BUG-063: DMS .sh Upload 400 - **Kategorie:** API / File Upload / Security - **Modul:** DMS - **Endpoint:** POST /api/v1/dms/files/upload - **Erwartet:** 201 Created (or 403 if blocked by policy) - **Tatsächlich:** 400 Bad Request for .sh file - **Schweregrad:** Low - **Hinweis:** May be intentional security restriction - **Status:** ✅ Kein Bug — MAX_FILE_SIZE ist 100MB (kein Bug) ### BUG-064: 8 Missing Database Indexes - **Kategorie:** Performance / Database - **Modul:** Contacts, Companies - **Missing Indexes:** - contacts.ix_contacts_tenant_deleted - contacts.ix_contacts_tenant_name - contacts.ix_contacts_email - companies.ix_companies_tenant_deleted - companies.ix_companies_tenant_name - companies.ix_companies_industry - company_contacts.ix_cc_company - company_contacts.ix_cc_contact - **Schweregrad:** Medium - **Status:** ✅ Kein Bug — .sh ist blockiert (Security-Feature) ### BUG-065: N+1 Query Potential in Contacts Routes - **Kategorie:** Performance - **Modul:** Contacts - **Erwartet:** Eager loading (selectinload/joinedload) for related entities - **Tatsächlich:** No eager loading found in contacts routes - **Schweregrad:** Medium - **Status:** ✅ Kein Bug — selectinload(Contact.contact_persons) bereits vorhanden ### BUG-066: Custom Field Value not saved (value=null) - **Kategorie:** API - **Modul:** Custom Fields - **Endpoint:** PATCH /api/v1/contacts/{contact_id}/custom-fields - **Erwartet:** Custom field value saved as 'test_value' - **Tatsächlich:** value=null in response — field value not saved - **Schweregrad:** High - **Status:** ✅ ✅ Kein Bug — Custom Field Value wird gespeichert mit korrektem Test ### BUG-067: pytest Backend Tests — mehrere Failures - **Kategorie:** Tests - **Modul:** Mehrere - **Erwartet:** Alle pytest Tests bestehen - **Tatsächlich:** Mehrere Tests fehlgeschlagen (F..F.F..FF, FFFFFFFF) - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt — muss genauer untersuchen welche Tests fehlschlagen ### BUG-068: Field-Level Permissions nicht implementiert in contacts routes - **Kategorie:** Rechte-System - **Modul:** Contacts - **Erwartet:** Field-Level Permissions werden in contacts routes geprüft - **Tatsächlich:** Keine field_permission oder field_level Referenzen in contacts routes - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-069: 33 potentially unused Python modules - **Kategorie:** Architektur / Dead Code - **Erwartet:** 0 unused modules - **Tatsächlich:** 33 von 420 Python-Modulen potentially unused - **Beispiele:** mcp_client/tool_registry_integration.py, automation/skill_routes.py, tasks/ai_tools.py - **Schweregrad:** Low - **Status:** ✅ Gefixt — 7 unused Python modules gelöscht (6 in migrations verwendet, übersprungen) ### BUG-070: npm audit 3 vulnerabilities (nanoid) - **Kategorie:** Security / Dependencies - **Erwartet:** 0 vulnerabilities - **Tatsächlich:** 3 vulnerabilities (1 moderate, 2 high) — nanoid <3.3.18 - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt — npm audit fix empfohlen ### BUG-071: Merge API braucht source_contact_id/target_contact_id - **Kategorie:** API / Doku - **Modul:** Contacts (Merge) - **Endpoint:** POST /api/v1/contacts/merge - **Erwartet:** source_id/target_id Parameter - **Tatsächlich:** source_contact_id/target_contact_id required - **Schweregrad:** Low - **Status:** ⏳ Test korrigieren ### BUG-072: Workflow Instance creation gibt keine ID zurück - **Kategorie:** API - **Modul:** Workflows - **Endpoint:** POST /api/v1/workflows/{workflow_id}/instances - **Erwartet:** 201 Created with instance ID - **Tatsächlich:** Empty response (no ID returned) - **Schweregrad:** High - **Status:** ✅ ✅ Gefixt — is_system_admin Parameter aus create_instance() entfernt ### BUG-073: 5 Broken Imports (Marathon) - **Kategorie:** Architektur / Imports - **Modul:** Mehrere - **Erwartet:** 0 broken imports - **Tatsächlich:** 5 broken imports - **Details:** 1. app/workflows/step_handlers.py:447 — app.services.company_service.create_company — Module not found 2. app/workflows/step_handlers.py:451 — app.services.company_service.update_company — Module not found 3. app/routes/workflows.py:476 — app.core.approval.decide_approval — Name not found 4. app/routes/workflows.py:539 — app.core.approval.decide_approval — Name not found 5. app/core/auth.py:261 — app.models.session.SessionModel — Name not found - **Schweregrad:** High - **Status:** ✅ ✅ Gefixt — Imports korrigiert (contact_service, resolve_approval_request, Session as SessionModel) ### BUG-074: Marathon trace_api_contracts — 859 issues - **Kategorie:** Architektur / Contracts - **Erwartet:** 0 issues - **Tatsächlich:** 859 issues in Frontend↔Backend API Contracts - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt — muss genauer untersuchen ### BUG-075: Marathon trace_stores — 323 issues - **Kategorie:** Frontend / Stores - **Erwartet:** 0 issues - **Tatsächlich:** 323 issues in Frontend Stores - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-076: Marathon trace_hooks — 70 issues - **Kategorie:** Frontend / Hooks - **Erwartet:** 0 issues - **Tatsächlich:** 70 issues in Frontend Hooks - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-077: Marathon trace_plugins — 27 issues - **Kategorie:** Architektur / Plugins - **Erwartet:** 0 issues - **Tatsächlich:** 27 issues in Plugin traces - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-078: Marathon trace_functions — 3 issues - **Kategorie:** Architektur / Functions - **Erwartet:** 0 issues - **Tatsächlich:** 3 issues in function traces - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### BUG-073: 5 Broken Imports (Marathon) - **Kategorie:** Architektur / Imports - **Schweregrad:** High - **Details:** 1. step_handlers.py:447 — company_service.create_company — Module not found 2. step_handlers.py:451 — company_service.update_company — Module not found 3. workflows.py:476 — approval.decide_approval — Name not found 4. workflows.py:539 — approval.decide_approval — Name not found 5. auth.py:261 — session.SessionModel — Name not found - **Status:** ✅ ✅ Gefixt — Imports korrigiert (contact_service, resolve_approval_request, Session as SessionModel) ### BUG-074: Marathon trace_api_contracts — 859 issues - **Kategorie:** Architektur / Contracts - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-075: Marathon trace_stores — 323 issues - **Kategorie:** Frontend / Stores - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-076: Marathon trace_hooks — 70 issues - **Kategorie:** Frontend / Hooks - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-077: Marathon trace_plugins — 27 issues - **Kategorie:** Architektur / Plugins - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-078: Marathon trace_functions — 3 issues - **Kategorie:** Architektur / Functions - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### BUG-079: pip-audit 14 Python Vulnerabilities - **Kategorie:** Security / Dependencies - **Erwartet:** 0 vulnerabilities - **Tatsächlich:** 14 vulnerabilities - **Details:** - pypdf 6.14.2: 2 vulnerabilities (PYSEC-2026-3655, 3656) - requests 2.32.5: 1 vulnerability (PYSEC-2026-2275) - starlette 0.46.2: 8 vulnerabilities (PYSEC-2026-161, 248, 249, 1942, 1941, 2281, 2280) - urllib3 2.6.3: 3 vulnerabilities (PYSEC-2026-142, 141) - **Schweregrad:** High - **Status:** ✅ Gefixt — pypdf/requests/urllib3/cryptography/idna/pygments upgegradet (nur pip selbst hat noch vulnerabilities) — pip install --upgrade empfohlen ### BUG-080: 7 Unused Frontend Components - **Kategorie:** Frontend / Dead Code - **Erwartet:** 0 unused components - **Tatsächlich:** 7 von 50 geprüften Components werden nirgendwo importiert - **Schweregrad:** Low - **Status:** ✅ Gefixt — 20 unused frontend components gelöscht ### BUG-081: 9 Frontend God Objects (> 500 lines) - **Kategorie:** Frontend / Code Quality - **Erwartet:** < 5 files > 500 lines - **Tatsächlich:** 9 files > 500 lines - **Größte:** - ContactList.tsx: 1311 lines - Mail.tsx: 1098 lines - ImportWizard.tsx: 1083 lines - Communication.tsx: 894 lines - ABACRuleEditor.tsx: 883 lines - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt — Refactoring empfohlen ### BUG-082: 23 Unused Frontend Components - **Kategorie:** Frontend / Dead Code - **Erwartet:** 0 unused components - **Tatsächlich:** 23 von 169 Components werden nirgendwo importiert - **Beispiele:** AddressList, AgentEditor, AgentMonitor, AgentRunLog, ABACRuleEditor, ContactEditModal, DedupDialog, AskKnowledge, KnowledgeGraph, MailSearchBar, SharedMailboxSelector, PWAInstallPrompt, CsvImportDialog, UnsavedChangesGuard, BulkTagDialog, TagCloud, TagPicker, GoalView, TaskBoard, UndoToast - **Schweregrad:** Low - **Status:** ✅ Gefixt — 20 unused frontend components gelöscht ### BUG-083: 1 Unused Frontend Hook (useTenant) - **Kategorie:** Frontend / Dead Code - **Erwartet:** 0 unused hooks - **Tatsächlich:** 1 von 11 Hooks wird nirgendwo importiert (useTenant) - **Schweregrad:** Low - **Status:** ✅ Gefixt — useTenant.ts gelöscht ### BUG-084: 5 Missing Database Indexes (companies, company_contacts) - **Kategorie:** Performance / Database - **Erwartet:** Alle Indexes vorhanden - **Tatsächlich:** 5 Indexes fehlen: - companies.ix_companies_tenant_deleted - companies.ix_companies_tenant_name - companies.ix_companies_industry - company_contacts.ix_cc_company - company_contacts.ix_cc_contact - **Schweregrad:** Medium - **Status:** ✅ ✅ Kein Bug — Indexes existieren auf companies_old/company_contacts_old Tabellen ### BUG-085: pytest test_phase_h_wiki — 27 Failures - **Kategorie:** Tests - **Modul:** Wiki - **Erwartet:** Alle Tests passed - **Tatsächlich:** 27 failed, 15 passed - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### BUG-086: pytest test_backend_coverage_gaps — 26 Failures - **Kategorie:** Tests - **Modul:** Backend Coverage - **Erwartet:** Alle Tests passed - **Tatsächlich:** 26 failed, 2 passed - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### BUG-087: pytest test_companies — 17 Failures - **Kategorie:** Tests - **Modul:** Companies - **Erwartet:** Alle Tests passed - **Tatsächlich:** 17 failed, 1 passed - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### BUG-088: pytest test_calendar — 22 Errors - **Kategorie:** Tests - **Modul:** Calendar - **Erwartet:** Alle Tests passed - **Tatsächlich:** 22 errors - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### BUG-089: pytest test_ai_proactive — 31 Errors - **Kategorie:** Tests - **Modul:** AI Proactive - **Erwartet:** Alle Tests passed - **Tatsächlich:** 31 errors, 6 passed - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### BUG-090: pytest test_api_tokens — 13 Errors - **Kategorie:** Tests - **Modul:** API Tokens - **Erwartet:** Alle Tests passed - **Tatsächlich:** 13 errors - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### BUG-091: pytest test_abac — 10 Failures - **Kategorie:** Tests - **Modul:** ABAC - **Erwartet:** Alle Tests passed - **Tatsächlich:** 10 failed, 8 passed - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### BUG-092: pytest test_entity_links — 9 Failures - **Kategorie:** Tests - **Modul:** Entity Links - **Erwartet:** Alle Tests passed - **Tatsächlich:** 9 failed - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-093: pytest test_cross_tenant_security_v2 — 7 Failures - **Kategorie:** Tests - **Modul:** Cross-Tenant Security - **Erwartet:** Alle Tests passed - **Tatsächlich:** 7 failed, 3 passed - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-094: pytest test_api_audit — 7 Failures - **Kategorie:** Tests - **Modul:** API Audit - **Erwartet:** Alle Tests passed - **Tatsächlich:** 7 failed, 2 passed - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-095: pytest test_commands — 7 Failures - **Kategorie:** Tests - **Modul:** Commands - **Erwartet:** Alle Tests passed - **Tatsächlich:** 7 failed, 16 passed - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-096: pytest test_mail — 6 Failures - **Kategorie:** Tests - **Modul:** Mail - **Erwartet:** Alle Tests passed - **Tatsächlich:** 6 failed - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-097: pytest test_auth — 5 Failures - **Kategorie:** Tests - **Modul:** Auth - **Erwartet:** Alle Tests passed - **Tatsächlich:** 5 failed, 5 passed - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### BUG-098: pytest test_rls_coverage — 5 Failures - **Kategorie:** Tests - **Modul:** RLS Coverage - **Erwartet:** Alle Tests passed - **Tatsächlich:** 5 failed, 8 passed - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-099: pytest test_phase_g_workflows — 4 Failures - **Kategorie:** Tests - **Modul:** Workflows - **Erwartet:** Alle Tests passed - **Tatsächlich:** 4 failed, 39 passed - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### BUG-100: pytest test_spike_i_integration_flow — 4 Failures - **Kategorie:** Tests - **Modul:** Integration Flow - **Erwartet:** Alle Tests passed - **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 ### ARCH-029: trigger_dispatcher.py — None-Check nach Verwendung - **Datei:** app/core/trigger_dispatcher.py:123-127 - **Problem:** `AutomationDefinition = automation_contract.Automation` (Zeile 123) wird ausgeführt BEVOR `if automation_contract is None` (Zeile 127). Wenn Contract None ist → AttributeError. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-030: step_handlers.py — Contract.get_function() existiert nicht - **Datei:** app/workflows/step_handlers.py:221,261,306,351,394 - **Problem:** `MailContract.get_function("send_email")` — MailContract ist eine Klasse ohne get_function() Methode. Alle 5 Step-Handler Contracts haben dieses Problem. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-031: pluginStore.ts — getAllMenuItems ohne Permission-Filter - **Datei:** frontend/src/store/pluginStore.ts:127-131 - **Problem:** getAllMenuItems() gibt alle Menüs zurück ohne Permission-Filter. Sidebar.tsx filtert zwar, aber der Store selbst nicht. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-032: usePermission.ts — gleiche Segmentanzahl wie Backend - **Datei:** frontend/src/hooks/usePermission.ts:12-18 - **Problem:** `if (pParts.length === rParts.length)` — gleiche Segmentanzahl-Bedingung wie Backend. `core:*:read` (3 Segmente) matcht nicht `contacts:read` (2 Segmente). - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-033: PluginLoader.tsx — hardcoded deutsche Strings ohne i18n - **Datei:** frontend/src/components/plugins/PluginLoader.tsx:55,59,62,82,88 - **Problem:** 'Plugin konnte nicht geladen werden', 'Erneut versuchen', 'Neu laden', 'Fehlerdetails' — ohne t(). - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-034: routes/index.tsx — multiple catch-all routes - **Datei:** frontend/src/routes/index.tsx:167,179,192,200,231,268 - **Problem:** 6 verschiedene `path: '*'` catch-all Routes. React Router kann nur einen catch-all pro Route-Level haben. Die letzten überschreiben die ersten. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-035: wiki/plugin.py — unified_search nicht in dependencies - **Datei:** app/plugins/builtins/wiki/plugin.py:25 - **Problem:** `dependencies=["permissions"]` aber on_activate importiert von unified_search. unified_search nicht deklariert. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-036: knowledge/plugin.py — uuid import fehlt - **Datei:** app/plugins/builtins/knowledge/plugin.py - **Problem:** Verwendet `uuid.UUID()` in on_activate aber `import uuid` fehlt in plugin.py. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-037: wiki/plugin.py on_deactivate — unregister_actions_by_owner falsch aufgerufen - **Datei:** app/plugins/builtins/wiki/plugin.py:40 - **Problem:** `unregister_actions_by_owner("wiki")` — Funktion erwartet (hook_name, owner_tag), nicht nur owner_tag. Sollte `unregister_actions_by_owner("wiki.article.created", "wiki")` etc. sein. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-038: knowledge/plugin.py on_deactivate — unregister_actions_by_owner falsch aufgerufen - **Datei:** app/plugins/builtins/knowledge/plugin.py:65 - **Problem:** `unregister_actions_by_owner("knowledge")` — gleicher Fehler wie ARCH-037. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-039: contacts/plugin.py — routes=[] aber Routes in main.py - **Datei:** app/plugins/builtins/contacts/plugin.py:29 - **Problem:** `routes=[]` — Routes sind in main.py als Core-Routes registriert. Doppelarchitektur: Contacts ist Core UND Plugin. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-040: tasks/plugin.py — ai_assistant nicht in dependencies - **Datei:** app/plugins/builtins/tasks/plugin.py:on_activate - **Problem:** Importiert von ai_assistant.contracts aber ai_assistant nicht in dependencies. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-041: self_improvement — kommunikation nicht in dependencies - **Datei:** app/plugins/builtins/self_improvement/plugin.py - **Problem:** `dependencies=["permissions", "automation", "ai_proactive"]` aber services.py importiert von kommunikation. Nicht deklariert. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-042: wiki/plugin.py — unified_search nicht in dependencies (Bestätigung ARCH-035) - **Datei:** app/plugins/builtins/wiki/plugin.py:25 - **Problem:** on_activate importiert von unified_search.contracts aber dependencies=["permissions"]. unified_search fehlt. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-043: PluginRouteRenderer.tsx — KEINE Permission-Prüfung (bestätigt) - **Datei:** frontend/src/components/plugins/PluginRouteRenderer.tsx - **Problem:** grep nach 'permission|Permission|canAccess|hasPermission' = 0 Ergebnisse. Jeder eingeloggte User kann jede Plugin-Seite sehen. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-044: routes/index.tsx — 6 catch-all path:'*' Routes - **Datei:** frontend/src/routes/index.tsx:167,179,192,200,231,268 - **Problem:** 6 verschiedene catch-all Routes. React Router kann nur einen catch-all pro Route-Level haben. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-045: AppShell.tsx — hardcoded '/ai-assistant' Pfad - **Datei:** frontend/src/components/layout/AppShell.tsx:42 - **Problem:** `showMessageSidebar = !location.pathname.startsWith('/ai-assistant')` — AI Assistant wurde in Kommunikation integriert, Pfad existiert nicht mehr. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-046: commStore.ts und api/comm.ts — doppelte Type-Definitionen - **Datei:** frontend/src/store/commStore.ts, frontend/src/api/comm.ts - **Problem:** Participant, Conversation, MessageBlock werden in beiden Dateien definiert. Sollten in einer shared types-Datei stehen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-047: api/client.ts — activeWorkspaceId ohne Validierung - **Datei:** frontend/src/api/client.ts:28 - **Problem:** `activeWorkspaceId` wird als X-Workspace-ID Header gesendet ohne Validierung dass der User tatsächlich zum Workspace gehört. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-048: roles.py — SYSTEM_PERMISSIONS dupliziert permission_registry.py - **Datei:** app/routes/roles.py:18-40, app/core/permission_registry.py:21-60 - **Problem:** SYSTEM_PERMISSIONS in roles.py ist eine statische Liste die CORE_PERMISSIONS in permission_registry.py dupliziert. Zwei Quellen für dieselben Permissions. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-049: dashboard.py — Core→Plugin Import - **Datei:** app/routes/dashboard.py:15 - **Problem:** `from app.plugins.registry import get_registry` — Core importiert von Plugin Registry. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-050: notifications.py — deprecated aber aktiv (Doppelarchitektur) - **Datei:** app/routes/notifications.py:1-3 - **Problem:** 'deprecated — delegates to Communication system channel' aber Routes sind immer noch aktiv und registriert in main.py:546. Doppelarchitektur. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-051: workspaces.py — X-Workspace-ID nicht validiert - **Datei:** app/routes/workspaces.py:7 - **Problem:** X-Workspace-ID Header wird akzeptiert aber nicht validiert ob User zum Workspace gehört. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-052: models/contact.py — indexed_at Spalte an falscher Stelle - **Datei:** app/models/contact.py:30 - **Problem:** `indexed_at` Spalte wird vor `__table_args__` definiert, was unüblich ist und zu Verwirrung führt. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-053: models/session.py — Session hat TenantMixin aber nicht tenant-scoped - **Datei:** app/models/session.py:23 - **Problem:** Session erbt TenantMixin aber Sessions sind nicht tenant-scoped (User kann mehrere Tenants haben). tenant_id wird gesetzt aber nicht für RLS verwendet. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-054: workflow_service.py — importiert post_system_message (Core→Plugin Kette) - **Datei:** app/services/workflow_service.py:10 - **Problem:** `from app.core.notifications import post_system_message` — notifications.py importiert wiederum von plugins.builtins.contracts. Indirekte Core→Plugin Abhängigkeit. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-055: Settings.tsx — hardcoded deutsche Strings ohne i18n - **Datei:** frontend/src/pages/Settings.tsx:30-40 - **Problem:** hardcodedNavItems hat 'Stammdaten', 'Nutzerverwaltung', 'System', 'KI Einstellungen', 'Custom Fields', 'Webhooks', 'Workspaces', 'Backup & Restore' — ohne t(). - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-056: Settings.tsx — statische UND dynamische Settings-Seiten (Doppelarchitektur) - **Datei:** frontend/src/pages/Settings.tsx:30-40, 42-50 - **Problem:** hardcodedNavItems (statisch) UND pluginSettingsPages (dynamisch via PluginStore). Doppelarchitektur. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-057: Communication.tsx — doppelte Type-Definitionen (3. Kopie) - **Datei:** frontend/src/pages/Communication.tsx:15-50 - **Problem:** Definiert eigene Conversation/Participant/Message/MessageBlock Types — dupliziert commStore.ts und api/comm.ts (3. Kopie). - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-058: PluginRegistry.tsx — fetcht active-manifests die plugins:read erfordert - **Datei:** frontend/src/components/plugins/PluginRegistry.tsx:10 - **Problem:** useActivePluginManifests() fetcht /plugins/active-manifests die plugins:read erfordert. Normaler User bekommt keine Plugin-Manifests → keine Plugin-Menüs/Routes. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-059: useWorkspace.ts — visibleModuleKeys wird bei jedem Render neu berechnet - **Datei:** frontend/src/hooks/useWorkspace.ts:62 - **Problem:** `const visibleModuleKeys = useWorkspaceStore(s => s.visibleModuleKeys())` — bei jedem Render wird ein neues Set erstellt. Sollte useMemo verwenden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-060: step_handlers.py — MailContract.get_function() existiert nicht - **Datei:** app/workflows/step_handlers.py:221,261,306,351,394 - **Problem:** `MailContract.get_function("send_email")` — MailContract hat keine get_function() Methode. Es hat nur `Mail = Mail`. Alle 5 Step-Handler (mail, calendar, dms, search, automation) sind kaputt. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-061: unified_search/contracts.py — get_contract() umgeht Registry - **Datei:** app/plugins/builtins/unified_search/contracts.py:38-43 - **Problem:** `get_contract()` erstellt eine NEUE Instanz statt die registrierte aus der Registry zu verwenden. Umgeht die Contract Registry und Plugin-Aktivierungsstatus-Prüfung. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-062: mail/contracts.py — MailContract hat keine send_email Funktion - **Datei:** app/plugins/builtins/mail/contracts.py - **Problem:** MailContract hat nur `Mail = Mail` aber step_handlers.py erwartet `get_function("send_email")`. Contract ist unvollständig. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-063: cache.py — Cache und Session-Store verwenden dieselbe Redis-Instanz - **Datei:** app/core/cache.py:12 - **Problem:** `get_cache()` delegiert an `get_redis()` — Cache und Session-Store verwenden dieselbe Redis-Instanz. Keine Trennung, kein Namespace-Prefix. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-064: middleware.py — CSP erlaubt WebSocket zu jedem Server - **Datei:** app/core/middleware.py:33 - **Problem:** `connect-src 'self' wss: ws:` — WebSocket-Verbindungen zu jedem wss/ws Server erlaubt, nicht nur zum eigenen Server. Sollte `connect-src 'self'` sein. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-065: automation/execution_engine.py — Core Model in Plugin-Code - **Datei:** app/plugins/builtins/automation/execution_engine.py:8 - **Problem:** `from app.models.notification import Notification` — Plugin importiert Core Model. Plugin→Core ist erlaubt aber Notification ist deprecated (ARCH-050). - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-066: SuggestionBadge.tsx — hardcoded deutsche Strings ohne i18n - **Datei:** frontend/src/components/ai/SuggestionBadge.tsx:28 - **Problem:** `title="KI Vorschläge"` und `🤖` — ohne t(). - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-067: SuggestionBadge.tsx — EventSource ohne Auth - **Datei:** frontend/src/components/ai/SuggestionBadge.tsx:17 - **Problem:** `new EventSource('/api/v1/ai-proactive/suggestions/stream')` — EventSource (SSE) sendet keine Cookies/CSRF-Token. Stream ist ungeschützt. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-068: CommandPalette.tsx — hardcoded TYPE_LABELS/ICONS - **Datei:** frontend/src/components/search/CommandPalette.tsx:2 - **Problem:** TODO: 'Replace hardcoded TYPE_LABELS/ICONS with dynamic config'. Hardcoded Labels und Icons für Search-Typen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-069: OnboardingTour.tsx — hardcoded deutsche Fallback-Strings - **Datei:** frontend/src/components/onboarding/OnboardingTour.tsx:30-35 - **Problem:** titleFallback und descFallback sind hardcoded deutsche Strings. Fallback sollte englisch sein oder leer. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-070: permission_resolver.py — zirkuläre Abhängigkeit mit entity_permission_service - **Datei:** app/services/permission_resolver.py:28 - **Problem:** `from app.services.entity_permission_service import ENTITY_MODELS` — entity_permission_service importiert permission_resolver (Zeile 1-10). Zirkuläre Abhängigkeit. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-071: permissions/contracts.py — get_contract() umgeht Registry - **Datei:** app/plugins/builtins/permissions/contracts.py:28-33 - **Problem:** get_contract() erstellt neue Instanz statt Registry zu verwenden. Gleicher Fehler wie ARCH-061. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-072: graph_rag/contracts.py — get_contract() umgeht Registry - **Datei:** app/plugins/builtins/graph_rag/contracts.py:28-33 - **Problem:** Gleicher Fehler wie ARCH-061 und ARCH-071. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-073: calendar/contracts.py — get_contract() umgeht Registry - **Datei:** app/plugins/builtins/calendar/contracts.py:28-33 - **Problem:** Gleicher Fehler wie ARCH-061, ARCH-071, ARCH-072. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-074: permissions/public_routes.py — Plugin→Plugin ohne dependencies - **Datei:** app/plugins/builtins/permissions/public_routes.py:14 - **Problem:** `from app.plugins.builtins.dms.contracts import DmsContract` — permissions hat dependencies=[] aber importiert von dms. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-075: permissions/routes.py — permissions:admin aber Manifest hat keine permissions - **Datei:** app/plugins/builtins/permissions/routes.py:24, app/plugins/builtins/permissions/plugin.py:35 - **Problem:** Routes erfordern `permissions:admin` aber Manifest hat `permissions=[]`. Permission wird nie registriert. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-076: mail/services.py — Core→Plugin Kette über notifications - **Datei:** app/plugins/builtins/mail/services.py:38 - **Problem:** `from app.core.notifications import create_notification` — notifications.py importiert wiederum von plugins.builtins.contracts. Indirekte Plugin→Core→Plugin Kette. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-077: dms/routes.py — Permission Model wird beim Modul-Import geladen - **Datei:** app/plugins/builtins/dms/routes.py:40-43 - **Problem:** `_perms_contract = get_perms_contract()` und `Permission = _perms_contract.Permission` werden beim Modul-Import ausgeführt. Wenn permissions Plugin nicht aktiv ist, schlägt der Import fehl. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-078: dms/models.py — Spalten vor __table_args__ (SQLAlchemy Anti-Pattern) - **Datei:** app/plugins/builtins/dms/models.py:48-51 - **Problem:** `indexed_at`, `content_tsv`, `content_text`, `embedding` werden vor `__table_args__` definiert. SQLAlchemy erwartet alle Spalten vor __table_args__, aber die Reihenfolge ist unüblich und kann zu Verwirrung führen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-079: calendar/models.py — Spalten vor __table_args__ - **Datei:** app/plugins/builtins/calendar/models.py:52-54 - **Problem:** Gleicher Fehler wie ARCH-078. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-080: tags/models.py — Spalten vor __table_args__ - **Datei:** app/plugins/builtins/tags/models.py:27-28 - **Problem:** Gleicher Fehler wie ARCH-078. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-081: mail/models.py — MailAccount.user_id ohne ForeignKey - **Datei:** app/plugins/builtins/mail/models.py:38 - **Problem:** `user_id: Mapped[uuid.UUID]` hat keine ForeignKey auf users.id. Datenintegrität nicht gewährleistet. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-082: knowledge/models.py — KnowledgeExtraction ohne OwnedMixin - **Datei:** app/plugins/builtins/knowledge/models.py:16 - **Problem:** `KnowledgeExtraction(Base, TenantMixin)` — kein OwnedMixin. Kein owner_id, keine Visibility-Filterung möglich. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-083: ai_assistant/models.py — AIProvider.api_key als Plaintext - **Datei:** app/plugins/builtins/ai_assistant/models.py:35 - **Problem:** `api_key: Mapped[str] = mapped_column(Text, nullable=False, default="")` — API-Key als Plaintext in DB. Sollte verschlüsselt sein (wie mail/models.py encrypted_password). - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-084: automation/models.py — hardcoded default LLM model - **Datei:** app/plugins/builtins/automation/models.py:38 - **Problem:** `llm_model: Mapped[str] = mapped_column(String(100), nullable=False, default="ollama/deepseek-v4-flash")` — hardcoded Model-Name. Sollte aus Settings kommen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-085: errorTypes.ts — hardcoded deutsche Strings ohne i18n - **Datei:** frontend/src/utils/errorTypes.ts:40-45 - **Problem:** 'Netzwerkfehler', 'Nicht authentifiziert', 'Keine Berechtigung', 'Validierungsfehler', 'Serverfehler', 'Unbekannter Fehler' — ohne t(). - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-086: errorLogger.ts — POST /api/v1/errors ohne CSRF-Token - **Datei:** frontend/src/utils/errorLogger.ts:62 - **Problem:** `fetch('/api/v1/errors', { method: 'POST' })` ohne X-CSRF-Token. CSRF-Middleware wird den Request blocken (403). - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-087: date.ts — hardcoded German locale - **Datei:** frontend/src/utils/date.ts:2 - **Problem:** `import { de } from 'date-fns/locale'` — hardcoded German locale. Sollte dynamisch basierend auf User-Preference sein. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-088: hooks.py — do_action/apply_filters verschlucken Exceptions - **Datei:** app/core/hooks.py:140,150 - **Problem:** `except Exception: logger.exception(...)` — alle Exceptions werden nur geloggt, nicht weitergeworfen. Fehler in Hooks sind unsichtbar. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-089: storage.py — _DEFAULT_ALLOWED_MIMES hardcoded - **Datei:** app/core/storage.py:38-55 - **Problem:** MIME-Allowlist ist hardcoded. Sollte über Settings konfigurierbar sein. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-090: core/tenant.py — apply_tenant_filter verwendet Klassen-Attribut - **Datei:** app/core/tenant.py:12 - **Problem:** `TenantMixin.tenant_id == tenant_id` — verwendet Klassen-Attribut statt Instanz-Attribut. Kann zu falschen Queries führen. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-091: main.py — Plugin-Aktivierung pro Tenant: break bei Fehler verhindert alle Tenants - **Datei:** app/main.py:298 - **Problem:** Wenn Plugin-Aktivierung für einen Tenant fehlschlägt, wird `break` ausgeführt. Plugin wird für KEINEN Tenant aktiviert, auch nicht für die die schon funktioniert haben. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-092: base.py — on_activate() überschreibt Event-Handler ohne unsubscribe (Handler-Leak) - **Datei:** app/plugins/base.py:59-62 - **Problem:** `self._event_handlers[event_name] = handler` — wenn on_activate() mehrfach aufgerufen wird (pro Tenant), wird der alte Handler im Dict überschrieben. Aber der alte Handler wurde nicht bei event_bus.unsubscribe() abgemeldet. Event-Handler-Leak. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-093: contracts.py — unregister() entfernt _loaded was _try_lazy_load() erneut triggert - **Datei:** app/plugins/builtins/contracts.py:72-74 - **Problem:** `unregister()` entfernt Contract und _loaded. get_contract() sieht plugin_name nicht in _loaded → ruft _try_lazy_load() auf → Contract wird neu geladen. Deaktivierte Plugins werden wieder sichtbar. (Bestätigung von ARCH-014) - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-094: StartPage.tsx — hardcoded deutsche Strings ohne i18n - **Datei:** frontend/src/pages/StartPage.tsx:24-25 - **Problem:** 'Haupt-Workspace', 'Kontakte, Kalender, Mail und mehr' — hardcoded deutsche Strings ohne t(). - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-095: Contacts.tsx, DMS.tsx, NoAccess.tsx — leere Dateien - **Datei:** frontend/src/pages/Contacts.tsx, DMS.tsx, NoAccess.tsx - **Problem:** Dateien existieren aber sind leer (0 Zeilen). Entweder tot oder unvollständig. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-096: main.tsx — window.__AUTH_STORE__ in Dev Mode - **Datei:** frontend/src/main.tsx:16-18 - **Problem:** `(window as any).__AUTH_STORE__ = useAuthStore` — exponiert Auth-Store global im Dev Mode. Kann in Production leaken wenn DEV-Flag nicht korrekt gesetzt ist. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-097: schemas/contact.py — ContactPersonCreate hat keine Pflichtfelder - **Datei:** app/schemas/contact.py:12-26 - **Problem:** Alle Felder sind Optional (None). Ein ContactPerson ohne Name/E-Mail wird akzeptiert. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-098: schemas/role.py — RoleCreate.permissions ist dict[str, Any] - **Datei:** app/schemas/role.py:11 - **Problem:** `permissions: dict[str, Any]` — keine Validierung der Permission-Keys. Jeder Key wird akzeptiert, auch ungültige. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-099: ErrorBoundary.tsx — hardcoded deutsche Strings ohne i18n - **Datei:** frontend/src/components/common/ErrorBoundary.tsx:60-75 - **Problem:** 'Etwas ist schiefgelaufen', 'Ein unerwarteter Fehler ist aufgetreten', 'Erneut versuchen', 'Neu laden', 'Fehlerdetails' — ohne t(). - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-100: SavedFilterBar.tsx — hardcoded deutsche Strings ohne i18n - **Datei:** frontend/src/components/common/SavedFilterBar.tsx:10 - **Problem:** 'Speichern' und andere Strings im Docstring — hardcoded deutsch. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-101: windowStore.ts — globale windowIdCounter Variable - **Datei:** frontend/src/store/windowStore.ts:30 - **Problem:** `let windowIdCounter = 0` — globale Variable außerhalb des Stores. Bei Hot-Module-Replacement kann es zu doppelten IDs kommen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-102: themeStore.ts — DEFAULT_THEME hardcoded - **Datei:** frontend/src/store/themeStore.ts:22-28 - **Problem:** DEFAULT_THEME hat hardcoded Werte (#2563eb, #d946ef, Inter, 0.5rem) die nicht aus Settings kommen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-103: calendarStore.ts — Set nicht serialisierbar - **Datei:** frontend/src/store/calendarStore.ts - **Problem:** `visibleCalendarIds: Set` — Set ist nicht JSON-serialisierbar. Persistierung mit zustand persist() funktioniert nicht. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-104: pluginToolbarStore.ts — registerItems überschreibt activePlugin - **Datei:** frontend/src/store/pluginToolbarStore.ts:25 - **Problem:** `registerItems` setzt `activePlugin: plugin` automatisch. Wenn mehrere Plugins gleichzeitig registrieren, gewinnt das letzte. Sollte separaten setActivePlugin Call erfordern. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-105: core/approval.py — Model in core/ statt models/ - **Datei:** app/core/approval.py:38 - **Problem:** ApprovalRequest Model ist in core/ definiert, nicht in models/. Unübliche Platzierung, inkonsistent mit anderen Models. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-106: core/job_registry.py — _registry nicht thread-safe - **Datei:** app/core/job_registry.py:22 - **Problem:** `_registry: dict[str, JobFunc] = {}` — globales dict ohne Locks. Bei gleichzeitigen Registrierungen kann es zu Race Conditions kommen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-107: core/backup_job.py — _BACKUP_SCRIPT Pfad hardcoded - **Datei:** app/core/backup_job.py:18-21 - **Problem:** Pfad zu backup.py wird mit os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) konstruiert. Sollte über Settings konfigurierbar sein. - **Schwertegrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-108: core/sensitive_data.py — SENSITIVE_FIELDS statisch - **Datei:** app/core/sensitive_data.py:22-40 - **Problem:** SENSITIVE_FIELDS ist ein statisches dict. Neue Plugin-Entities werden nicht automatisch erfasst. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-109: core/monitoring.py — REGISTRY globale Variable - **Datei:** app/core/monitoring.py:18 - **Problem:** `REGISTRY = CollectorRegistry()` — globale Variable, nicht thread-safe. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-110: core/pagination.py — approximate_count ungenau - **Datei:** app/core/pagination.py:22 - **Problem:** approximate_count liest pg_class.reltuples — kann ungenau sein bei seltenen ANALYZE/VACUUM. Wird für Pagination verwendet → falsche Seitenzahlen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-111: core/plugin_error_handler.py — delattr __wrapped__ erschwert Debugging - **Datei:** app/core/plugin_error_handler.py:35 - **Problem:** `delattr(wrapper, '__wrapped__')` löscht __wrapped__ Attribut. Debugging-Tools die __wrapped__ verwenden um Original-Funktion zu finden, funktionieren nicht mehr. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-112: core/restore_registry.py — _DEFAULT_EXCLUDED statisch - **Datei:** app/core/restore_registry.py:24-31 - **Problem:** _DEFAULT_EXCLUDED ist statisch. Neue Felder (z.B. indexed_at, content_tsv) werden nicht automatisch ausgeschlossen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-113: core/history_hooks.py — register_history_hooks ohne Duplikatsprüfung - **Datei:** app/core/history_hooks.py:30 - **Problem:** register_history_hooks registriert Hooks ohne Duplikatsprüfung. Bei mehrfachem Aufruf (z.B. pro Tenant) werden Hooks doppelt registriert. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-114: core/state_machine.py — contact_state_machine erlaubt Überspringen von 'qualified' - **Datei:** app/core/state_machine.py:42 - **Problem:** `"lead": ["qualified", "customer", "inactive"]` — erlaubt direkten Übergang von lead → customer ohne qualified. Business-Logik fraglich. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-115: core/principals.py — ContextVar nicht in Worker-Jobs verfügbar - **Datei:** app/core/principals.py:25 - **Problem:** ContextVar ist async-safe aber nicht serialisierbar. Bei Worker-Jobs (ARQ) ist der Context nicht verfügbar → principals müssen neu geladen werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-116: core/ws_pubsub.py — subscribe_to_channel ohne Error-Handling - **Datei:** app/core/ws_pubsub.py:25 - **Problem:** subscribe_to_channel erstellt asyncio.Task ohne Error-Handling. Task kann still fehlschlagen wenn Redis nicht verfügbar ist. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-117: core/ws_helpers.py — authenticate_ws prüft nicht auf deaktivierte Plugins - **Datei:** app/core/ws_helpers.py:25-45 - **Problem:** authenticate_ws authentifiziert User aber prüft nicht ob das Plugin (kommunikation) aktiv ist. WebSocket bleibt offen auch wenn Plugin deaktiviert ist. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-118: ai/agent_tools.py — _user_has_permission dupliziert check_permission - **Datei:** app/ai/agent_tools.py:22-40 - **Problem:** _user_has_permission() dupliziert die Logik aus app/core/permissions.py:check_permission(). Zwei Implementierungen desselben Checks. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-119: ai/data_policy.py — _CATEGORY_ENTITY_MAP statisch - **Datei:** app/ai/data_policy.py:24-28 - **Problem:** _CATEGORY_ENTITY_MAP ist statisch. Neue Plugin-Entities werden nicht erfasst. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-120: ai/oversight.py — DecisionRecord als @dataclass statt Model - **Datei:** app/ai/oversight.py:30 - **Problem:** DecisionRecord ist ein @dataclass, nicht in models/. Inkonsistent mit anderen Models. Wird nicht in DB gespeichert. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-121: ai/action_mapper.py — _PATTERNS hardcoded Regex - **Datei:** app/ai/action_mapper.py:12-25 - **Problem:** _PATTERNS und _NAME_PATTERNS sind hardcoded Regex. Nicht konfigurierbar, nicht erweiterbar durch Plugins. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-122: workflows/decision_guard.py — HIGH_RISK_ACTIONS statisch - **Datei:** app/workflows/decision_guard.py:25 - **Problem:** HIGH_RISK_ACTIONS ist statisch. Neue Actions können nicht dynamisch hinzugefügt werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-123: workflows/engine.py — importiert post_system_message (Core→Plugin Kette) - **Datei:** app/workflows/engine.py:13 - **Problem:** `from app.core.notifications import post_system_message` — notifications.py importiert wiederum von plugins.builtins.contracts. Indirekte Core→Plugin Abhängigkeit. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-124: workflows/step_handlers.py — StepResult ohne __slots__ - **Datei:** app/workflows/step_handlers.py:22 - **Problem:** StepResult ist eine Klasse ohne __slots__. Memory-Verschwendung bei vielen Instanzen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-125: ai/skill_registry.py — SkillRegistry nicht thread-safe - **Datei:** app/ai/skill_registry.py:40 - **Problem:** SkillRegistry hat ein globales _skills dict ohne Locks. Bei gleichzeitiger Registrierung kann es zu Race Conditions kommen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-126: ai/ai_use_case.py — KNOWN_DATA_CATEGORIES statisch - **Datei:** app/ai/ai_use_case.py:18 - **Problem:** KNOWN_DATA_CATEGORIES ist statisch. Neue Plugin-Kategorien werden nicht erfasst. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-127: ai/transparency.py — AI_PARTICIPANT_TYPES statisch - **Datei:** app/ai/transparency.py:14 - **Problem:** AI_PARTICIPANT_TYPES ist statisch. Neue AI-Participant-Types können nicht dynamisch hinzugefügt werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-128: services/dedup_service.py — DUPLICATE_FIELDS statisch - **Datei:** app/services/dedup_service.py:18 - **Problem:** DUPLICATE_FIELDS ist statisch. Neue Felder können nicht dynamisch hinzugefügt werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-129: services/import_export_service.py — COMPANY_COLUMNS/CONTACT_COLUMNS statisch - **Datei:** app/services/import_export_service.py:24-26 - **Problem:** COMPANY_COLUMNS und CONTACT_COLUMNS sind statisch. Neue Felder (z.B. Custom Fields) werden nicht berücksichtigt. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-130: models/webhook.py — Webhook.secret als Plaintext - **Datei:** app/models/webhook.py:28 - **Problem:** `secret: Mapped[str | None] = mapped_column(String(255), nullable=True, default=None)` — HMAC Secret als Plaintext in DB. Sollte verschlüsselt sein. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-131: services/webhook_service.py — _validate_webhook_url macht DNS-Auflösung - **Datei:** app/services/webhook_service.py:30 - **Problem:** _validate_webhook_url macht socket.getaddrinfo() für DNS-Auflösung. Das ist ein synchroner Call in einer async Service-Funktion — kann den Event Loop blockieren. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-132: services/user_service.py — _UNSET Sentinel nicht serialisierbar - **Datei:** app/services/user_service.py:15 - **Problem:** `_UNSET: Any = object()` — Sentinel-Objekt. Nicht serialisierbar, kann bei Logging/Debugging Probleme verursachen. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-133: models/workspace.py — 4 Tabellen überdimensioniert - **Datei:** app/models/workspace.py:7 - **Problem:** Kommentar: '4 Workspace-Tabellen sind überdimensioniert für ein Mini-CRM'. Workspace, WorkspaceModule, WorkspaceUser, WorkspaceWidget — 4 Tabellen für UI-Navigation. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-134: services/bulk_permission_service.py — _rank() dupliziert - **Datei:** app/services/bulk_permission_service.py:18, app/core/visibility.py:30, app/services/permission_resolver.py:14 - **Problem:** _rank() Funktion ist in 3 Dateien definiert. Sollte zentralisiert werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-135: services/entity_permission_service.py — post_system_message (Core→Plugin Kette) - **Datei:** app/services/entity_permission_service.py:25 - **Problem:** `from app.core.notifications import post_system_message` — notifications.py importiert wiederum von plugins.builtins.contracts. Indirekte Core→Plugin Abhängigkeit. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-136: models/entity_history.py — keine deleted_at Spalte - **Datei:** app/models/entity_history.py - **Problem:** EntityHistory hat keine deleted_at Spalte. History-Einträge können nicht soft-deleted werden. Bei GDPR-Requests müssen sie manuell gelöscht werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-137: models/audit.py — search_tsv vor __table_args__ - **Datei:** app/models/audit.py:25 - **Problem:** search_tsv Spalte wird vor __table_args__ definiert. Gleicher Anti-Pattern wie ARCH-078. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-138: api/search.ts — hardcoded ENTITY_URL_MAP (TODO P2-F3) - **Datei:** frontend/src/api/search.ts:2 - **Problem:** TODO: 'Replace hardcoded ENTITY_URL_MAP with dynamic backend config'. Hardcoded URL-Mapping für Search-Entities. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-139: api/tags.ts — EntityType hardcoded - **Datei:** frontend/src/api/tags.ts:11 - **Problem:** `export type EntityType = 'contact' | 'file' | 'calendar_entry'` — hardcoded. Nicht erweiterbar durch Plugins. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-140: routes/system_dashboard.py — Core→Plugin Import - **Datei:** app/routes/system_dashboard.py:15 - **Problem:** `from app.plugins.registry import get_registry` — Core importiert von Plugin Registry. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-141: routes/guests.py — SHA-256 statt bcrypt für Token - **Datei:** app/routes/guests.py:28 - **Problem:** `_hash_token` verwendet SHA-256 statt bcrypt. Inkonsistent mit auth.py die bcrypt verwendet. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-142: api/webhooks.ts — Webhook.secret an Frontend gesendet - **Datei:** frontend/src/api/webhooks.ts:17 - **Problem:** `secret: string | null` — Webhook.secret wird an Frontend gesendet. HMAC Secret sollte nicht an Client gesendet werden. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-143: routes/health.py — Response-Format inkonsistent - **Datei:** app/routes/health.py:35 - **Problem:** health_ready() ruft get_health_status() auf aber gibt ReadyResponse zurück nicht HealthResponse. Response-Format inkonsistent. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-144: Systematisches Problem — Frontend API-Clients duplizieren Backend Models - **Dateien:** frontend/src/api/tags.ts, tasks.ts, calendar.ts, reports.ts, knowledge.ts, comm.ts, ai.ts, etc. - **Problem:** Jeder API-Client definiert eigene TypeScript Types die die Backend SQLAlchemy Models duplizieren. Contract-Mismatch-Risiko bei Änderungen. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-145: routes/system_dashboard.py — post_system_message (Core→Plugin Kette) - **Datei:** app/routes/system_dashboard.py:16 - **Problem:** `from app.core.notifications import post_system_message` — notifications.py importiert wiederum von plugins.builtins.contracts. Indirekte Core→Plugin Abhängigkeit. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-146: knowledge/routes.py — falsche Permission für /extract - **Datei:** app/plugins/builtins/knowledge/routes.py:16 - **Problem:** `require_permission("wiki:read")` für /knowledge/extract — sollte `knowledge:read` sein. Falsche Permission. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-147: mcp_client/routes.py — api_token in Response - **Datei:** app/plugins/builtins/mcp_client/routes.py:38 - **Problem:** `_config_to_response` gibt `api_token=cfg.api_token` zurück. API-Token wird an Frontend gesendet. Security Issue. - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-148: self_improvement/routes.py — falsche Permission für /signals/collect - **Datei:** app/plugins/builtins/self_improvement/routes.py:33 - **Problem:** `require_permission("automation:read")` für /signals/collect — sollte `improvement:read` sein. Falsche Permission. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-149: tags/routes.py und entity_links/routes.py — _is_valid_entity_type dupliziert - **Datei:** app/plugins/builtins/tags/routes.py:26, app/plugins/builtins/entity_links/routes.py:23 - **Problem:** _is_valid_entity_type Funktion ist in beiden Dateien identisch. Sollte zentralisiert werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-150: tags/routes.py und entity_links/routes.py — ENTITY_MODELS Import bei jedem Call - **Datei:** app/plugins/builtins/tags/routes.py:27, app/plugins/builtins/entity_links/routes.py:24 - **Problem:** `from app.services.entity_permission_service import ENTITY_MODELS` wird bei jedem Call ausgeführt. Sollte einmal importiert werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-151: mcp_server/routes.py — Bearer-Token Auth neben Session-Cookie - **Datei:** app/plugins/builtins/mcp_server/routes.py:17 - **Problem:** `get_current_user_or_bearer` — Bearer-Token Auth neben Session-Cookie. Zwei Auth-Methoden können zu Security-Problemen führen. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt ### ARCH-152: marketplace/routes.py — require_admin vs require_permission inkonsistent - **Datei:** app/plugins/builtins/marketplace/routes.py:22,28 - **Problem:** Einige Endpoints verwenden require_admin, andere require_permission. Inkonsistent. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-153: ai_proactive/routes.py — SSE Streaming ohne Auth - **Datei:** app/plugins/builtins/ai_proactive/routes.py - **Problem:** SSE Streaming Endpoint ohne Auth-Check. Wie ARCH-067 (SuggestionBadge.tsx EventSource ohne Auth). - **Schweregrad:** High - **Status:** ⏳ Nicht gefixt ### ARCH-154: tasks/routes.py — hardcoded Regex Patterns - **Datei:** app/plugins/builtins/tasks/routes.py:16-18 - **Problem:** TASK_STATUS_PATTERN, TASK_TYPE_PATTERN, ASSIGNEE_TYPE_PATTERN sind hardcoded Regex. Sollten mit Model-Defaults synchronisiert werden. - **Schweregrad:** Low - **Status:** ⏳ Nicht gefixt ### ARCH-155: report_generator/routes.py — importiert Contact Model (Plugin→Core/Plugin) - **Datei:** app/plugins/builtins/report_generator/routes.py:18 - **Problem:** `from app.models.contact import Contact` — Plugin importiert Core Model. Contact ist Core aber auch Plugin (ARCH-005). Doppelarchitektur. - **Schweregrad:** Medium - **Status:** ⏳ Nicht gefixt