Files
leocrm/docs/test-bugs.md
T

1197 lines
65 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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: <Kurze Beschreibung>
- **Kategorie:** API | Frontend | DB | Rechte | Security | Plugin | Performance
- **Modul:** <Modul-Name>
- **Endpoint:** <HTTP Method + Path>
- **Erwartet:** <Was sollte passieren>
- **Tatsächlich:** <Was passiert ist>
- **Status Code:** <HTTP Status Code>
- **Response:** <Fehlermeldung / Response Body>
- **Schweregrad:** Critical | High | Medium | Low
- **Getestet von:** Admin | Sales | Reader
- **Trace-ID:** <trace_id falls verfügbar>
```
---
## 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:** ✅ Triage 2026-08-24 (Block D/D4): Präziser Entropie-Wert-Scan (Literals ≥16 Zeichen an secret-ish Namen, Placeholder gefiltert) = **0 echte hardcoded Secret-Werte**. Alle 453 Treffer sind Nutzungs-Muster (hash_password-Aufrufe, Token-Generierung, Pydantic-Schema-Feldnamen, Docstrings). Kein Handlungsbedarf.
### 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:** ✅ Triage 2026-08-24 (Block D/D4): Auf 10 f-string-SQL-Stellen + 2 String-Konkatenationen reduziert (Rest = parameterisierte text()-Aufrufe). Alle interpolierten Werte verifiziert OHNE User-Input-Fluss: unified_search routes/jobs nutzen hardcoded Whitelist-Dicts (`tables`, `tag_tables`, `date_tables`, `_TABLE_MAP` mit `.get()`+None-Guard), hnsw.ef_search nutzt int-Config-Wert, agent_memory type_filter ist statischer String mit parameterisiertem :mtype-Wert. **Kein fixbares Finding** — Muster ist sicher.
### 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:** ✅ Gefixt 2026-08-24 (Block E/I-C): GET /api/v1/plugins/{name} implementiert — Manifest-Metadaten + DB-Status kombiniert, 404 für unbekannte Plugins; Beweistest tests/test_plugin_detail.py 2/2 grün (200 für calendar inkl. status-Objekt, 404 für unknown); ruff clean. Nutzungsrelevanz war niedrig (Frontend ruft kein Detail auf), aber API-Vollständigkeit hergestellt.
### 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:** ✅ Triage+Scanner-Fixes 2026-08-24 (Block D/D5): 859→218 (-75%). Scanner-Bugs behoben: (1) Router-Präfixe fehlten im Endpoint-Pfad (371 Fehlalarme), (2) Multi-Router-Module (calendar_router/resource_router) nutzten falschen Präfix, (3) leere Pfad-Strings ('' für Collection-Routen) nicht erfasst, (4) Template-Literals (${qs}) nicht normalisiert. Verbleibende 196 backend_endpoint_no_frontend = legitime Admin-/Interne-Endpoints ohne Frontend-Nutzung. Verbleibende 22 frontend_call_no_backend = ~10 Parsing-Artefakte + ~12 echte Bugs als Follow-up dokumentiert:
- /ai/sessions-Familie ×5 (Frontend nutzt alte API; Backend hat /ai/conversations)
- /policies/{type}/{id}-Nested ×4 (Backend nur PUT/DELETE /policies/{policy_id})
- mail signatures PATCH/DELETE ×2, mail drafts PATCH-vs-PUT ×1, mail labels DELETE ×1
- DELETE /notifications/{id} ×1 (Backend nur PATCH .../read), GET /agents/skills ×1 (Backend /agents/tools)
### 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:** ✅ Triage+Scanner-Fixes 2026-08-24 (Block D/D5): 27→0. Root-Cause war Scanner-Bug: Erwartete manifest.py pro Plugin, aber Projekt-Konvention ist Inline-Manifest via PluginManifest(...) in plugin.py (0/28 Builtins haben manifest.py). Zusätzlich: migrations/tests-Verzeichnisse fälschlich als Plugins gewertet; menu_items-MEDIUM-Findings waren konzeptionell falsch (Frontend konsumiert Menüs dynamisch über active-manifests-API/pluginManifests.ts, nicht statische Imports).
### 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:** ✅ Gefixt 2026-08-24 (Block D/D1, 9d8da99): test_phase_h_wiki 42/42 grün verifiziert (Voll-Lauf gegen .env.test)
### 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:** ✅ Gefixt 2026-08-24 (Block D/D1, 9d8da99 + 6d04206): test_backend_coverage_gaps 41/41 grün; dabei SystemSettings-Schema-Drift behoben (backup_interval/retention/destination Model-Spalten + Migration 0142)
### BUG-087: pytest test_companies — 17 Failures
- **Kategorie:** Tests
- **Modul:** Companies
- **Erwartet:** Alle Tests passed
- **Tatsächlich:** 17 failed, 1 passed
- **Schweregrad:** High
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D1-b, 9d8da99): test_companies 18/18 grün; Root-Cause ContactCreate-Typ-Inferenz (Person-Payloads ohne type wurden als Firma abgelehnt → 422)
### BUG-088: pytest test_calendar — 22 Errors
- **Kategorie:** Tests
- **Modul:** Calendar
- **Erwartet:** Alle Tests passed
- **Tatsächlich:** 22 errors
- **Schweregrad:** High
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D1-c, f6e117b): test_calendar 34/34 grün; Root-Cause conftest fehlte CalendarPlugin-Import (abbe7a1-Regression)
### 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:** ✅ Gefixt 2026-08-24 (Block D/D1-d+e, f6e117b): test_ai_proactive 38 passed+1 skipped; Root-Causes: CalendarContract snake_case-Zugriffe ×4 (Produktionsbug behoben) + 2 stale Rate-Limit-Tests auf zentrale check_rate_limit umgestellt
### BUG-090: pytest test_api_tokens — 13 Errors
- **Kategorie:** Tests
- **Modul:** API Tokens
- **Erwartet:** Alle Tests passed
- **Tatsächlich:** 13 errors
- **Schweregrad:** High
- **Status:** ✅ Verifiziert 2026-08-24 (Block D/D1, Batch 4): test_api_tokens komplett grün
### BUG-091: pytest test_abac — 10 Failures
- **Kategorie:** Tests
- **Modul:** ABAC
- **Erwartet:** Alle Tests passed
- **Tatsächlich:** 10 failed, 8 passed
- **Schweregrad:** High
- **Status:** ✅ Verifiziert 2026-08-24 (Block D/D1, Batch 2): test_abac komplett grün
### BUG-092: pytest test_entity_links — 9 Failures
- **Kategorie:** Tests
- **Modul:** Entity Links
- **Erwartet:** Alle Tests passed
- **Tatsächlich:** 9 failed
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D3-d, ef90d57): test_permissions 22/22 grün; Root-Cause systemischer Permission-Resolver-Bug (DMS/Mail get_entity_models fehlten im ENTITY_MODELS-Mapping)
### 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:** ✅ Gefixt 2026-08-23 (Block H/A)
### 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:** ✅ Gefixt 2026-08-23 (Block H/A)
### 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:** ✅ Gefixt 2026-08-23 (Block H/A)
### 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:** ✅ Gefixt 2026-08-23 (Block A): Kanon-Schema modul:aktion festgelegt (docs/permissions.md), Manifest-Validator erzwingt es bei Load-Time, Quellvertragstest verhindert 3-Segment-Literals in app/routes
### 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:** ✅ Gefixt 2026-08-23 (Block A): Migration 0141 konvertiert Bestandsrollen core:*:X → *:X (Roundtrip per psql bewiesen); 14 Route-Literals delegations/policies/templates auf 2-Segment korrigiert; Hash-Gate unverändert grün
### 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:** ✅ Gefixt 2026-08-23 (Block H/A)
### 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:** ✅ Gefixt 2026-08-23 (Block A/A2): wiki deregistriert WikiSearchProvider via Contract (entity_type wiki_article); dabei 2 latente Bugs entdeckt und behoben — on_activate nutzte nicht existierende register_provider-Methode am unified_search-Contract, und beide Plugins importierten unregister_actions_by_owner als Modulfunktion (ImportError bei jeder Deaktivierung); jetzt get_hook_registry().unregister_all_for_plugin; Lifecycle-Symmetrie per Funktionstest bewiesen
### 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:** ✅ Gefixt 2026-08-23 (Block A/A2): Contract-only ohne direkten Plugin-Import; dabei latenter Bug entdeckt — KommunikationContract wurde nie importiert, die Proposal-Benachrichtigung lief in den stillen except-Zweig und war komplett tot; jetzt saubere Contract-Nutzung mit logger.warning wenn Contract fehlt
### 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:** ✅ Gefixt 2026-08-23 (Block H/A)
### 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:** ✅ Gefixt 2026-08-23 (Block A/A2): registry.deactivate ruft sync_notification_types() jetzt NACH dem DB-Status-Update auf — der Sync sieht den Plugin als inaktiv und entfernt seine Types; Fehler werden geloggt statt die Deaktivierung zu blockieren
### 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:** ✅ Gefixt 2026-08-23 (Block B/B3): /registry-Endpoint generiert jetzt dynamisch aus ENTITY_MODELS (Label-Map für bekannte Typen, Title-Case-Fallback für Plugin-Entities, Alias-Dedupe); notification ins Registry-Core ergänzt; neue Plugin-Entities erscheinen automatisch ohne Core-Änderung
### 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:** ✅ Gefixt 2026-08-23 (Block B/B3): Neue Core-Permissions custom_fields:read/write in CORE_PERMISSIONS registriert; alle 4 Definitions-Routes umgestellt; Values-Endpoint bleibt bei contacts (Entity-Zugriff); RBAC-Test unverändert grün
### 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:** ✅ Gefixt 2026-08-23 (Block H/A)
### 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:** ✅ Gefixt 2026-08-23 (Block B/B3): _get_write_permissions() generiert die Write-Permissions lazy aus der permission_registry (Core + aktive Plugins); Legacy-Liste nur noch als Fallback bei uninitialisierter Registry; Funktionstest beweist automatische Aufnahme von custom_fields:write und Plugin-Perms
### 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:** ✅ Triage 2026-08-24 (Block D/D6): Verifiziertes No-Op — bewusstes Design. Plugin-Services (comm_miniapps, comm_websocket, ai_ui_control_ws) registrieren sich selbst bei Plugin-on_activate (Lifecycle-Symmetrie aus Block A); initialize() stellt nur die Core-Basis bereit (cache, event_bus). Kein unvollständiger Code — Finding war ein Design-Missverständnis.
### 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:** `<Navigate to="/kein-zugriff" replace />` — hardcoded deutscher Pfad.
- **Schweregrad:** Low
- **Status:** ⏳ Nicht gefixt
### ARCH-026: Plugin Cross-Dependencies nicht deklariert
- **Dateien:** app/plugins/builtins/tasks/plugin.py, wiki/plugin.py, self_improvement/plugin.py
- **Problem:** tasks importiert von kommunikation (dependencies=["permissions"]), wiki importiert von unified_search (dependencies=["permissions"]), self_improvement importiert von kommunikation (dependencies=["permissions","automation","ai_proactive"]). Die tatsächlichen Cross-Plugin-Dependencies (kommunikation, unified_search) sind nicht deklariert.
- **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:** ✅ Verifiziert 2026-08-24 (Block D/D4-a): Bereits implementiert UND strenger als gefordert — get_settings() lehnt Default-Key UND <32-Zeichen-Keys Import-zeitig in ALLEN Umgebungen ab (RuntimeError, Traceback-Beweis)
### 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:** ✅ Gefixt 2026-08-23 (Block H/A)
### 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:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-031: knowledge/plugin.py — uuid nicht importiert (NameError zur Laufzeit)
- **Datei:** app/plugins/builtins/knowledge/plugin.py:28,30
- **Problem:** `uuid.UUID(str(tenant_id))` und `uuid.UUID(str(article_id))` werden in `on_wiki_create` und `on_wiki_update` verwendet, aber `uuid` wird nie importiert. NameError bei erstem Wiki-Artikel-Ereignis.
- **Schweregrad:** High
- **Status:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-032: knowledge/plugin.py + wiki/plugin.py — unregister_actions_by_owner mit falscher Signatur
- **Dateien:** app/plugins/builtins/knowledge/plugin.py:66, app/plugins/builtins/wiki/plugin.py:41
- **Problem:** `unregister_actions_by_owner("knowledge")` und `unregister_actions_by_owner("wiki")` rufen die Funktion mit nur 1 Argument auf. Die Signatur ist `unregister_actions_by_owner(hook_name: str, owner_tag: str)` — 2 Argumente. TypeError bei Deaktivierung.
- **Schweregrad:** High
- **Status:** ⏳ Nicht gefixt
### ARCH-033: kommunikation/plugin.py — on_deactivate entfernt nicht Services aus service_container
- **Datei:** app/plugins/builtins/kommunikation/plugin.py:on_deactivate
- **Problem:** `on_activate` registriert `comm_websocket` und `comm_miniapps` im service_container. `on_deactivate` entfernt diese nicht. Andere Plugins die auf diese Services zugreifen bekommen stale Referenzen.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-23 (Block A/A2): on_deactivate entfernt comm_websocket + comm_miniapps VOR super().on_deactivate(); dafür ServiceContainer.remove() ergänzt (fehlte komplett); Lifecycle-Symmetrie per Funktionstest bewiesen (Activate→da, Deactivate→weg, Re-Activate→ohne Dupes)
### ARCH-034: self_improvement/plugin.py — on_deactivate macht kein contract unregister
- **Datei:** app/plugins/builtins/self_improvement/plugin.py:on_deactivate
- **Problem:** `on_deactivate` ruft nicht `get_contract_registry().unregister(self.manifest.name)` auf. Contract bleibt nach Deaktivierung sichtbar.
- **Schweregrad:** Medium
- **Status:** ✅ Verifiziert 2026-08-23 (Block A/A2): Kein Fix nötig — Plugin definiert und registriert KEINEN Contract (grep-Beweis), es gibt nichts zu deregistrieren; Finding war gegen eine Annahme geschrieben die im Code nicht zutrifft
### ARCH-035: marketplace/plugin.py — on_deactivate macht kein contract unregister
- **Datei:** app/plugins/builtins/marketplace/plugin.py:on_deactivate
- **Problem:** `on_deactivate` ruft nicht `get_contract_registry().unregister(self.manifest.name)` auf. Contract bleibt nach Deaktivierung sichtbar.
- **Schweregrad:** Low
- **Status:** ✅ Verifiziert 2026-08-23 (Block A/A2): Kein Fix nötig — Plugin definiert und registriert KEINEN Contract (grep-Beweis), es gibt nichts zu deregistrieren; Finding war gegen eine Annahme geschrieben die im Code nicht zutrifft
### ARCH-036: mail/plugin.py — _auto_sync_task ist Klassenvariable, nicht Instanzvariable
- **Datei:** app/plugins/builtins/mail/plugin.py
- **Problem:** `_auto_sync_task: asyncio.Task | None = None` ist eine Klassenvariable. Bei mehreren MailPlugin-Instanzen (z.B. Reload) teilen sie sich denselben Task-Referenz. Kann zu doppelten Background-Tasks oder falschem Cleanup führen.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-23 (Block A/A2): __init__ ergänzt, _auto_sync_task ist jetzt Instanzvariable — mehrere MailPlugin-Instanzen teilen sich den Task-State nicht mehr
### ARCH-037: graph_rag/plugin.py — on_activate ruft registry.register() VOR super().on_activate()
- **Datei:** app/plugins/builtins/graph_rag/plugin.py:on_activate
- **Problem:** `registry.register(GraphRAGSearchProvider())` wird vor `super().on_activate()` aufgerufen. Wenn super().on_activate() fehlschlägt, bleibt der Search Provider registriert ohne dass Event-Handler aktiv sind.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-23 (Block A/A2): super().on_activate() läuft jetzt zuerst, eigene Registrierungen danach — ein Fehler im Plugin-Code kann die Basisklasse nicht mehr halb-initialisiert zurücklassen
### ARCH-038: worker.py — register_event_handlers() existiert nicht in BasePlugin
- **Datei:** app/core/worker.py:168, app/plugins/base.py
- **Problem:** Worker ruft `plugin.register_event_handlers(event_bus)` auf, aber BasePlugin hat keine solche Methode. `hasattr(plugin, 'register_event_handlers')` ist immer False. Im Worker werden Event-Handler NIE registriert — alle Events die über den Worker laufen (outbox events) werden nicht von Plugins verarbeitet.
- **Schweregrad:** High
- **Status:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-039: worker.py — cleanup jobs verwenden datetime.utcnow() (naive datetime)
- **Datei:** app/core/worker.py:cleanup_audit_log_job, cleanup_trash_job, cleanup_knowledge_job
- **Problem:** `datetime.utcnow() - timedelta(days=...)` verwendet naive datetime. AGENTS.md verbietet naive datetime — TIMESTAMPTZ only. Sollte `datetime.now(UTC)` sein.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D2): Beide Cleanup-Jobs auf datetime.now(UTC) umgestellt, lokale Imports erweitert; 0 utcnow-Referenzen verbleiben im Codebase
### ARCH-040: worker.py — cleanup_knowledge_job importiert direkt von Plugin (Core→Plugin)
- **Datei:** app/core/worker.py:cleanup_knowledge_job
- **Problem:** `from app.plugins.builtins.knowledge.models import KnowledgeExtraction` — Core importiert direkt von Plugin. Sollte über Contract laufen.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-041: trigger_dispatcher.py — _dispatch_matching_agents hat None-Check nach Verwendung
- **Datei:** app/core/trigger_dispatcher.py:172-173
- **Problem:** `AgentDefinition = automation_contract.AgentDefinition` (Zeile 172) wird ausgeführt BEVOR `if automation_contract is None` (Zeile 173). Wenn Contract None ist → AttributeError. Gleicher Bug wie ARCH-029.
- **Schweregrad:** High
- **Status:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-042: calendar/contracts.py + dms/contracts.py — get_contract() erzeugt neue Instanz statt registrierte zu nutzen
- **Dateien:** app/plugins/builtins/calendar/contracts.py:get_contract, app/plugins/builtins/dms/contracts.py:get_contract
- **Problem:** `get_contract()` erzeugt eine NEUE Contract-Instanz statt die registrierte aus der Registry zu nutzen. Das bedeutet es gibt zwei Instanzen — die registrierte und die lokal erzeugte. Änderungen an der registrierten Instanz sind nicht sichtbar.
- **Schweregrad:** Medium
- **Status:** ⏳ Nicht gefixt
### ARCH-043: automation/plugin.py — register_plugin_contributions nutzt Tenant.limit(1) statt current tenant
- **Datei:** app/plugins/builtins/automation/plugin.py:register_plugin_contributions
- **Problem:** `select(Tenant).limit(1)` nimmt den ersten Tenant in der DB, nicht den aktuellen Tenant. In Multi-Tenant-Setups werden Contributed Agents/Automations im falschen Tenant erstellt.
- **Schweregrad:** High
- **Status:** ✅ Gefixt 2026-08-23 (Block A): Konfigurierbarer system_tenant_slug (Default 'default', wie seed_admin) in Settings; wiederverwendbarer Helper get_system_tenant() im Core-Layer (app/core/db); beide automation-Stellen nutzen ihn; Test beweist Slug-Lookup gegen Decoy-Ersteintrag
### ARCH-044: ai_ui_control/plugin.py — on_deactivate ruft super().on_deactivate() VOR service_container.remove()
- **Datei:** app/plugins/builtins/ai_ui_control/plugin.py:on_deactivate
- **Problem:** `super().on_deactivate()` wird vor `service_container.remove("ai_ui_control_ws")` aufgerufen. Wenn super().on_deactivate() Event-Handler entfernt, kann ein Event noch den WebSocket-Manager versuchen zu nutzen der bereits durch super() als deaktiviert markiert wurde.
- **Schweregrad:** Low
- **Status:** ✅ Gefixt 2026-08-23 (Block A/A2): remove() läuft jetzt VOR super().on_deactivate(); dabei latenter Bug entdeckt — ServiceContainer hatte gar kein remove() (der guarded Aufruf hätte AttributeError geworfen); Methode ergänzt
### ARCH-045: Frontend — hardcoded deutsche Strings ohne i18n in mehreren Komponenten
- **Dateien:** frontend/src/components/contacts/FolderPermissionDialog.tsx:24-25, frontend/src/components/common/ShareDialog.tsx:39-40, frontend/src/components/layout/PluginToolbar.tsx:49,67, frontend/src/pages/SettingsStammdaten.tsx:173, frontend/src/pages/SettingsRechte.tsx:50, frontend/src/pages/Workflows.tsx:219, frontend/src/pages/AutomationSettings.tsx:24, frontend/src/components/workflows/WorkflowEditor.tsx:553, frontend/src/components/settings/WorkspaceManager.tsx:256,263
- **Problem:** Mehrere Frontend-Komponenten haben hardcoded deutsche Strings ('Löschen', 'Bearbeiten', 'Speichern', 'Kein Zugriff', 'Suchen', 'Error') ohne `t()` i18n-Aufruf. Verletzt AGENTS.md Frontend-Konvention.
- **Schweregrad:** Low
- **Status:** ⏳ Nicht gefixt
### ARCH-046: compliance.py — Core Route importiert direkt von Plugin Model
- **Datei:** app/routes/compliance.py:22
- **Problem:** `from app.plugins.builtins.automation.models import AgentDefinition` — Core Route importiert direkt von Plugin Model. Sollte über Contract laufen.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-047: step_handlers.py — SearchContract statt UnifiedSearchContract
- **Datei:** app/workflows/step_handlers.py:306
- **Problem:** `from app.plugins.builtins.unified_search.contracts import SearchContract` — die Klasse heißt `UnifiedSearchContract`, nicht `SearchContract`. ImportError zur Laufzeit.
- **Schweregrad:** High
- **Status:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-048: engine.py — register_workflow_event_handlers nutzt falschen payload key
- **Datei:** app/workflows/engine.py:register_workflow_event_handlers
- **Problem:** `payload.get("event", "")` — aber der outbox envelope nutzt `event_name` als key, nicht `event`. Workflow-Events werden nie triggern weil der key immer leer ist.
- **Schweregrad:** High
- **Status:** ⏳ Nicht gefixt
### ARCH-049: engine.py — Core→Plugin direkter Import von kommunikation.models
- **Datei:** app/workflows/engine.py:94,95
- **Problem:** `from app.plugins.builtins.kommunikation.models import CommConversation` — Core importiert direkt von Plugin. Sollte über Contract laufen.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-050: engine.py — acquire_lock awaitet nicht-async get_redis()
- **Datei:** app/workflows/engine.py:acquire_lock
- **Problem:** `r = await get_redis()` — `get_redis()` ist nicht async (gibt direkt aioredis.Redis zurück). `await` auf einem nicht-awaitable Objekt wirft TypeError.
- **Schweregrad:** High
- **Status:** ⏳ Nicht gefixt
### ARCH-051: Mehrere Routes nutzen dict body statt Pydantic schema
- **Dateien:** app/routes/companies.py:86,198, app/routes/entity_permissions.py:259,284, app/routes/guests.py:38, app/routes/system_settings.py:89,246, app/routes/users.py:371
- **Problem:** Mehrere Routes akzeptieren `body: dict[str, Any]` oder `body: dict` statt Pydantic schemas. Verletzt AGENTS.md: "Pydantic schemas validate input, never validate in routes".
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D3-g, c32e4bb): 14 dict-body-Routes auf Pydantic-Schemas umgestellt; ruff exit=0; create_app OK (559 routes)
### ARCH-052: storage.py — get_file_metadata nutzt asyncio.new_event_loop() in async Kontext
- **Datei:** app/core/storage.py:get_file_metadata
- **Problem:** `loop = asyncio.new_event_loop()` für S3 fallback — erstellt einen neuen Event Loop in einem async Kontext. Kann zu Deadlocks führen wenn bereits ein Loop läuft.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-23 (Block A): Neue get_file_metadata_async() awaited backend.exists() direkt; Sync-Funktion ist Wrapper mit Fail-Fast-Guard gegen verschachtelte Loops im laufenden Loop; bestehende Sync-Tests unverändert grün
### ARCH-053: audit.py — datetime.utcnow() naive datetime in retention cleanup
- **Datei:** app/routes/audit.py:179
- **Problem:** `datetime.utcnow() - timedelta(days=retention_days)` verwendet naive datetime. AGENTS.md verbietet naive datetime — TIMESTAMPTZ only. Sollte `datetime.now(UTC)` sein.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D2): Retention-Cutoff auf datetime.now(UTC) umgestellt, UTC-Import ergänzt
### ARCH-054: entity_permissions.py — _check_entity_ownership greift auf falsche Datenstruktur
- **Datei:** app/routes/entity_permissions.py:259
- **Problem:** `model_info = ENTITY_MODELS.get(entity_type)` gibt eine Model-Klasse zurück, nicht ein dict. `model_info["model"]` wirft TypeError. Sollte `model = ENTITY_MODELS.get(entity_type)` sein.
- **Schweregrad:** High
- **Status:** ✅ Gefixt 2026-08-23 (Block H/A)
### ARCH-055: errors.py — error.userAgent statt error.user_agent
- **Datei:** app/routes/errors.py:124
- **Problem:** `error.userAgent` im extra dict — aber das Pydantic model ErrorReport hat `user_agent` als field name, nicht `userAgent`. AttributeError zur Laufzeit.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D3-a, 0768cfb): Beide error.userAgent-Zugriffe auf error.user_agent korrigiert (ErrorReport definiert user_agent); AttributeError zur Laufzeit behoben
### ARCH-056: roles.py — hardcoded SYSTEM_PERMISSIONS dupliziert permission_registry.py
- **Datei:** app/routes/roles.py:38-70
- **Problem:** `SYSTEM_PERMISSIONS` Liste ist hardcoded und dupliziert `CORE_PERMISSIONS` aus `app/core/permission_registry.py`. Änderungen an permission_registry werden nicht in roles.py reflektiert.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D3-b, 0768cfb): SYSTEM_PERMISSIONS aus CORE_PERMISSIONS abgeleitet (36→47 Permissions, Drift bewiesen via Key-Diff); category→system für Frontend-Gruppierung remappt
### ARCH-057: roles.py — Zugriff auf private Variable registry._plugins
- **Datei:** app/routes/roles.py:87
- **Problem:** `registry._plugins.items()` greift auf eine private Variable zu. Sollte eine öffentliche Methode wie `registry.list_discovered()` oder `registry.get_all_plugins()` verwenden.
- **Schweregrad:** Low
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D3-c, 0768cfb): registry._plugins.items() durch öffentliche API list_discovered()+get_plugin() ersetzt
### ARCH-058: webhook_service.py — send_webhook nutzt naive datetime.utcnow()
- **Datei:** app/services/webhook_service.py:send_webhook
- **Problem:** `__import__("datetime").datetime.utcnow().isoformat() + "Z"` verwendet naive datetime. AGENTS.md verbietet naive datetime — TIMESTAMPTZ only. Sollte `datetime.now(UTC)` sein.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D2): Inline-__import__-Hack entfernt, sauberer UTC-Import; Wire-Format unverändert (isoformat().replace('+00:00','Z'))
### ARCH-059: ai_copilot_service.py — Legacy AIConversation/AIMessage statt kommunikation
- **Datei:** app/services/ai_copilot_service.py:18-21
- **Problem:** Nutzt `AIConversation`/`AIMessage` aus `app.models.ai_conversation` mit try/except ImportError fallback. Das ist das Legacy AI Chat System das nach kommunikation migriert werden sollte (ARCH-018 pattern). AI Copilot sollte die kommunikation Plugin Conversations nutzen.
- **Schweregrad:** Medium
- **Status:** ✅ Triage+Deprecation 2026-08-24 (Block D/D6): Beweise — Backend-only (0 Frontend-Referenzen in api/store), Test geskippt ('ai_copilot routes removed in Phase 2'), keine Router-Inklusion in main.py. Migration nach kommunikation wäre Verschwendung (Plugin deckt Chat bereits ab). Modul als deprecated markiert mit Abschaltplan im Service-Docstring; DeprecationWarning bei Import; Entfernung (routes/service/model + ai_conversations-Tabellen) als eigene Migration nach Traffic-Bestätigung.
### ARCH-060: backup_service.py — datetime.utcnow() naive datetime
- **Datei:** app/services/backup_service.py:create_backup
- **Problem:** `backup.completed_at = datetime.utcnow()` verwendet naive datetime. AGENTS.md verbietet naive datetime — TIMESTAMPTZ only. Sollte `datetime.now(UTC)` sein.
- **Schweregrad:** Medium
- **Status:** ✅ Gefixt 2026-08-24 (Block D/D2): completed_at auf datetime.now(UTC) umgestellt; UTC war bereits im Import
### ARCH-061: routes/index.tsx — Leeres Route-Objekt (Dead Code)
- **Datei:** frontend/src/routes/index.tsx:58-59
- **Problem:** Zwischen der `/login` Route und der `/dms-standalone` Route exists ein leeres Objekt `{ }` ohne `path` und ohne `element`. Dies ist Dead Code der zu Verwirrung führt.
- **Schweregrad:** Low
- **Status:** ⏳ Nicht gefixt
### ARCH-062: MessageSidebar.tsx — Dupliziert TeamPanel aus AISidebar.tsx
- **Datei:** frontend/src/components/layout/MessageSidebar.tsx:38-89
- **Problem:** `TeamPanel` ist identisch in AISidebar.tsx und MessageSidebar.tsx implementiert (Code-Duplikation). Sollte ein gemeinsames Component sein (z.B. `components/shared/TeamPanel.tsx`).
- **Schweregrad:** Medium
- **Status:** ⏳ Nicht gefixt
### ARCH-063: SortableMenuItem.tsx — import * as LucideIcons lädt ALL icons
- **Datei:** frontend/src/components/layout/SortableMenuItem.tsx:4
- **Problem:** `import * as LucideIcons from 'lucide-react'` lädt alle Icons was OOM in Tests verursacht. Sidebar.tsx nutzt korrekt ein kuratiertes ICON_MAP. SortableMenuItem sollte dasselbe Pattern nutzen.
- **Schweregrad:** Medium
- **Status:** ⏳ Nicht gefixt