3875 lines
188 KiB
Markdown
3875 lines
188 KiB
Markdown
# 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:** ⏳ 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:** `<Navigate to="/kein-zugriff" replace />` — 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<string> nicht serialisierbar
|
|
- **Datei:** frontend/src/store/calendarStore.ts
|
|
- **Problem:** `visibleCalendarIds: Set<string>` — 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
|
|
|
|
### ARCH-156: CustomFieldRenderer.tsx — Duplikat in zwei Ordnern
|
|
- **Datei:** frontend/src/components/contacts/CustomFieldRenderer.tsx, frontend/src/components/custom-fields/CustomFieldRenderer.tsx
|
|
- **Problem:** CustomFieldRenderer existiert in beiden Ordnern. Duplikat.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-157: components/knowledge/ — leerer Ordner
|
|
- **Datei:** frontend/src/components/knowledge/
|
|
- **Problem:** Ordner existiert aber enthält 0 Dateien. Entweder tot oder unvollständig.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-158: components/contact/ — leerer Ordner
|
|
- **Datei:** frontend/src/components/contact/
|
|
- **Problem:** Ordner existiert aber enthält 0 Dateien. Entweder tot oder unvollständig.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-159: components/agents/AgentChat.tsx — AI Chat wurde in Kommunikation integriert
|
|
- **Datei:** frontend/src/components/agents/AgentChat.tsx
|
|
- **Problem:** AI Chat wurde in Phase 2 in Kommunikation integriert. AgentChat.tsx ist möglicherweise ungenutzt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-160: ContactList.tsx — hardcoded ALL_COLUMNS (TODO P2-F18)
|
|
- **Datei:** frontend/src/components/contacts/ContactList.tsx:2
|
|
- **Problem:** TODO: 'Replace hardcoded ALL_COLUMNS with backend/manifest config'. Hardcoded Column-Definitions.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-161: MailList.tsx — inline style (TODO P3-F6)
|
|
- **Datei:** frontend/src/components/mail/MailList.tsx:2
|
|
- **Problem:** TODO: 'Replace inline style with Tailwind classes'. Inline styles statt Tailwind.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-162: NotificationBell.tsx — TODO Migrate to communication API
|
|
- **Datei:** frontend/src/components/layout/NotificationBell.tsx:2
|
|
- **Problem:** TODO: 'Migrate from /notifications to communication API'. Verwendet noch deprecated /notifications API.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-163: DashboardWidgetLoader.tsx — hardcoded widgetRegistry (TODO P2-F17)
|
|
- **Datei:** frontend/src/components/dashboard/DashboardWidgetLoader.tsx:2
|
|
- **Problem:** TODO: 'Replace hardcoded widgetRegistry with dynamic manifest config'. Hardcoded Widget-Registry.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-164: AISidebar.tsx — importiert createSession, fetchSessions (Phase 2 entfernt)
|
|
- **Datei:** frontend/src/components/layout/AISidebar.tsx:6
|
|
- **Problem:** `import { createSession, fetchSessions } from '@/api/ai'` — AI Sessions wurden in Phase 2 entfernt. Funktionen existieren möglicherweise nicht mehr.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-165: WorkspaceSwitcher.tsx — hardcoded Tailwind dark: classes
|
|
- **Datei:** frontend/src/components/layout/WorkspaceSwitcher.tsx:35
|
|
- **Problem:** `dark:bg-gray-900`, `dark:text-gray-300` — hardcoded Tailwind dark: classes statt design tokens (secondary-*, primary-*).
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-166: BlockRenderer.tsx — hardcoded switch-case für Block-Typen
|
|
- **Datei:** frontend/src/components/comm/blocks/BlockRenderer.tsx:30
|
|
- **Problem:** Hardcoded switch-case für Block-Typen. Neue Block-Typen können nicht dynamisch hinzugefügt werden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-167: AiChatPanel.tsx — kein API cancel bei unmount
|
|
- **Datei:** frontend/src/components/window/AiChatPanel.tsx:50
|
|
- **Problem:** Erstellt comm conversation bei mount, aber bei unmount wird nur `cancelled = true` gesetzt. Die Konversation wird nicht gelöscht. Leak von leeren Konversationen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-168: ContactDetail.tsx — importiert useAIUIControlStore (Plugin-Abhängigkeit)
|
|
- **Datei:** frontend/src/components/contacts/ContactDetail.tsx:14
|
|
- **Problem:** `import { useAIUIControlStore } from '@/store/aiUIControlStore'` — ContactDetail hängt von AI UI Control Plugin ab. Core-Component hängt von Plugin ab.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-169: CalendarTree.tsx — TYPE_ORDER hardcoded
|
|
- **Datei:** frontend/src/components/calendar/CalendarTree.tsx:15
|
|
- **Problem:** `const TYPE_ORDER: CalendarType[] = ['personal', 'team', 'project', 'company']` — hardcoded. Nicht dynamisch erweiterbar.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-170: DashboardGrid.tsx — drag-and-drop speichert nicht in Backend
|
|
- **Datei:** frontend/src/components/dashboard/DashboardGrid.tsx:35
|
|
- **Problem:** Drag-and-drop ändert nur local state (`setWidgets`). Widget-Position wird nicht in Backend gespeichert. Bei Reload geht die Anordnung verloren.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-171: schemas/common.py — Deprecated Notification Schemas noch aktiv
|
|
- **Datei:** app/schemas/common.py:15-40
|
|
- **Problem:** Deprecated Notification Schemas (NotificationResponse, NotificationListResponse, etc.) noch aktiv. Doppelarchitektur mit kommunikation.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-172: schemas/webhook.py — WebhookResponse gibt secret zurück
|
|
- **Datei:** app/schemas/webhook.py:40
|
|
- **Problem:** WebhookResponse gibt secret zurück. HMAC Secret sollte nicht in API Response stehen.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-173: automation/schemas.py — llm_model default hardcoded
|
|
- **Datei:** app/plugins/builtins/automation/schemas.py:18
|
|
- **Problem:** `llm_model: str = Field(default="ollama/deepseek-v4-flash")` — hardcoded Model-Name. Sollte aus Settings kommen.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-174: ai_assistant/schemas.py — api_key als Plaintext String
|
|
- **Datei:** app/plugins/builtins/ai_assistant/schemas.py:18
|
|
- **Problem:** `api_key: str = Field(default="", max_length=2000)` — API-Key als Plaintext im Schema. Sollte verschlüsselt gespeichert werden.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-175: wiki/schemas.py — ArticleCreate erfordert slug
|
|
- **Datei:** app/plugins/builtins/wiki/schemas.py:22
|
|
- **Problem:** `slug: str = Field(..., min_length=1, max_length=300)` — slug ist Pflichtfeld. Sollte auto-generiert werden aus title.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-176: permissions/schemas.py — ShareLinkResponse gibt token zurück
|
|
- **Datei:** app/plugins/builtins/permissions/schemas.py:35
|
|
- **Problem:** ShareLinkResponse gibt token zurück. Share-Token sollte nicht in API Response stehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-177: mail/schemas.py — MailAccountCreate password als Plaintext
|
|
- **Datei:** app/plugins/builtins/mail/schemas.py:25
|
|
- **Problem:** `password: str = Field(..., min_length=1, max_length=512)` — Mail-Account Password als Plaintext im Schema. Wird zwar verschlüsselt gespeichert aber im Request unverschlüsselt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-178: schemas/custom_field_definition.py — entity ohne Validierung
|
|
- **Datei:** app/schemas/custom_field_definition.py:15
|
|
- **Problem:** `entity: str = Field(...)` — keine Validierung gegen ENTITY_MODELS. Jeder String wird akzeptiert.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-179: schemas/entity_permission.py — principal_type pattern hardcoded
|
|
- **Datei:** app/schemas/entity_permission.py:12
|
|
- **Problem:** `principal_type: str = Field(..., pattern="^(user|group|role|guest)$")` — hardcoded. Neue Principal-Types können nicht dynamisch hinzugefügt werden.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-180: Systematisches Problem — Schemas mit hardcoded Regex Patterns
|
|
- **Dateien:** tasks/schemas.py, calendar/schemas.py, report_generator/schemas.py, etc.
|
|
- **Problem:** Viele Schemas haben hardcoded Regex Patterns für Enums (status, type, etc.). Diese sollten mit den Model-Defaults synchronisiert sein, sind aber dupliziert.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-181: Systematisches Problem — entity_type/entity ohne ENTITY_MODELS Validierung
|
|
- **Dateien:** entity_links/schemas.py, tags/schemas.py, custom_field_definition.py, graph_rag/schemas.py
|
|
- **Problem:** entity_type und entity Felder in Schemas haben keine Validierung gegen ENTITY_MODELS. Jeder String wird akzeptiert.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-182: Systematisches Problem — API Secrets in Responses
|
|
- **Dateien:** schemas/webhook.py, permissions/schemas.py, mcp_client/routes.py, api/webhooks.ts
|
|
- **Problem:** Webhook.secret, ShareLink.token, McpServerConfig.api_token werden in API Responses an Frontend gesendet. Secrets sollten nie in Responses stehen.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-183: routes/api_tokens.py — falsche Permission (mcp:write)
|
|
- **Datei:** app/routes/api_tokens.py:33
|
|
- **Problem:** `require_permission("mcp:write")` für API Tokens — sollte `api_tokens:write` oder ähnlich sein. Falsche Permission.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-184: routes/backups.py — falsche Permission (automation:admin)
|
|
- **Datei:** app/routes/backups.py:18
|
|
- **Problem:** `require_permission("automation:admin")` für Backups — sollte `backups:admin` oder ähnlich sein. Falsche Permission.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-185: routes/custom_fields.py — Core→Plugin Import
|
|
- **Datei:** app/routes/custom_fields.py:15
|
|
- **Problem:** `from app.plugins.registry import get_registry` — Core importiert von Plugin Registry.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-186: routes/webhooks.py — falsche Permission (workflows:read)
|
|
- **Datei:** app/routes/webhooks.py:22
|
|
- **Problem:** `require_permission("workflows:read")` für Webhooks — sollte `webhooks:read` oder ähnlich sein. Falsche Permission.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-187: routes/entity_permissions.py — list_entity_permissions ohne require_permission
|
|
- **Datei:** app/routes/entity_permissions.py:26
|
|
- **Problem:** `list_entity_permissions` hat nur `get_current_user`, kein `require_permission`. Jeder eingeloggte User kann alle Permissions sehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-188: routes/saved_filters.py und saved_views.py — _validate_entity_type dupliziert (3. und 4. Kopie)
|
|
- **Datei:** app/routes/saved_filters.py:20, app/routes/saved_views.py:20
|
|
- **Problem:** _validate_entity_type Funktion ist jetzt in 4 Dateien identisch (tags, entity_links, saved_filters, saved_views). Sollte zentralisiert werden.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-189: routes/groups.py — redundant import uuid as _uuid
|
|
- **Datei:** app/routes/groups.py:27
|
|
- **Problem:** `import uuid as _uuid` inside list_groups Funktion — uuid ist bereits am Datei-Anfang importiert. Redundant.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-190: Systematisches Problem — falsche Permissions in mehreren Routes
|
|
- **Dateien:** api_tokens.py (mcp:write), backups.py (automation:admin), webhooks.py (workflows:read), custom_field_definitions.py (contacts:read), knowledge/routes.py (wiki:read), self_improvement/routes.py (automation:read)
|
|
- **Problem:** Mehrere Routes verwenden falsche Permissions die nicht zu ihrem Modul passen. Permission-Namen sind inkonsistent und zugeordnet zu falschen Modulen.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-191: models/compliance.py — ComplianceIncident ohne OwnedMixin
|
|
- **Datei:** app/models/compliance.py:18
|
|
- **Problem:** ComplianceIncident hat kein OwnedMixin. Kein owner_id, keine Visibility-Filterung. Jeder User kann alle Incidents sehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-192: models/outbox.py — EventOutbox hat tenant_id aber kein TenantMixin
|
|
- **Datei:** app/models/outbox.py:20
|
|
- **Problem:** EventOutbox hat `tenant_id: Mapped[uuid.UUID]` aber erbt nicht von TenantMixin. Inkonsistent mit anderen Models.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-193: models/entity_policy.py — ABAC EntityPolicy nicht aktiv genutzt (toter Code)
|
|
- **Datei:** app/models/entity_policy.py:7
|
|
- **Problem:** Kommentar: 'ABAC EntityPolicy ist implementiert aber wird nicht aktiv genutzt'. Toter Code der verwirrt.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-194: models/address.py — bekannte Inkonsistenz (inline vs Tabelle)
|
|
- **Datei:** app/models/address.py:5
|
|
- **Problem:** Kommentar: 'Address-Tabelle wird für Bank-Accounts genutzt. Contacts nutzen inline Address-Felder. Diese Inkonsistenz ist bekannt'. Bekanntes Architektur-Problem.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-195: models/bank_account.py — IBAN als Plaintext
|
|
- **Datei:** app/models/bank_account.py:25
|
|
- **Problem:** `iban: Mapped[str] = mapped_column(String(34), nullable=False)` — IBAN als Plaintext in DB. Sollte verschlüsselt sein.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-196: models/system_settings.py — Sensitive Daten als Plaintext
|
|
- **Datei:** app/models/system_settings.py:35-37
|
|
- **Problem:** tax_number, iban, bic als Plaintext in DB. Sensitive Finanzdaten unverschlüsselt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-197: models/tenant.py — resolution_strategy hardcoded
|
|
- **Datei:** app/models/tenant.py:25
|
|
- **Problem:** `CheckConstraint("resolution_strategy IN ('highest_wins')")` — hardcoded. Nur eine Strategie erlaubt.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-198: models/workflow.py — steps als JSONB ohne Validierung
|
|
- **Datei:** app/models/workflow.py:30
|
|
- **Problem:** `steps: Mapped[list[dict[str, Any]]] = mapped_column(JSONB, nullable=False)` — keine Validierung der Step-Struktur. Jedes JSON wird akzeptiert.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-199: models/contact_merge.py — inkonsistente ondelete policies
|
|
- **Datei:** app/models/contact_merge.py:25-28
|
|
- **Problem:** source_contact_id hat ondelete='SET NULL', target_contact_id hat ondelete='CASCADE'. Inkonsistent — wenn Target gelöscht wird, wird Merge-History gelöscht. Wenn Source gelöscht wird, bleibt History mit NULL.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-200: Systematisches Problem — Sensitive Daten als Plaintext in DB
|
|
- **Dateien:** models/bank_account.py (iban), models/system_settings.py (tax_number, iban, bic), ai_assistant/models.py (api_key), mail/models.py (encrypted_password — OK), models/webhook.py (secret)
|
|
- **Problem:** Mehrere Models speichern sensitive Daten als Plaintext. Nur mail/models.py verschlüsselt passwords. Andere sensitive Felder (IBAN, API-Keys, Webhook-Secrets, Tax-Numbers) sind unverschlüsselt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-201: .env.example und .env.docker.example — ADMIN_PASSWORD hardcoded
|
|
- **Datei:** .env.example:79, .env.docker.example:55, docker-compose.yaml:55
|
|
- **Problem:** `ADMIN_PASSWORD=Admin123!` — hardcoded Default-Admin-Password in allen Config-Dateien. Security Risk.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-202: tsconfig.json — noUnusedLocals/noUnusedParameters false
|
|
- **Datei:** frontend/tsconfig.json:16-17
|
|
- **Problem:** `noUnusedLocals: false` und `noUnusedParameters: false` — TypeScript strict mode ist nicht vollständig aktiviert. Unbenutzte Variablen werden nicht erkannt.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-203: prestart.sh — f-string SQL injection risk
|
|
- **Datei:** prestart.sh:42
|
|
- **Problem:** `ALTER ROLE {role} WITH LOGIN PASSWORD '{pwd}'` — pwd wird direkt in SQL eingefügt. Wenn pwd Sonderzeichen enthält (z.B. '), kann SQL injection auftreten.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-204: vite.config.ts — PWA Reste (manifest.json ohne PWA plugin)
|
|
- **Datei:** frontend/public/manifest.json, frontend/vite.config.ts
|
|
- **Problem:** public/manifest.json existiert aber vite-plugin-pwa ist nicht in vite.config.ts importiert. PWA-Reste die verwirren.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-205: pyproject.toml — mypy disallow_untyped_defs = false
|
|
- **Datei:** pyproject.toml:55
|
|
- **Problem:** `disallow_untyped_defs = false` — mypy strict mode ist nicht vollständig aktiviert. Ungetypte Funktionen werden akzeptiert.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-206: alembic/env.py — wildcard import `from app.models import *`
|
|
- **Datei:** alembic/env.py:14
|
|
- **Problem:** `from app.models import *` — wildcard import. Unklar welche Models importiert werden. Kann zu fehlenden Migrationen führen wenn neue Models nicht in __init__.py stehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-207: requirements.txt — passlib[bcrypt]==1.7.4 gepinnt
|
|
- **Datei:** requirements.txt:14
|
|
- **Problem:** `passlib[bcrypt]==1.7.4` — exact version pinned. passlib 1.7.4 ist veraltet, neuere Versionen haben Bugfixes.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-208: tailwind.config.js — Hardcoded color values
|
|
- **Datei:** frontend/tailwind.config.js:10-80
|
|
- **Problem:** Alle Farben sind hardcoded (primary: #2563eb, etc.). themeStore.ts hat DEFAULT_THEME mit denselben Werten — zwei Quellen für dieselben Farben. Sollte CSS variables verwenden.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-209: tsconfig.json — target ES2020 statt ES2022+
|
|
- **Datei:** frontend/tsconfig.json:4
|
|
- **Problem:** `target: ES2020` — moderne JavaScript Features (top-level await, class fields, etc.) werden nicht genutzt. Sollte ES2022+ sein.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-210: docker-compose.yaml — DB_PASSWORD als einzelnes Password für alle Roles
|
|
- **Datei:** docker-compose.yaml:38-40
|
|
- **Problem:** `DB_PASSWORD` wird für alle DB-Roles (crm_api, crm_auth, crm_worker, crm_user) verwendet. Jede Role sollte ein eigenes Password haben für Security-Isolation.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-211: permission_audit.py — hardcoded deutsche Strings in Notifications
|
|
- **Datei:** app/services/permission_audit.py:30-32
|
|
- **Problem:** 'Neue Berechtigung', '{perm.entity_type} wurde mit dir geteilt' — hardcoded deutsche Strings in create_notification().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-212: owner_transfer_service.py — ENTITY_TABLES statisch
|
|
- **Datei:** app/services/owner_transfer_service.py:16-26
|
|
- **Problem:** ENTITY_TABLES ist statisch. Neue Plugin-Tabellen werden nicht erfasst. Owner Transfer funktioniert nur für Core-Tabellen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-213: policy_service.py — ABAC_ALLOWED_FIELDS statisch
|
|
- **Datei:** app/services/policy_service.py:33-36
|
|
- **Problem:** ABAC_ALLOWED_FIELDS ist statisch. Neue Plugin-Entities können keine ABAC Policies verwenden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-214: workspaceStore.ts — visibleModuleKeys() gibt ALLE Module zurück (bestätigt ARCH-004)
|
|
- **Datei:** frontend/src/store/workspaceStore.ts:88-91
|
|
- **Problem:** `visibleModuleKeys: () => new Set(ctx?.modules?.map(m => m.module_key) || [])` — gibt alle Module zurück, nicht nur sichtbare. is_visible wird nicht gefiltert.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-215: useAIContext.ts — POST ohne Error-Handling
|
|
- **Datei:** frontend/src/hooks/useAIContext.ts:14
|
|
- **Problem:** `apiClient.post('/ai-proactive/context', {...}).catch(() => {})` — Fehler werden still verschluckt. Kein Logging, kein Error-Handling.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-216: contact_folder_permission_service.py — _rank() dupliziert (5. Kopie)
|
|
- **Datei:** app/services/contact_folder_permission_service.py:22
|
|
- **Problem:** _rank() Funktion ist jetzt in 5 Dateien definiert (visibility.py, permission_resolver.py, bulk_permission_service.py, contact_folder_permission_service.py, und in permissions.py als PERM_RANK). Sollte zentralisiert werden.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-217: auth.py — Dead Code: Response Objekt wird erstellt aber nie verwendet
|
|
- **Datei:** app/routes/auth.py:52-53
|
|
- **Problem:** `response = Response(status_code=status.HTTP_200_OK)` wird erstellt und `response.set_cookie(...)` aufgerufen, aber dann wird ein neues `JSONResponse` Objekt erstellt (Zeile 57). Das erste Response-Objekt ist Dead Code.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-218: auth.py — logout hat ungenutzten db Parameter
|
|
- **Datei:** app/routes/auth.py:74
|
|
- **Problem:** `db: AsyncSession = Depends(get_auth_db)` wird injiziert aber nie verwendet. Nur redis wird für logout genutzt. Verschwendet DB-Connection.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-219: auth.py — me_permissions verwendet zwei verschiedene DB-Sessions
|
|
- **Datei:** app/routes/auth.py:150
|
|
- **Problem:** `db: AsyncSession = Depends(get_auth_db)` UND `current_user: dict = Depends(get_current_user)` — get_current_user verwendet get_db (crm_api role), get_auth_db verwendet crm_auth role. Zwei verschiedene DB-Sessions in einem Request.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-220: users.py — user.created direkt published statt über Outbox
|
|
- **Datei:** app/routes/users.py:140
|
|
- **Problem:** `event_bus.publish('user.created', ...)` direkt statt über `enqueue_outbox_event()`. outbox.py sagt 'domain events must go through outbox for durability'. user.created ist nicht durable — geht verloren bei Crash.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-221: users.py — update_menu_order Double-Commit
|
|
- **Datei:** app/routes/users.py:350
|
|
- **Problem:** `await db.commit()` im Route-Handler, aber `get_db()` committet bereits bei Erfolg (Zeile 248 in db/__init__.py). Double-Commit kann zu Fehlern führen.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-222: users.py — delete_user verwendet users:write statt users:delete
|
|
- **Datei:** app/routes/users.py:260
|
|
- **Problem:** `require_permission('users:write')` für DELETE, aber CORE_PERMISSIONS hat `users:delete`. Falsche Permission — User mit write aber ohne delete können User löschen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-223: contacts.py — pydantic Import in der Mitte der Datei
|
|
- **Datei:** app/routes/contacts.py:25
|
|
- **Problem:** `from pydantic import BaseModel, Field` wird in der Mitte der Datei importiert (nach dem Router-Import), nicht am Anfang. Anti-Pattern — alle Imports sollten am Datei-Anfang stehen.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-224: companies.py — create_company ohne Pydantic Schema
|
|
- **Datei:** app/routes/companies.py:85
|
|
- **Problem:** `body: dict[str, Any]` statt Pydantic Schema. Keine Validierung — beliebige Felder werden akzeptiert.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-225: companies.py — export_companies ohne visibility filter
|
|
- **Datei:** app/routes/companies.py:200
|
|
- **Problem:** Exportiert alle Companies ohne `apply_visibility_filter()`. Jeder User mit contacts:read kann ALLE Companies exportieren, auch solche die er nicht sehen dürfte.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-226: companies.py — update_company ohne Pydantic Schema
|
|
- **Datei:** app/routes/companies.py:260
|
|
- **Problem:** `body: dict[str, Any]` — keine Validierung. Gleicher Fehler wie ARCH-224.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-227: companies.py — get_company_emails returns empty list (Stub)
|
|
- **Datei:** app/routes/companies.py:340
|
|
- **Problem:** `return []` — Stub/Placeholder. Endpoint existiert aber gibt immer leere Liste zurück.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-228: companies.py — created_by/updated_by Felder existieren nicht auf Contact Model
|
|
- **Datei:** app/routes/companies.py:100
|
|
- **Problem:** `Contact(created_by=user_id, updated_by=user_id)` — aber Contact Model hat `owner_id` von OwnedMixin, nicht `created_by`/`updated_by`. Diese Felder werden still ignoriert oder verursachen Fehler.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-229: companies.py — Hooks direkt published statt über Outbox
|
|
- **Datei:** app/routes/companies.py:100,115
|
|
- **Problem:** `do_action('company.before_create', ...)` und `do_action('company.after_create', ...)` — domain events direkt am Event Bus statt über Outbox. Nicht durable.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-230: roles.py — Core→Plugin Import (get_registry)
|
|
- **Datei:** app/routes/roles.py:22
|
|
- **Problem:** `from app.plugins.registry import get_registry` — Core importiert von Plugin Registry.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-231: roles.py — delete_role verwendet roles:write statt roles:delete
|
|
- **Datei:** app/routes/roles.py:230
|
|
- **Problem:** `require_permission('roles:write')` für DELETE, aber CORE_PERMISSIONS hat `roles:delete`. User mit write aber ohne delete können Rollen löschen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-232: groups.py — get_group ohne require_permission
|
|
- **Datei:** app/routes/groups.py:100
|
|
- **Problem:** `get_group` hat nur `get_current_user`, kein `require_permission`. Jeder eingeloggte User kann jede Gruppe sehen inkl. Permissions und field_permissions.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-233: groups.py — list_group_members ohne require_permission
|
|
- **Datei:** app/routes/groups.py:200
|
|
- **Problem:** `list_group_members` hat nur `get_current_user`. Jeder eingeloggte User kann alle Gruppen-Mitglieder sehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-234: groups.py — get_user_groups ohne require_permission
|
|
- **Datei:** app/routes/groups.py:240
|
|
- **Problem:** `get_user_groups` hat nur `get_current_user`. Jeder eingeloggte User kann alle Gruppen eines beliebigen Users sehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-235: workflows.py — delete_workflow verwendet workflows:write statt workflows:delete
|
|
- **Datei:** app/routes/workflows.py:200
|
|
- **Problem:** `require_permission('workflows:write')` für DELETE, aber CORE_PERMISSIONS hat `workflows:delete` nicht — nur `workflows:read` und `workflows:write`. Delete sollte separate Permission haben.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-236: workflows.py — approve_workflow_step auto-approves (sinnlos)
|
|
- **Datei:** app/routes/workflows.py:480
|
|
- **Problem:** `create_approval_request()` und sofort `resolve_approval_request(decision='approved')` — Approval wird in selben Request erstellt und approved. Approval ist bedeutungslos.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-237: workflows.py — reject_workflow_step auto-rejects (sinnlos)
|
|
- **Datei:** app/routes/workflows.py:530
|
|
- **Problem:** Gleicher Pattern wie ARCH-236 — ApprovalRequest wird erstellt und sofort rejected.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-238: workflows.py — webhook_trigger ohne Auth
|
|
- **Datei:** app/routes/workflows.py:580
|
|
- **Problem:** `webhook_trigger` hat keine Auth-Dependency. Jeder mit dem Token kann Workflows triggern. Keine Rate-Limiting, keine IP-Whitelist.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-239: workflows.py — webhook.workflow_id existiert nicht auf Webhook Model
|
|
- **Datei:** app/routes/workflows.py:595
|
|
- **Problem:** `webhook.workflow_id if hasattr(webhook, 'workflow_id') else webhook.entity_id` — Webhook Model hat kein `workflow_id` Feld. Der hasattr-Check ist ein Workaround für ein nicht existierendes Feld.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-240: workflows.py — WORKFLOW_TEMPLATES hardcoded
|
|
- **Datei:** app/routes/workflows.py:620
|
|
- **Problem:** `WORKFLOW_TEMPLATES` ist eine hardcoded Liste in der Route-Datei. Sollte in Config, DB oder Plugin-Manifest stehen.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-241: dashboard.py — Core→Plugin Import (get_registry)
|
|
- **Datei:** app/routes/dashboard.py:22
|
|
- **Problem:** `from app.plugins.registry import get_registry` — Core Route importiert direkt von Plugin Registry. Core darf nicht von Plugins abhängen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-242: dashboard.py — Company count über Contact.type statt Company Model
|
|
- **Datei:** app/routes/dashboard.py:75
|
|
- **Problem:** `Contact.type == 'company'` für Company count. Companies werden als Contacts mit type='company' behandelt, aber es gibt separate companies.py Routes. Doppelarchitektur.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-243: notifications.py — Deprecated Route existiert weiterhin (Doppelarchitektur)
|
|
- **Datei:** app/routes/notifications.py:1
|
|
- **Problem:** Route ist deprecated (delegiert an Communication), aber existiert weiterhin und wird in main.py registriert. Legacy Notifications und Communication laufen parallel.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-244: notifications.py — N+1 Query in list_notifications_endpoint
|
|
- **Datei:** app/routes/notifications.py:55
|
|
- **Problem:** `entity_permission_service.check_entity_access()` wird für jede Notification in einer Schleife aufgerufen. Bei 100 Notifications = 100 DB-Queries.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-245: compliance.py — Core→Plugin Import (AgentDefinition)
|
|
- **Datei:** app/routes/compliance.py:22
|
|
- **Problem:** `from app.plugins.builtins.automation.models import AgentDefinition` — Core Route importiert direkt von Plugin Model. Core darf nicht von Plugins abhängen.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-246: compliance.py — Doppelte Permission-Dependency
|
|
- **Datei:** app/routes/compliance.py:120
|
|
- **Problem:** `dependencies=[Depends(require_permission('system:admin'))]` UND `current_user: dict = Depends(require_permission('system:admin'))` — Permission wird zweimal geprüft. Redundant.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-247: compliance.py — _DEFAULT_RETENTION_POLICIES hardcoded
|
|
- **Datei:** app/routes/compliance.py:380
|
|
- **Problem:** Retention Policies sind hardcoded in der Route-Datei. Sollte in Config, DB oder Plugin-Manifest stehen.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-248: system_settings.py — dsgvo_export NameError (datetime/timezone nicht importiert)
|
|
- **Datei:** app/routes/system_settings.py:200
|
|
- **Problem:** `datetime.now(timezone.utc)` wird verwendet, aber `datetime` und `timezone` sind nicht importiert. Weder am Datei-Anfang noch in der Funktion. Das wird einen NameError geben beim Aufruf.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-249: system_settings.py — update_backup_config ohne Pydantic Schema
|
|
- **Datei:** app/routes/system_settings.py:160
|
|
- **Problem:** `body: dict` statt Pydantic Schema. Keine Validierung von backup_enabled, backup_interval, backup_retention_days, backup_destination.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-250: system_dashboard.py — Core→Plugin Import (get_registry)
|
|
- **Datei:** app/routes/system_dashboard.py:22
|
|
- **Problem:** `from app.plugins.registry import get_registry` — Core Route importiert direkt von Plugin Registry.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-251: system_dashboard.py — Sync I/O in async Context
|
|
- **Datei:** app/routes/system_dashboard.py:200
|
|
- **Problem:** `os.path.exists()`, `os.walk()`, `shutil.disk_usage()` in async Funktion `_get_storage_stats()` — sync I/O blockiert Event Loop.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-252: system_dashboard.py — _send_alert_notifications verschluckt Fehler
|
|
- **Datei:** app/routes/system_dashboard.py:260
|
|
- **Problem:** `except Exception: pass` — Fehler beim Senden von Alert-Notifications werden still ignoriert.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-253: audit.py — audit_retention_cleanup verwendet audit:read statt audit:delete
|
|
- **Datei:** app/routes/audit.py:160
|
|
- **Problem:** `require_permission('audit:read')` für DELETE-Endpoint. Jeder mit Leserecht kann Audit-Logs löschen. Sollte `audit:delete` oder `system:admin` sein.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-254: audit.py — datetime.utcnow() deprecated
|
|
- **Datei:** app/routes/audit.py:165
|
|
- **Problem:** `datetime.utcnow()` ist deprecated in Python 3.12+. Sollte `datetime.now(UTC)` sein.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-255: entity_permissions.py — _check_entity_ownership importiert statische ENTITY_MODELS
|
|
- **Datei:** app/routes/entity_permissions.py:100
|
|
- **Problem:** `from app.services.entity_permission_service import ENTITY_MODELS` — statische Liste, neue Plugin-Entities nicht erfasst.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-256: entity_permissions.py — list_entity_registry hardcoded Entity-Liste
|
|
- **Datei:** app/routes/entity_permissions.py:250
|
|
- **Problem:** Statische Liste mit 12 Entity-Typen und deutschen Labels. Neue Plugin-Entities werden nicht erfasst.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-257: entity_permissions.py — bulk_share_permissions ohne Pydantic Schema
|
|
- **Datei:** app/routes/entity_permissions.py:280
|
|
- **Problem:** `body: dict` statt Pydantic Schema. Keine Validierung von entity_type, entity_ids, principal_type, principal_id, level.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-258: entity_permissions.py — bulk_unshare_permissions ohne Pydantic Schema
|
|
- **Datei:** app/routes/entity_permissions.py:300
|
|
- **Problem:** `body: dict` statt Pydantic Schema. Keine Validierung.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-259: entity_permissions.py — Hardcoded deutsche Fehlermeldung
|
|
- **Datei:** app/routes/entity_permissions.py:60
|
|
- **Problem:** `"Sie benötigen Admin-Rechte auf diesen Datensatz, um Berechtigungen zu verwalten"` — hardcoded deutsch ohne i18n.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-260: custom_field_definitions.py — Custom Fields an contacts:read gekoppelt
|
|
- **Datei:** app/routes/custom_field_definitions.py:25
|
|
- **Problem:** `require_permission('contacts:read')` für generische Custom Field Definitions. Custom Fields sind nicht Contacts-spezifisch.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-261: custom_field_definitions.py — Custom Fields Create an contacts:write gekoppelt
|
|
- **Datei:** app/routes/custom_field_definitions.py:45
|
|
- **Problem:** `require_permission('contacts:write')` für Create. Sollte generisch sein (z.B. `custom_fields:write`).
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-262: custom_fields.py — Core→Plugin Import (get_registry)
|
|
- **Datei:** app/routes/custom_fields.py:15
|
|
- **Problem:** `from app.plugins.registry import get_registry` — Core Route importiert direkt von Plugin Registry.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-263: custom_fields.py — Route prefix an Contacts gekoppelt
|
|
- **Datei:** app/routes/custom_fields.py:20
|
|
- **Problem:** `prefix="/api/v1/contacts"` — Custom Fields sind generisch aber Route ist an Contacts gekoppelt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-264: custom_fields.py — _collect_custom_field_definitions iteriert über Plugin Manifeste
|
|
- **Datei:** app/routes/custom_fields.py:100
|
|
- **Problem:** Core Route iteriert über alle Plugin-Manifeste um Custom Fields zu sammeln. Core sollte nicht wissen dass Plugins Custom Fields haben.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-265: webhooks.py — Inkonsistente Permissions (workflows:read vs automation:read)
|
|
- **Datei:** app/routes/webhooks.py:25 vs :80
|
|
- **Problem:** list_webhooks verwendet `workflows:read`, get_webhook verwendet `automation:read`. Inkonsistente Permissions für dasselbe Modul.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-266: webhooks.py — Inkonsistente Permissions (workflows:write vs automation:write)
|
|
- **Datei:** app/routes/webhooks.py:45 vs :120 vs :160
|
|
- **Problem:** create_webhook verwendet `workflows:write`, update/delete/test verwenden `automation:write`. Inkonsistent.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-267: saved_views.py — create_saved_view an contacts:read gekoppelt
|
|
- **Datei:** app/routes/saved_views.py:100
|
|
- **Problem:** `require_permission('contacts:read')` für generische Saved Views. Saved Views sind nicht Contacts-spezifisch.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-268: saved_views.py — update_saved_view verwendet contacts:read statt contacts:write
|
|
- **Datei:** app/routes/saved_views.py:140
|
|
- **Problem:** Update verwendet `contacts:read` statt `contacts:write`. Update sollte Write-Recht erfordern.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-269: saved_views.py — delete_saved_view verwendet contacts:read statt contacts:delete
|
|
- **Datei:** app/routes/saved_views.py:170
|
|
- **Problem:** Delete verwendet `contacts:read` statt `contacts:delete`. Delete sollte Delete-Recht erfordern.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-270: saved_views.py — _validate_entity_type importiert statische ENTITY_MODELS
|
|
- **Datei:** app/routes/saved_views.py:30
|
|
- **Problem:** `from app.services.entity_permission_service import ENTITY_MODELS` — statische Liste, neue Plugin-Entities nicht erfasst.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-271: saved_filters.py — create_saved_filter an contacts:read gekoppelt
|
|
- **Datei:** app/routes/saved_filters.py:80
|
|
- **Problem:** `require_permission('contacts:read')` für generische Saved Filters.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-272: saved_filters.py — delete_saved_filter verwendet contacts:read statt contacts:delete
|
|
- **Datei:** app/routes/saved_filters.py:120
|
|
- **Problem:** Delete verwendet `contacts:read` statt `contacts:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-273: saved_filters.py — _validate_entity_type importiert statische ENTITY_MODELS
|
|
- **Datei:** app/routes/saved_filters.py:30
|
|
- **Problem:** Gleicher Fehler wie saved_views.py — statische ENTITY_MODELS.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-274: import_export.py — export_data ohne visibility filter
|
|
- **Datei:** app/routes/import_export.py:280
|
|
- **Problem:** export_data exportiert alle Contacts/Companies ohne Ownership-Check. user_id und is_system_admin werden übergeben, aber der Service könnte sie nicht filtern.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-275: import_export.py — ineffiziente CSV→XLSX Konvertierung
|
|
- **Datei:** app/routes/import_export.py:300
|
|
- **Problem:** export_data parst CSV-Daten zurück zu Rows um sie in XLSX umzuwandeln. Ineffizient — sollte direkt XLSX generieren statt CSV→parse→XLSX.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-276: attachments.py — download_attachment liest gesamte Datei in Memory
|
|
- **Datei:** app/routes/attachments.py:100
|
|
- **Problem:** `file_bytes = await storage.read(storage_path)` liest gesamte Datei in Memory. Bei großen Dateien (100MB) kann das OOM verursachen. Sollte StreamingResponse verwenden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-277: addresses.py — _validate_entity_type importiert statische ENTITY_MODELS
|
|
- **Datei:** app/routes/addresses.py:20
|
|
- **Problem:** Gleicher Fehler wie saved_views/saved_filters — statische ENTITY_MODELS.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-278: bank_accounts.py — delete verwendet bank-accounts:write statt bank-accounts:delete
|
|
- **Datei:** app/routes/bank_accounts.py:90
|
|
- **Problem:** Delete verwendet `bank-accounts:write` statt `bank-accounts:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-279: bank_accounts.py — IBAN/BIC als Plaintext in DB
|
|
- **Datei:** app/routes/bank_accounts.py (implizit über BankAccount Model)
|
|
- **Problem:** BankAccount Model speichert IBAN und BIC als Plaintext. Sensitive Daten sollten verschlüsselt werden.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-280: currencies.py — delete verwendet currencies:write statt currencies:delete
|
|
- **Datei:** app/routes/currencies.py:70
|
|
- **Problem:** Delete verwendet `currencies:write` statt `currencies:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-281: taxes.py — delete verwendet taxes:write statt taxes:delete
|
|
- **Datei:** app/routes/taxes.py:70
|
|
- **Problem:** Delete verwendet `taxes:write` statt `taxes:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-282: sequences.py — delete verwendet sequences:write statt sequences:delete
|
|
- **Datei:** app/routes/sequences.py:85
|
|
- **Problem:** Delete verwendet `sequences:write` statt `sequences:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-283: Systematischer Fehler — Alle Core-Routes verwenden :write für DELETE statt :delete
|
|
- **Datei:** app/routes/ (currencies, taxes, sequences, bank_accounts, workflows, roles, users)
|
|
- **Problem:** Systematischer Architektur-Fehler — alle Core-Routes verwenden `:write` Permission für DELETE-Operationen statt `:delete`. Betroffen: currencies, taxes, sequences, bank_accounts, workflows, roles, users.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-284: delegations.py — delete verwendet permissions:delegations:write statt :delete
|
|
- **Datei:** app/routes/delegations.py:80
|
|
- **Problem:** Delete verwendet `permissions:delegations:write` statt `permissions:delegations:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-285: policies.py — delete verwendet permissions:policies:write statt :delete
|
|
- **Datei:** app/routes/policies.py:80
|
|
- **Problem:** Delete verwendet `permissions:policies:write` statt `permissions:policies:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-286: owner_transfer.py — Kein Audit-Log für Ownership-Transfer
|
|
- **Datei:** app/routes/owner_transfer.py:35
|
|
- **Problem:** transfer_ownership hat kein Audit-Log. Ownership-Transfer ist eine kritische Operation die auditiert werden muss.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-287: api_tokens.py — create_token verwendet mcp:write statt api_tokens:write
|
|
- **Datei:** app/routes/api_tokens.py:30
|
|
- **Problem:** `require_permission('mcp:write')` für API Token Creation. API Tokens sind nicht MCP-spezifisch.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-288: api_tokens.py — list_tokens verwendet mcp:read statt api_tokens:read
|
|
- **Datei:** app/routes/api_tokens.py:60
|
|
- **Problem:** `require_permission('mcp:read')` für API Token List. Sollte `api_tokens:read` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-289: api_tokens.py — revoke_token verwendet mcp:write statt api_tokens:delete
|
|
- **Datei:** app/routes/api_tokens.py:65
|
|
- **Problem:** `require_permission('mcp:write')` für Token Revoke. Sollte `api_tokens:delete` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-290: approvals.py — __import__('sqlalchemy').func.count() in Query
|
|
- **Datei:** app/routes/approvals.py:120
|
|
- **Problem:** `__import__('sqlalchemy').func.count()` — dynamischer Import in Query-Construction. Sollte `from sqlalchemy import func` am Datei-Anfang stehen.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-291: backups.py — create_backup ohne Audit-Log
|
|
- **Datei:** app/routes/backups.py:60
|
|
- **Problem:** create_backup hat kein Audit-Log. Backup-Erstellung sollte auditiert werden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-292: backups.py — restore_backup ohne Audit-Log
|
|
- **Datei:** app/routes/backups.py:80
|
|
- **Problem:** restore_backup hat kein Audit-Log. Restore ist eine kritische destruktive Operation die auditiert werden muss.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-293: contact_folder_permissions.py — delete verwendet contacts:write statt contacts:delete
|
|
- **Datei:** app/routes/contact_folder_permissions.py:80
|
|
- **Problem:** Delete verwendet `contacts:write` statt `contacts:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-294: contact_folders.py — delete_folder verwendet contacts:write statt contacts:delete
|
|
- **Datei:** app/routes/contact_folders.py:75
|
|
- **Problem:** Delete verwendet `contacts:write` statt `contacts:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-295: contact_folders.py — reorder_folders ohne Pydantic Schema
|
|
- **Datei:** app/routes/contact_folders.py:90
|
|
- **Problem:** `body: list[dict]` statt Pydantic Schema. Keine Validierung.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-296: entity_history.py — restore_from_history manuelle Permission-Prüfung
|
|
- **Datei:** app/routes/entity_history.py:100
|
|
- **Problem:** Permission wird manuell geprüft statt `require_permission` Dependency. Inkonsistent mit anderen Routes.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-297: entity_history.py — undo_last_action manuelle Permission-Prüfung
|
|
- **Datei:** app/routes/entity_history.py:150
|
|
- **Problem:** Gleiche manuelle Permission-Prüfung wie restore_from_history.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-298: entity_history.py — list_trash ohne require_permission
|
|
- **Datei:** app/routes/entity_history.py:200
|
|
- **Problem:** `get_current_user` ohne `require_permission` — jeder eingeloggte User kann Trash sehen ohne spezifische Permission.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-299: errors.py — error.userAgent statt error.user_agent
|
|
- **Datei:** app/routes/errors.py:120
|
|
- **Problem:** `error.userAgent` wird verwendet aber Pydantic Model hat `user_agent` (snake_case). AttributeError möglich.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-300: errors.py — Core→Plugin Import (get_contract)
|
|
- **Datei:** app/routes/errors.py:130
|
|
- **Problem:** `from app.plugins.builtins.contracts import get_contract` — Core Route importiert direkt von Plugin Contracts.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-301: guests.py — invite_guest ohne Pydantic Schema
|
|
- **Datei:** app/routes/guests.py:50
|
|
- **Problem:** `body: dict` statt Pydantic Schema. Keine Validierung von email und name.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-302: guests.py — inkonsistente Transaction-Handling
|
|
- **Datei:** app/routes/guests.py:100
|
|
- **Problem:** `db.commit()` und `db.refresh()` in einem Branch (neuer User) aber nicht im anderen (existing User). Inkonsistent.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-303: guests.py — delete_guest verschluckt Fehler
|
|
- **Datei:** app/routes/guests.py:170
|
|
- **Problem:** `except Exception: pass` beim Session-Invalidate. Fehler werden ignoriert.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-304: guests.py — settings am Module-Level
|
|
- **Datei:** app/routes/guests.py:22
|
|
- **Problem:** `settings = get_settings()` am Module-Level. Settings werden beim Import geladen, nicht bei Request. Änderungen zur Laufzeit werden nicht erkannt.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-305: permission_templates.py — delete verwendet permissions:templates:write statt :delete
|
|
- **Datei:** app/routes/permission_templates.py:80
|
|
- **Problem:** Delete verwendet `permissions:templates:write` statt `permissions:templates:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-306: tenants.py — create_tenant ohne Audit-Log
|
|
- **Datei:** app/routes/tenants.py:40
|
|
- **Problem:** create_tenant hat kein Audit-Log. Tenant-Erstellung ist eine kritische Operation.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-307: tenants.py — assign_user_to_tenant ohne Audit-Log
|
|
- **Datei:** app/routes/tenants.py:65
|
|
- **Problem:** assign_user_to_tenant hat kein Audit-Log. User-Tenant-Zuweisung sollte auditiert werden.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-308: user_preferences.py — delete verwendet user_preferences:write statt :delete
|
|
- **Datei:** app/routes/user_preferences.py:160
|
|
- **Problem:** Delete verwendet `user_preferences:write` statt `user_preferences:delete`.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-309: workspaces.py — workspace_context return empty modules wenn kein Workspace
|
|
- **Datei:** app/routes/workspaces.py:100
|
|
- **Problem:** Wenn kein Workspace gefunden wird, return `{"modules": []}` — User sieht keine Module. Problem 4 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-310: entity_permission_service.py — Hardcoded deutsche Strings in Notifications
|
|
- **Datei:** app/services/entity_permission_service.py:200
|
|
- **Problem:** `'Neue Berechtigung'`, `'Berechtigung entfernt'` — hardcoded deutsch ohne i18n.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-311: entity_permission_service.py — String-Concatenation in SQL für distinct count
|
|
- **Datei:** app/services/entity_permission_service.py:380
|
|
- **Problem:** `EntityPermission.entity_type + ":" + EntityPermission.entity_id.cast(String)` für distinct count — ineffizient.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-312: plugin_service.py — activate_plugin prüft Zustand nach registry.activate()
|
|
- **Datei:** app/services/plugin_service.py:100
|
|
- **Problem:** `was_already_active = record.active and record.status == 'active'` wird NACH `registry.activate()` geprüft. Problem 1 bestätigt — wenn Plugin bereits aktiv war, werden Permissions trotzdem neu registriert.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-313: plugin_service.py — direkter Zugriff auf _active_plugins
|
|
- **Datei:** app/services/plugin_service.py:110
|
|
- **Problem:** `get_permission_registry()._active_plugins.add(name)` greift direkt auf private Attribute zu. Sollte eine public Methode verwenden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-314: user_service.py — delete_user ohne Audit-Log
|
|
- **Datei:** app/services/user_service.py:200
|
|
- **Problem:** delete_user hat kein Audit-Log. User-Löschung sollte auditiert werden.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-315: workspace_service.py — list_workspaces N+1 Query
|
|
- **Datei:** app/services/workspace_service.py:40
|
|
- **Problem:** Count users per workspace in einer Schleife — N+1 Query. Bei 10 Workspaces = 10 Count-Queries.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-316: workspace_service.py — hardcoded deutscher String
|
|
- **Datei:** app/services/workspace_service.py:580
|
|
- **Problem:** `'Standard-Workspace mit allen Modulen'` — hardcoded deutsch ohne i18n.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-317: role_service.py — delete_role ohne Audit-Log
|
|
- **Datei:** app/services/role_service.py:95
|
|
- **Problem:** delete_role hat kein Audit-Log. Rollen-Löschung sollte auditiert werden.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-318: webhook_service.py — __import__('datetime').datetime.utcnow()
|
|
- **Datei:** app/services/webhook_service.py:200
|
|
- **Problem:** `__import__('datetime').datetime.utcnow()` — deprecated und ugly. Sollte `datetime.now(UTC)` sein.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-319: webhook_service.py — socket.getaddrinfo sync I/O in async Context
|
|
- **Datei:** app/services/webhook_service.py:50
|
|
- **Problem:** `socket.getaddrinfo(hostname, None)` ist sync I/O in async Function. Blockiert Event Loop.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-320: webhook_service.py — secret als Plaintext gespeichert
|
|
- **Datei:** app/services/webhook_service.py:150
|
|
- **Problem:** `secret=data.get('secret')` — Webhook Secret wird als Plaintext in DB gespeichert. Sollte verschlüsselt werden.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-321: backup_service.py — datetime.utcnow() deprecated
|
|
- **Datei:** app/services/backup_service.py:180
|
|
- **Problem:** `datetime.utcnow()` ist deprecated in Python 3.12+.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-322: backup_service.py — subprocess.run() sync I/O in async Function
|
|
- **Datei:** app/services/backup_service.py:200
|
|
- **Problem:** `subprocess.run()` ist sync I/O in async Function. Blockiert Event Loop. Sollte `asyncio.create_subprocess_exec()` verwenden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-323: owner_transfer_service.py — ENTITY_TABLES statisch
|
|
- **Datei:** app/services/owner_transfer_service.py:30
|
|
- **Problem:** `ENTITY_TABLES` ist statisch. Neue Plugin-Entities nicht erfasst.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-325: ai_copilot_service.py — AIConversation/AIMessage mit try/except ImportError
|
|
- **Datei:** app/services/ai_copilot_service.py:20
|
|
- **Problem:** `try: from app.models.ai_conversation import AIConversation, AIMessage except ImportError: AIConversation = None` — Models könnten nicht existieren. Wenn None, wird process_query crashen.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-326: ai_copilot_service.py — get_history N+1 Query
|
|
- **Datei:** app/services/ai_copilot_service.py:300
|
|
- **Problem:** get_history fragt Messages pro Conversation in einer Schleife ab — N+1 Query.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-327: delegation_service.py — create_delegation verwendet db.commit()
|
|
- **Datei:** app/services/delegation_service.py:80
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein. Route macht den Commit.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-328: delegation_service.py — delete_delegation verwendet db.commit()
|
|
- **Datei:** app/services/delegation_service.py:120
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-329: delegation_service.py — keine Audit-Logs
|
|
- **Datei:** app/services/delegation_service.py
|
|
- **Problem:** Keine Audit-Logs für Delegation-Erstellung/Update/Löschung. Permission-Delegation ist sicherheitsrelevant.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-330: group_service.py — delete_group ohne Audit-Log
|
|
- **Datei:** app/services/group_service.py:160
|
|
- **Problem:** delete_group hat kein Audit-Log.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-331: group_service.py — add_user_to_group ohne Audit-Log
|
|
- **Datei:** app/services/group_service.py:200
|
|
- **Problem:** add_user_to_group hat kein Audit-Log. Gruppen-Mitgliedschaft ist sicherheitsrelevant.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-332: group_service.py — remove_user_from_group ohne Audit-Log
|
|
- **Datei:** app/services/group_service.py:230
|
|
- **Problem:** remove_user_from_group hat kein Audit-Log.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-333: dedup_service.py — merge_contacts ohne Audit-Log
|
|
- **Datei:** app/services/dedup_service.py:280
|
|
- **Problem:** merge_contacts hat kein Audit-Log. Contact-Merge ist kritische Operation.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-334: permission_audit.py — hardcoded deutsche Strings
|
|
- **Datei:** app/services/permission_audit.py:40
|
|
- **Problem:** `'Neue Berechtigung'`, `'Berechtigung entfernt'` — hardcoded deutsch ohne i18n.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-335: policy_service.py — ABAC_ALLOWED_FIELDS statisch
|
|
- **Datei:** app/services/policy_service.py:60
|
|
- **Problem:** `ABAC_ALLOWED_FIELDS` ist statisch. Neue Plugin-Entities nicht erfasst.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-336: policy_service.py — create_policy verwendet db.commit()
|
|
- **Datei:** app/services/policy_service.py:200
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-337: policy_service.py — update_policy verwendet db.commit()
|
|
- **Datei:** app/services/policy_service.py:240
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-338: policy_service.py — delete_policy verwendet db.commit()
|
|
- **Datei:** app/services/policy_service.py:260
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-339: policy_service.py — apply_policy_filter Group/Role nicht aufgelöst
|
|
- **Datei:** app/services/policy_service.py:300
|
|
- **Problem:** Group/Role policies werden nicht richtig aufgelöst — nur `principal_id == user_id` wird geprüft, nicht Group-Membership.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-340: permission_template_service.py — create_template db.commit()
|
|
- **Datei:** app/services/permission_template_service.py:80
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-341: permission_template_service.py — update_template db.commit()
|
|
- **Datei:** app/services/permission_template_service.py:120
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-342: permission_template_service.py — delete_template db.commit()
|
|
- **Datei:** app/services/permission_template_service.py:140
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-343: permission_template_service.py — _evaluate_trigger gibt immer True
|
|
- **Datei:** app/services/permission_template_service.py:200
|
|
- **Problem:** `_evaluate_trigger()` gibt immer True zurück. Trigger-Conditions werden nicht ausgewertet.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-344: permission_template_service.py — apply_template db.commit()
|
|
- **Datei:** app/services/permission_template_service.py:210
|
|
- **Problem:** `db.commit()` in Service — Route kann nicht rollbacken.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-345: contact_folder_service.py — reorder_folders db.commit() in Service
|
|
- **Datei:** app/services/contact_folder_service.py:200
|
|
- **Problem:** `db.commit()` in Service — sollte `db.flush()` sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-346: currency_service.py — seed_default_currencies hardcoded Strings
|
|
- **Datei:** app/services/currency_service.py:140
|
|
- **Problem:** `code='EUR'`, `name='Euro'`, `symbol='€'` hardcoded.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-347: tax_service.py — seed_default hardcoded deutsche Strings
|
|
- **Datei:** app/services/tax_service.py:140
|
|
- **Problem:** `name='Mehrwertsteuer 19%'`, `name='Mehrwertsteuer 7%'` hardcoded deutsch.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-348: address_service.py — hardcoded 'Privat' Label
|
|
- **Datei:** app/services/address_service.py:250
|
|
- **Problem:** `label='Privat'` hardcoded deutsch.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-349: tenant_service.py — assign_user_to_tenant ohne Audit-Log
|
|
- **Datei:** app/services/tenant_service.py:80
|
|
- **Problem:** assign_user_to_tenant hat kein Audit-Log. User-Tenant-Zuweisung ist sicherheitsrelevant.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-350: contact.py — indexed_at Spalte vor __table_args__
|
|
- **Datei:** app/models/contact.py:50
|
|
- **Problem:** `indexed_at` Spalte wird vor `__table_args__` definiert — SQLAlchemy Anti-Pattern.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-351: contact.py — IBAN/BIC als Plaintext
|
|
- **Datei:** app/models/contact.py:170
|
|
- **Problem:** `bank_account` (IBAN) und `bic` werden als Plaintext gespeichert. Sensitive Finanzdaten.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-352: contact.py — vat_code/fiscal_code als Plaintext
|
|
- **Datei:** app/models/contact.py:160
|
|
- **Problem:** `vat_code` (USt-IdNr.) und `fiscal_code` (Steuernummer) als Plaintext. Sensitive Steuerdaten.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-353: webhook.py — secret als Plaintext
|
|
- **Datei:** app/models/webhook.py:30
|
|
- **Problem:** `secret` wird als Plaintext in DB gespeichert. Sollte verschlüsselt werden.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-354: system_settings.py — tax_number/vat_id/iban/bic als Plaintext
|
|
- **Datei:** app/models/system_settings.py:35
|
|
- **Problem:** `tax_number`, `vat_id`, `iban`, `bic` werden als Plaintext gespeichert. Sensitive Unternehmensdaten.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-355: bank_account.py — iban/bic als Plaintext
|
|
- **Datei:** app/models/bank_account.py:20
|
|
- **Problem:** `iban` und `bic` als Plaintext. Sensitive Finanzdaten.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-356: compliance.py — ComplianceIncident ohne OwnedMixin
|
|
- **Datei:** app/models/compliance.py
|
|
- **Problem:** ComplianceIncident hat kein OwnedMixin (kein owner_id). Entity-Permissions nicht möglich.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-357: audit.py — search_tsv Spalte vor __table_args__
|
|
- **Datei:** app/models/audit.py:30
|
|
- **Problem:** `search_tsv` Spalte wird vor `__table_args__` definiert — SQLAlchemy Anti-Pattern.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-358: group.py — UserGroup.deleted_at vor __table_args__
|
|
- **Datei:** app/models/group.py:40
|
|
- **Problem:** `deleted_at` Spalte wird vor `__table_args__` definiert — SQLAlchemy Anti-Pattern.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-359: notification.py — NotificationType.deleted_at vor __table_args__
|
|
- **Datei:** app/models/notification.py:60
|
|
- **Problem:** `deleted_at` Spalte wird vor `__table_args__` definiert — SQLAlchemy Anti-Pattern.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-360: ai_conversation.py — AIConversation/AIMessage sollten entfernt sein (Phase 2)
|
|
- **Datei:** app/models/ai_conversation.py
|
|
- **Problem:** AIConversation/AIMessage existieren noch, aber Phase 2 hat AI Chat in Kommunikation integriert und 5 AI-Tabellen gedropped. Diese Models sollten entfernt werden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-361: attachment.py — Attachment parallel zu EntityAttachment (Doppelarchitektur)
|
|
- **Datei:** app/models/attachment.py
|
|
- **Problem:** Attachment Model existiert parallel zu EntityAttachment. Doppelarchitektur — zwei Modelle für ähnliche Funktionalität.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-362: address.py — Address-Tabelle für Bank-Accounts, Contacts nutzen inline Felder
|
|
- **Datei:** app/models/address.py:10
|
|
- **Problem:** Bekannte Inkonsistenz: Address-Tabelle wird für Bank-Accounts genutzt, Contacts nutzen inline Address-Felder. Doppelarchitektur.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-363: system_settings.py — SystemSettingsResponse gibt sensitive Felder zurück
|
|
- **Datei:** app/schemas/system_settings.py:50
|
|
- **Problem:** SystemSettingsResponse gibt tax_number, vat_id, iban, bic in Response zurück. Route maskiert für non-admin, aber Schema erlaubt es.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-364: bank_account.py — BankAccountResponse gibt iban/bic zurück
|
|
- **Datei:** app/schemas/bank_account.py:35
|
|
- **Problem:** BankAccountResponse gibt iban und bic in Response zurück. Sensitive Finanzdaten.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-365: agent_loop.py — Core→Plugin Imports (contracts, kommunikation, ai_assistant)
|
|
- **Datei:** app/ai/agent_loop.py:280, 300
|
|
- **Problem:** Importiert `from app.plugins.builtins.contracts import get_contract_registry`, `from app.plugins.builtins.kommunikation.models import CommConversation`, `from app.plugins.builtins.ai_assistant.tool_registry import ToolRegistry`. Core→Plugin Verstöße.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-366: llm_client.py — Core→Plugin Import (get_contract)
|
|
- **Datei:** app/ai/llm_client.py:292
|
|
- **Problem:** `from app.plugins.builtins.contracts import get_contract` — Core→Plugin Import.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-367: context_builder.py — Core→Plugin Import (ai_assistant contracts)
|
|
- **Datei:** app/ai/context_builder.py:224
|
|
- **Problem:** `from app.plugins.builtins.ai_assistant.contracts import get_tool_registry` — Core→Plugin Import.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-368: agent_permissions.py — Core→Plugin Import (ai_assistant contracts)
|
|
- **Datei:** app/ai/agent_permissions.py:64
|
|
- **Problem:** `from app.plugins.builtins.ai_assistant.contracts import get_tool_registry` — Core→Plugin Import.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-369: oversight.py — DB Model in ai/ Module statt models/
|
|
- **Datei:** app/ai/oversight.py:50
|
|
- **Problem:** `DecisionRecordDB` ist ein SQLAlchemy Model definiert in `app/ai/oversight.py` statt in `app/models/`. Sollte in models/ sein.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-370: agent_loop.py — `pass # agent_workstream removed` Dead Code
|
|
- **Datei:** app/ai/agent_loop.py:280
|
|
- **Problem:** `pass # agent_workstream removed` — Dead Code Kommentar, Code wurde entfernt aber Kommentar bleibt.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-371: engine.py — Core→Plugin Imports (contracts, kommunikation)
|
|
- **Datei:** app/workflows/engine.py:100, 110
|
|
- **Problem:** Importiert `from app.plugins.builtins.contracts import get_contract_registry`, `from app.plugins.builtins.kommunikation.models import CommConversation`. Core→Plugin Verstöße.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-372: step_handlers.py — Core→Plugin Imports (mail, calendar, dms, search, automation contracts)
|
|
- **Datei:** app/workflows/step_handlers.py:200, 250, 300, 350, 400
|
|
- **Problem:** Importiert direkt von `app.plugins.builtins.mail.contracts`, `calendar.contracts`, `dms.contracts`, `unified_search.contracts`, `automation.contracts`. Core→Plugin Verstöße.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-373: step_handlers.py — crm handler importiert contact_service direkt
|
|
- **Datei:** app/workflows/step_handlers.py:450
|
|
- **Problem:** `from app.services.contact_service import create_contact, update_contact` — direkter Service-Import in Step Handler. Sollte über Contract oder generische Interface gehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-374: engine.py — acquire_lock fail-open
|
|
- **Datei:** app/workflows/engine.py:550
|
|
- **Problem:** `return True # Fail open — allow processing without lock` — wenn Redis-Lock nicht akquiriert werden kann, wird der Workflow trotzdem ausgeführt. Das kann zu Race Conditions führen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-375: engine.py — `from app.core.redis import get_redis` aber app/core/redis.py existiert nicht
|
|
- **Datei:** app/workflows/engine.py:540
|
|
- **Problem:** `from app.core.redis import get_redis` — aber es gibt keine `app/core/redis.py`. Redis wird über `app.core.auth.get_redis` importiert. Das wird einen ImportError geben.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-376: registry.py — `from app.core.redis import get_redis` aber app/core/redis.py existiert nicht
|
|
- **Datei:** app/plugins/registry.py:600, 650
|
|
- **Problem:** `from app.core.redis import get_redis` — aber es gibt keine `app/core/redis.py`. Redis wird über `app.core.auth.get_redis` importiert. ImportError bei Cache-Invalidation.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-377: registry.py — sync_notification_types löscht Types nicht vollständig bei Deaktivierung
|
|
- **Datei:** app/plugins/registry.py:181
|
|
- **Problem:** sync_notification_types löscht nur Types wenn das Plugin nicht mehr aktiv ist. Aber die Reihenfolge ist: on_deactivate() → sync_notification_types(). Wenn on_deactivate fehlschlägt, bleiben Types.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-378: registry.py — activate() ruft on_activate() vor sync_notification_types() auf
|
|
- **Datei:** app/plugins/registry.py:580
|
|
- **Problem:** Reihenfolge: on_activate() → register_contributions() → sync_notification_types(). Wenn on_activate Event-Handler registriert die Notification-Types verwenden, sind die Types noch nicht in DB.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-379: contracts.py — _try_lazy_load lädt deaktivierte Plugins neu
|
|
- **Datei:** app/plugins/builtins/contracts.py:109
|
|
- **Problem:** `get_contract()` macht `_try_lazy_load()` auch nach `unregister()`. `unregister()` entfernt Contract und setzt `_loaded`, aber `_try_lazy_load` kann ihn wiederherstellen. Problem 14 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-380: base.py — on_activate registriert Event-Handler ohne Duplikatsprüfung
|
|
- **Datei:** app/plugins/base.py:59
|
|
- **Problem:** `event_bus.subscribe(event_name, handler)` wird bei jedem `on_activate()` aufgerufen. Bei mehrfachem `on_activate()` (pro Tenant) werden Handler doppelt registriert. Problem 2 und 20 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-381: base.py — on_deactivate überschreibt _event_handlers nicht
|
|
- **Datei:** app/plugins/base.py:75
|
|
- **Problem:** `on_deactivate()` ruft `self._event_handlers.clear()` auf, aber wenn eine Subclass `on_deactivate()` überschreibt und `super().on_deactivate()` nicht aufruft, werden Event-Handler nicht deregistriert.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-382: contacts/plugin.py — Routes=[] aber Core hat contacts routes (Doppelarchitektur)
|
|
- **Datei:** app/plugins/builtins/contacts/plugin.py:40
|
|
- **Problem:** `routes=[]` mit Kommentar 'Routes are registered as core routes in main.py'. Contacts ist halb Plugin halb Core — Problem 5 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-383: ai_assistant/plugin.py — menu_items und page_routes für AIAssistant (Phase 2 entfernt)
|
|
- **Datei:** app/plugins/builtins/ai_assistant/plugin.py:80
|
|
- **Problem:** Manifest hat noch `menu_items` und `page_routes` für `/ai-assistant` — aber AIAssistant.tsx wurde in Phase 2 entfernt. Frontend wird versuchen eine nicht existierende Seite zu laden.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-384: knowledge/plugin.py — uuid wird verwendet aber nicht importiert
|
|
- **Datei:** app/plugins/builtins/knowledge/plugin.py:40
|
|
- **Problem:** `uuid.UUID(str(tenant_id))` wird verwendet, aber `import uuid` fehlt am Datei-Anfang. Problem 12 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-385: wiki/plugin.py — Cross-Plugin Import (unified_search)
|
|
- **Datei:** app/plugins/builtins/wiki/plugin.py:30
|
|
- **Problem:** `from app.plugins.builtins.unified_search.providers.wiki_provider import WikiSearchProvider` — direkter Plugin→Plugin Import. Sollte über Contract gehen. Problem 6/15 bestätigt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-386: wiki/plugin.py — on_deactivate ruft unregister_actions_by_owner aber nicht base on_deactivate
|
|
- **Datei:** app/plugins/builtins/wiki/plugin.py:35
|
|
- **Problem:** `unregister_actions_by_owner('wiki')` wird aufgerufen, dann `await super().on_deactivate()`. Aber wenn super().on_deactivate() fehlschlägt, sind Actions bereits deregistriert. Reihenfolge sollte umgekehrt sein.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-387: system_notif/plugin.py — Legacy Notifications parallel zu Kommunikation
|
|
- **Datei:** app/plugins/builtins/system_notif/plugin.py
|
|
- **Problem:** system_notif konvertiert System-Events in Chat-Nachrichten über kommunikation. Aber es gibt auch noch die Legacy Notification Routes (notifications.py). Doppelarchitektur. Problem 18 bestätigt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-388: self_improvement/plugin.py — dependencies deklariert ai_proactive aber nicht kommunikation
|
|
- **Datei:** app/plugins/builtins/self_improvement/plugin.py:30
|
|
- **Problem:** `dependencies=['permissions', 'automation', 'ai_proactive']` — aber services.py importiert von kommunikation. Nicht deklariert. Problem 13/29 bestätigt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-389: tasks/plugin.py — dependencies deklariert nicht kommunikation
|
|
- **Datei:** app/plugins/builtins/tasks/plugin.py
|
|
- **Problem:** `dependencies=['permissions']` — aber tasks/workstream.py importiert von kommunikation. Nicht deklariert. Problem 29 bestätigt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-390: 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'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-391: routes/index.tsx — TODO P2-F1 hardcoded plugin routes
|
|
- **Datei:** frontend/src/routes/index.tsx:1
|
|
- **Problem:** `// TODO: P2-F1 — Replace hardcoded plugin routes with dynamic PluginRouteRenderer`. Statische Routes für /calendar, /dms, /mail, /reports etc. existieren parallel zu PluginRouteRenderer. Problem 6 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-392: routes/index.tsx — /kein-zugriff hardcoded deutscher Pfad
|
|
- **Datei:** frontend/src/routes/index.tsx:100
|
|
- **Problem:** `path: '/kein-zugriff'` — hardcoded deutscher Pfad. Sollte `/no-access` sein.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-393: routes/index.tsx — PluginRouteRenderer als catch-all ohne Permission-Check
|
|
- **Datei:** frontend/src/routes/index.tsx:270
|
|
- **Problem:** `{ path: '*', element: <ErrorBoundary>{<PluginRouteRenderer />}</ErrorBoundary> }` — PluginRouteRenderer als catch-all ohne Permission-Check. Problem 7/28 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-394: routes/index.tsx — /wiki ohne PermissionRoute
|
|
- **Datei:** frontend/src/routes/index.tsx:260
|
|
- **Problem:** `{ path: '/wiki', element: withSuspense(<WikiPage />) }` — keine PermissionRoute. Alle anderen Plugin-Seiten haben PermissionRoute.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-395: routes/index.tsx — /system-dashboard ohne PermissionRoute
|
|
- **Datei:** frontend/src/routes/index.tsx:261
|
|
- **Problem:** `{ path: '/system-dashboard', element: withSuspense(<SystemDashboardPage />) }` — keine PermissionRoute. Sollte system:admin erfordern.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-396: routes/index.tsx — /tags ohne führenden Slash
|
|
- **Datei:** frontend/src/routes/index.tsx:255
|
|
- **Problem:** `{ path: 'tags', ... }` — fehlender führender Slash. Alle anderen Paths haben `/`. Inkonsistent.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-397: routes/index.tsx — communication:read Permission existiert nicht
|
|
- **Datei:** frontend/src/routes/index.tsx:245
|
|
- **Problem:** `<PermissionRoute permission="communication:read">` — aber das kommunikation Plugin definiert `comm:read`, nicht `communication:read`. Problem 8 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-398: routes/index.tsx — activity:read Permission existiert nicht
|
|
- **Datei:** frontend/src/routes/index.tsx:257
|
|
- **Problem:** `<PermissionRoute permission="activity:read">` — aber kein Plugin definiert `activity:read`. Problem 8 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-399: AppShell.tsx — showMessageSidebar prüft /ai-assistant aber AIAssistant wurde entfernt
|
|
- **Datei:** frontend/src/components/layout/AppShell.tsx:40
|
|
- **Problem:** `location.pathname.startsWith('/ai-assistant')` — aber AIAssistant.tsx wurde in Phase 2 entfernt. Dead Code.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-400: workspaceStore.ts — visibleModuleKeys gibt alle Module zurück wenn kein Workspace
|
|
- **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. Problem 4 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-401: Sidebar.tsx — Statische UND dynamische Menü-Items (Doppelarchitektur)
|
|
- **Datei:** frontend/src/components/layout/Sidebar.tsx:54-60
|
|
- **Problem:** `singleItems` ist hardcoded (dashboard, contacts, system-dashboard). Gleichzeitig kommen Plugin-Menüs via `usePluginStore(s => s.getAllMenuItems())`. Doppelarchitektur — Problem 6/22 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-402: Sidebar.tsx — dashboard:read Permission existiert nicht
|
|
- **Datei:** frontend/src/components/layout/Sidebar.tsx:100
|
|
- **Problem:** `permission: item.to === '/dashboard' ? 'dashboard:read'` — aber kein Plugin definiert `dashboard:read`. Problem 8 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-403: PluginRouteRenderer.tsx — Keine Permission-Prüfung
|
|
- **Datei:** frontend/src/components/plugins/PluginRouteRenderer.tsx:18-50
|
|
- **Problem:** PluginRouteRenderer rendert jede Plugin-Seite ohne Permission-Check. Problem 7/28 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-404: PluginLoader.tsx — @vite-ignore im Production-Build
|
|
- **Datei:** frontend/src/components/plugins/PluginLoader.tsx:108
|
|
- **Problem:** `import(/* @vite-ignore */ importPath)` — @vite-ignore funktioniert im Dev-Modus, kann aber im Production-Build Probleme machen. Problem 19 bestätigt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-405: PluginLoader.tsx — Hardcoded deutsche Strings ohne i18n
|
|
- **Datei:** frontend/src/components/plugins/PluginLoader.tsx:70,75,80
|
|
- **Problem:** `'Plugin konnte nicht geladen werden'`, `'Erneut versuchen'`, `'Neu laden'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-406: PluginRouteRenderer.tsx — 'Page Not Found' hardcoded englisch
|
|
- **Datei:** frontend/src/components/plugins/PluginRouteRenderer.tsx:60
|
|
- **Problem:** `'Page Not Found'` — hardcoded englisch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-407: useAIContext.ts — .catch(() => {}) verschluckt Fehler
|
|
- **Datei:** frontend/src/hooks/useAIContext.ts:16
|
|
- **Problem:** `.catch(() => {})` — Fehler beim AI Context Update werden still ignoriert.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-408: usePermission.ts — Wildcard-Matching prüft Segment-Anzahl
|
|
- **Datei:** frontend/src/hooks/usePermission.ts:25
|
|
- **Problem:** `if (pParts.length === rParts.length)` — Wildcard-Matching prüft Segment-Anzahl. `core:*:read` (3 Segmente) matcht nicht `contacts:read` (2 Segmente). Problem 9 bestätigt.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-409: contacts.ts — TODO P2-F9 dual API clients
|
|
- **Datei:** frontend/src/api/contacts.ts:1
|
|
- **Problem:** `// TODO: P2-F9 — Consolidate dual API clients` — contacts.ts und unifiedContacts.ts existieren parallel. Doppelarchitektur.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-410: ai.ts — AIProvider.api_key in Type definiert
|
|
- **Datei:** frontend/src/api/ai.ts:20
|
|
- **Problem:** `api_key: string` im AIProvider Interface — API Key sollte nie im Frontend Type definiert sein. Wird in Responses zurückgegeben.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-411: pluginManifests.ts — /plugins/active-manifests erfordert plugins:read
|
|
- **Datei:** frontend/src/api/pluginManifests.ts:10
|
|
- **Problem:** `apiGet('/plugins/active-manifests')` — dieser Endpoint erfordert `plugins:read` (Problem 3). Normaler User ohne plugins:read bekommt keine Plugin-Menüs.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-412: ai_assistant/models.py — api_key als Plaintext in DB
|
|
- **Datei:** app/plugins/builtins/ai_assistant/models.py:35
|
|
- **Problem:** `api_key: Mapped[str] = mapped_column(Text, nullable=False, default="")` — API Key wird als Plaintext gespeichert.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-413: mcp_client/models.py — api_token als Plaintext in DB
|
|
- **Datei:** app/plugins/builtins/mcp_client/models.py:30
|
|
- **Problem:** `api_token: Mapped[str | None] = mapped_column(String(500), nullable=True)` — API Token wird als Plaintext gespeichert.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-414: permissions/models.py — ShareLink.token als Plaintext
|
|
- **Datei:** app/plugins/builtins/permissions/models.py:50
|
|
- **Problem:** `token: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)` — Share Link Token als Plaintext. Sollte gehasht werden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-415: calendar/models.py — CalendarEntry Spalten vor __table_args__
|
|
- **Datei:** app/plugins/builtins/calendar/models.py:60
|
|
- **Problem:** `indexed_at`, `embedding`, `search_tsv` werden vor `__table_args__` definiert — SQLAlchemy Anti-Pattern.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-416: dms/models.py — File Spalten vor __table_args__
|
|
- **Datei:** app/plugins/builtins/dms/models.py:50
|
|
- **Problem:** `indexed_at`, `content_tsv`, `content_text`, `embedding` vor `__table_args__` — SQLAlchemy Anti-Pattern.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-417: mail/models.py — Mail Spalten vor __table_args__
|
|
- **Datei:** app/plugins/builtins/mail/models.py:100
|
|
- **Problem:** `indexed_at`, `embedding`, `body_tsv`, `company_id` vor `__table_args__` — SQLAlchemy Anti-Pattern.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-418: tags/models.py — Tag Spalten vor __table_args__
|
|
- **Datei:** app/plugins/builtins/tags/models.py:30
|
|
- **Problem:** `embedding`, `search_tsv` vor `__table_args__` — SQLAlchemy Anti-Pattern.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-419: mail/models.py — MailAccount.encrypted_password mit password_salt
|
|
- **Datei:** app/plugins/builtins/mail/models.py:40
|
|
- **Problem:** `encrypted_password` und `password_salt` — gut dass verschlüsselt, aber der Salt sollte pro-Account random sein, nicht hardcoded default="".
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-420: mail/models.py — PgpKey.encrypted_private_key in DB
|
|
- **Datei:** app/plugins/builtins/mail/models.py:300
|
|
- **Problem:** `encrypted_private_key: Mapped[str] = mapped_column(Text, nullable=False)` — PGP Private Key in DB gespeichert. Auch wenn verschlüsselt, ist das ein hohes Risiko.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-421: forgejo_error_reporter/models.py — Integer auto-increment PK statt UUID
|
|
- **Datei:** app/plugins/builtins/forgejo_error_reporter/models.py:20
|
|
- **Problem:** `id = Column(Integer, primary_key=True, autoincrement=True)` — Integer auto-increment PK. AGENTS.md verbietet Integer IDs, UUID only.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-422: forgejo_error_reporter/models.py — Kein TenantMixin
|
|
- **Datei:** app/plugins/builtins/forgejo_error_reporter/models.py
|
|
- **Problem:** `ReportedError` hat kein TenantMixin — nicht tenant-scoped. Kann für Cross-Tenant Data Leaks führen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-423: marketplace/models.py — Kein TenantMixin (global)
|
|
- **Datei:** app/plugins/builtins/marketplace/models.py:30
|
|
- **Problem:** `MarketplaceListing` hat kein TenantMixin — bewusst global, aber muss dokumentiert sein.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-424: ai_assistant/services.py — hardcoded deutsche Strings in seed_default_providers
|
|
- **Datei:** app/plugins/builtins/ai_assistant/services.py:450
|
|
- **Problem:** `'Standard Assistent'`, `'Allgemeiner KI-Assistent'`, `'Du bist ein hilfreicher KI-Assistent...'` — hardcoded deutsch.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-425: ai_assistant/schemas.py — AIProviderCreate.api_key in Schema
|
|
- **Datei:** app/plugins/builtins/ai_assistant/schemas.py:15
|
|
- **Problem:** `api_key: str = Field(default="", max_length=2000)` — API Key in Pydantic Schema. Wird in Create/Update akzeptiert und in Response zurückgegeben.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-426: permissions/schemas.py — ShareLinkResponse.token in Response
|
|
- **Datei:** app/plugins/builtins/permissions/schemas.py:35
|
|
- **Problem:** `token: str` in ShareLinkResponse — Share Link Token wird in API Response zurückgegeben.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-427: mcp_client/schemas.py — McpServerConfigResponse gibt api_token zurück
|
|
- **Datei:** app/plugins/builtins/mcp_client/schemas.py:40
|
|
- **Problem:** McpServerConfigResponse enthält `api_token` — wird in API Response zurückgegeben.
|
|
- **Schweregrad:** High
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-428: knowledge/services.py — Core→Plugin Import (graph_rag)
|
|
- **Datei:** app/plugins/builtins/knowledge/services.py:200
|
|
- **Problem:** `from app.plugins.builtins.graph_rag.services import create_relationship` — Plugin→Plugin direkter Import. Sollte über Contract gehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-429: agent_memory/services.py — Core→Plugin Import (unified_search)
|
|
- **Datei:** app/plugins/builtins/agent_memory/services.py:15
|
|
- **Problem:** `from app.plugins.builtins.unified_search.contracts import generate_embedding` — Plugin→Plugin Import. Sollte über Contract Registry gehen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-430: ai_proactive/services.py — Core→Plugin Import (create_notification)
|
|
- **Datei:** app/plugins/builtins/ai_proactive/services.py:20
|
|
- **Problem:** `from app.core.notifications import create_notification` — Plugin importiert von Core. Das ist OK (Plugin→Core ist erlaubt).
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Kein Bug (Plugin→Core ist erlaubt)
|
|
|
|
### ARCH-431: mail/services.py — 3086 Zeilen (God Object)
|
|
- **Datei:** app/plugins/builtins/mail/services.py
|
|
- **Problem:** 3086 Zeilen — massives God Object. Sollte aufgeteilt werden in: imap_sync.py, smtp_send.py, encryption.py, rules.py, vacation.py, pgp.py.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-432: kommunikation/services.py — 1340 Zeilen (God Object)
|
|
- **Datei:** app/plugins/builtins/kommunikation/services.py
|
|
- **Problem:** 1340 Zeilen — God Object. Sollte aufgeteilt werden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-433: self_improvement/services.py — 1058 Zeilen (God Object)
|
|
- **Datei:** app/plugins/builtins/self_improvement/services.py
|
|
- **Problem:** 1058 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-434: automation/services.py — 896 Zeilen (God Object)
|
|
- **Datei:** app/plugins/builtins/automation/services.py
|
|
- **Problem:** 896 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-435: ai_proactive/services.py — 867 Zeilen (God Object)
|
|
- **Datei:** app/plugins/builtins/ai_proactive/services.py
|
|
- **Problem:** 867 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-436: SuggestionCard.tsx — Hardcoded deutsche Strings ohne i18n
|
|
- **Datei:** frontend/src/components/ai/SuggestionCard.tsx:80
|
|
- **Problem:** `'✓ Ausgeführt'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-437: SuggestionSidebar.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/components/ai/SuggestionSidebar.tsx:20
|
|
- **Problem:** `'Alle'`, `'Info'`, `'Warnung'`, `'Aktion'`, `'Erkenntnis'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-438: AIUIControlIndicator.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/components/ai-ui-control/AIUIControlIndicator.tsx:70
|
|
- **Problem:** `'Navigation'`, `'Filter setzen'`, `'Kontakt öffnen'`, `'Dialog öffnen'`, `'Tab wechseln'`, `'Einstellungen ändern'` — hardcoded deutsch.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-439: ImprovementPanel.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/components/ai/ImprovementPanel.tsx:150
|
|
- **Problem:** `'Messen'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-440: ApprovalRequestBlock.tsx — Hardcoded englische Strings
|
|
- **Datei:** frontend/src/components/comm/blocks/ApprovalRequestBlock.tsx:25
|
|
- **Problem:** `'Approval Required'`, `'Approve'`, `'Reject'` — hardcoded englisch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-441: ContactCardBlock.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/components/comm/blocks/ContactCardBlock.tsx:20
|
|
- **Problem:** `'Unbekannter Kontakt'`, `'Kontakt anzeigen'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-442: AudioBlock.tsx — Hardcoded deutscher String
|
|
- **Datei:** frontend/src/components/comm/blocks/AudioBlock.tsx:35
|
|
- **Problem:** `'Dauer:'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-443: KnowledgeCardBlock.tsx — Hardcoded englische Strings
|
|
- **Datei:** frontend/src/components/comm/blocks/KnowledgeCardBlock.tsx:20
|
|
- **Problem:** `'Knowledge'`, `'Confidence:'`, `'Open'` — hardcoded englisch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-444: MiniAppBlock.tsx — Hardcoded deutscher String
|
|
- **Datei:** frontend/src/components/comm/blocks/MiniAppBlock.tsx:80
|
|
- **Problem:** `'Keine Konfiguration'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-445: ProtectedRoute.tsx — /kein-zugriff hardcoded deutscher Pfad
|
|
- **Datei:** frontend/src/components/common/ProtectedRoute.tsx:25
|
|
- **Problem:** `<Navigate to="/kein-zugriff" replace />` — hardcoded deutscher Pfad.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-446: PrintButton.tsx — Hardcoded deutscher String
|
|
- **Datei:** frontend/src/components/common/PrintButton.tsx:100
|
|
- **Problem:** `'Als PDF'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-447: ShareDialog.tsx — Hardcoded deutscher String
|
|
- **Datei:** frontend/src/components/common/ShareDialog.tsx:300
|
|
- **Problem:** `'Schließen'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-448: FolderPermissionDialog.tsx — Hardcoded deutscher String
|
|
- **Datei:** frontend/src/components/contacts/FolderPermissionDialog.tsx:280
|
|
- **Problem:** `'Schließen'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-449: ContactList.tsx — TODO P2-F18 hardcoded ALL_COLUMNS
|
|
- **Datei:** frontend/src/components/contacts/ContactList.tsx:2
|
|
- **Problem:** `// TODO: P2-F18 — Replace hardcoded ALL_COLUMNS with backend/manifest config` — hardcoded Spalten-Definition.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-450: FilterPanel.tsx — TODO P2-F10 hardcoded FIELD_DEFS
|
|
- **Datei:** frontend/src/components/contacts/FilterPanel.tsx:2
|
|
- **Problem:** `// TODO: P2-F10 — Replace hardcoded FIELD_DEFS with backend/manifest config` — hardcoded Feld-Definitionen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-451: FilterPanel.tsx — Hardcoded deutscher String 'Fertig'
|
|
- **Datei:** frontend/src/components/contacts/FilterPanel.tsx:600
|
|
- **Problem:** `'Fertig'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-452: GroupPanel.tsx — TODO P2-F12 hardcoded GROUP_FIELDS
|
|
- **Datei:** frontend/src/components/contacts/GroupPanel.tsx:2
|
|
- **Problem:** `// TODO: P2-F12 — Replace hardcoded GROUP_FIELDS with shared constant` — hardcoded Gruppierungs-Felder.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-453: GroupPanel.tsx — Hardcoded deutscher String 'Fertig'
|
|
- **Datei:** frontend/src/components/contacts/GroupPanel.tsx:420
|
|
- **Problem:** `'Fertig'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-454: SortPanel.tsx — TODO P2-F11 hardcoded SORT_FIELDS
|
|
- **Datei:** frontend/src/components/contacts/SortPanel.tsx:2
|
|
- **Problem:** `// TODO: P2-F11 — Replace hardcoded SORT_FIELDS with shared constant` — hardcoded Sortier-Felder.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-455: SortPanel.tsx — Hardcoded deutscher String 'Fertig'
|
|
- **Datei:** frontend/src/components/contacts/SortPanel.tsx:430
|
|
- **Problem:** `'Fertig'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-456: SaveViewDialog.tsx — Hardcoded deutscher String 'Speichern'
|
|
- **Datei:** frontend/src/components/contacts/SaveViewDialog.tsx:120
|
|
- **Problem:** `'Speichern'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-457: DashboardWidgetLoader.tsx — TODO P2-F17 hardcoded widgetRegistry
|
|
- **Datei:** frontend/src/components/dashboard/DashboardWidgetLoader.tsx:2
|
|
- **Problem:** `// TODO: P2-F17 — Replace hardcoded widgetRegistry with dynamic manifest config` — hardcoded Widget Registry.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-458: ContactFolderTree.tsx — Hardcoded 'OK' String
|
|
- **Datei:** frontend/src/components/contacts/ContactFolderTree.tsx:580
|
|
- **Problem:** `'OK'` — hardcoded ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-459: NotificationBell.tsx — TODO P2-F8 Legacy Notifications
|
|
- **Datei:** frontend/src/components/layout/NotificationBell.tsx:2
|
|
- **Problem:** `// TODO: P2-F8 — Migrate from /notifications to communication API` — Legacy Notification System läuft parallel zu Kommunikation.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-460: NotificationDropdown.tsx — TODO P2-F7 Legacy Notifications
|
|
- **Datei:** frontend/src/components/notifications/NotificationDropdown.tsx:2
|
|
- **Problem:** `// TODO: P2-F7 — Migrate from /notifications to communication API` — Legacy Notification System.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-461: MailFilterPanel.tsx — TODO P2-F14 hardcoded FIELD_DEFS
|
|
- **Datei:** frontend/src/components/mail/MailFilterPanel.tsx:2
|
|
- **Problem:** `// TODO: P2-F14 — Replace hardcoded FIELD_DEFS with backend config` — hardcoded Feld-Definitionen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-462: MailFolderTree.tsx — TODO P2-F13 hardcoded FOLDER_NAME_MAP
|
|
- **Datei:** frontend/src/components/mail/MailFolderTree.tsx:2
|
|
- **Problem:** `// TODO: P2-F13 — Replace hardcoded FOLDER_NAME_MAP with i18n keys` — hardcoded Ordner-Namen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-463: MailGroupPanel.tsx — TODO P2-F16 hardcoded GROUP_FIELDS
|
|
- **Datei:** frontend/src/components/mail/MailGroupPanel.tsx:2
|
|
- **Problem:** `// TODO: P2-F16 — Replace hardcoded GROUP_FIELDS with shared constant` — hardcoded Gruppierungs-Felder.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-464: MailList.tsx — TODO P3-F6 inline style
|
|
- **Datei:** frontend/src/components/mail/MailList.tsx:2
|
|
- **Problem:** `// TODO: P3-F6 — Replace inline style with Tailwind classes` — inline style statt Tailwind.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-465: MailSortPanel.tsx — TODO P2-F15 hardcoded SORT_FIELDS
|
|
- **Datei:** frontend/src/components/mail/MailSortPanel.tsx:2
|
|
- **Problem:** `// TODO: P2-F15 — Replace hardcoded SORT_FIELDS with shared constant` — hardcoded Sortier-Felder.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-466: CommandPalette.tsx — TODO P2-F4 hardcoded TYPE_LABELS/ICONS
|
|
- **Datei:** frontend/src/components/search/CommandPalette.tsx:2
|
|
- **Problem:** `// TODO: P2-F4 — Replace hardcoded TYPE_LABELS/ICONS with dynamic config` — hardcoded Type-Labels und Icons.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-467: WorkflowEditor.tsx — TODO P2-F21 hardcoded triggerEventOptions
|
|
- **Datei:** frontend/src/components/workflows/WorkflowEditor.tsx:3
|
|
- **Problem:** `// TODO: P2-F21 — Replace hardcoded triggerEventOptions with backend config` — hardcoded Trigger-Event-Optionen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-468: WorkspaceManager.tsx — hardcoded CORE_MENU_ITEMS
|
|
- **Datei:** frontend/src/components/settings/WorkspaceManager.tsx:10
|
|
- **Problem:** `const CORE_MENU_ITEMS = [{ key: 'dashboard', label: 'Dashboard' }, { key: 'contacts', label: 'Kontakte' }]` — hardcoded deutsche Labels und statische Core-Module.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-469: SortableMenuItem.tsx — import * as LucideIcons
|
|
- **Datei:** frontend/src/components/layout/SortableMenuItem.tsx:5
|
|
- **Problem:** `import * as LucideIcons from 'lucide-react'` — lädt ALLE Icons, kann OOM in Tests verursachen. Sidebar.tsx hat bereits einen kommentierten Fix dafür.
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-470: ImportWizard.tsx — 1083 Zeilen (God Object)
|
|
- **Datei:** frontend/src/components/import-export/ImportWizard.tsx
|
|
- **Problem:** 1083 Zeilen — God Object. Sollte aufgeteilt werden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-471: ContactList.tsx — 1311 Zeilen (God Object)
|
|
- **Datei:** frontend/src/components/contacts/ContactList.tsx
|
|
- **Problem:** 1311 Zeilen — God Object. Sollte aufgeteilt werden.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-472: ContactFolderTree.tsx — 616 Zeilen (God Object)
|
|
- **Datei:** frontend/src/components/contacts/ContactFolderTree.tsx
|
|
- **Problem:** 616 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-473: MessageSidebar.tsx — 671 Zeilen (God Object)
|
|
- **Datei:** frontend/src/components/layout/MessageSidebar.tsx
|
|
- **Problem:** 671 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-474: FilterPanel.tsx — 641 Zeilen (God Object)
|
|
- **Datei:** frontend/src/components/contacts/FilterPanel.tsx
|
|
- **Problem:** 641 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-475: ContactDetail.tsx — 588 Zeilen (God Object)
|
|
- **Datei:** frontend/src/components/contacts/ContactDetail.tsx
|
|
- **Problem:** 588 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-476: AgentDashboard.tsx — TODO P2-F25 hardcoded commonModels
|
|
- **Datei:** frontend/src/pages/AgentDashboard.tsx:3
|
|
- **Problem:** `// TODO: P2-F25 — Replace hardcoded commonModels with /ai/providers API` — hardcoded Model-Liste.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-477: AISettings.tsx — Hardcoded deutscher String
|
|
- **Datei:** frontend/src/pages/AISettings.tsx:300
|
|
- **Problem:** `'KI Assistent Einstellungen'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-478: AgentsPlaceholder.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/pages/agents/AgentsPlaceholder.tsx:8
|
|
- **Problem:** `'Agenten'`, `'Diese Seite wird gerade erstellt...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-479: AutomationOverview.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/pages/automation/AutomationOverview.tsx:5
|
|
- **Problem:** `'Automation Übersicht'`, `'Erstellen und verwalten Sie...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-480: AutomationPlaceholder.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/pages/automation/AutomationPlaceholder.tsx:8
|
|
- **Problem:** `'Automation'`, `'Diese Seite wird gerade erstellt...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-481: CustomFields.tsx — TODO P2-T21 hardcoded ENTITY_OPTIONS
|
|
- **Datei:** frontend/src/pages/CustomFields.tsx:3
|
|
- **Problem:** `// TODO: P2-T21 — Replace hardcoded ENTITY_OPTIONS with backend config` — hardcoded Entity-Optionen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-482: GlobalSearchResults.tsx — TODO P2-F5 hardcoded TYPE_LABELS
|
|
- **Datei:** frontend/src/pages/GlobalSearchResults.tsx:3
|
|
- **Problem:** `// TODO: P2-F5 — Replace hardcoded TYPE_LABELS with shared constant` — hardcoded Type-Labels.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-483: DmsTrash.tsx — TODO P3-F29 DMS trash endpoint nicht implementiert
|
|
- **Datei:** frontend/src/pages/DmsTrash.tsx:2
|
|
- **Problem:** `// TODO: P3-F29 — Implement DMS trash endpoint` — DMS Trash Endpoint fehlt.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-484: GuestContacts.tsx — Hardcoded deutscher String
|
|
- **Datei:** frontend/src/pages/GuestContacts.tsx:15
|
|
- **Problem:** `'Weiterleitung zu Kontakten...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-485: GuestLogin.tsx — Hardcoded deutscher String
|
|
- **Datei:** frontend/src/pages/GuestLogin.tsx:15
|
|
- **Problem:** `'Weiterleitung zum Login...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-486: Help pages — Alle hardcoded deutsch ohne i18n
|
|
- **Datei:** frontend/src/pages/help/HelpApiDocs.tsx, HelpContacts.tsx, HelpLogin.tsx, HelpMailSetup.tsx, HelpNavigation.tsx
|
|
- **Problem:** Alle Help-Seiten haben hardcoded deutsche Strings ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-487: AgentDashboard.tsx — 832 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/AgentDashboard.tsx
|
|
- **Problem:** 832 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-488: AutomationDashboard.tsx — 778 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/AutomationDashboard.tsx
|
|
- **Problem:** 778 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-489: Calendar.tsx — 759 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/Calendar.tsx
|
|
- **Problem:** 759 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-490: Dms.tsx — 746 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/Dms.tsx
|
|
- **Problem:** 746 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-491: ContactsList.tsx — 787 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/ContactsList.tsx
|
|
- **Problem:** 787 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-492: Communication.tsx — 894 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/Communication.tsx
|
|
- **Problem:** 894 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-493: CustomFields.tsx — 521 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/CustomFields.tsx
|
|
- **Problem:** 521 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-494: ComplianceTab.tsx — 463 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/ComplianceTab.tsx
|
|
- **Problem:** 463 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-495: ProactiveAISettings.tsx — TODO P2-T20 hardcoded categoryLabels/modelOptions
|
|
- **Datei:** frontend/src/pages/ProactiveAISettings.tsx:3
|
|
- **Problem:** `// TODO: P2-T20 — Replace hardcoded categoryLabels/modelOptions with backend config` — hardcoded Labels und Model-Optionen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-496: SettingsMenuOrder.tsx — TODO P2-F23 hardcoded DEFAULT_ORDER
|
|
- **Datei:** frontend/src/pages/SettingsMenuOrder.tsx:3
|
|
- **Problem:** `// TODO: P2-F23 — Replace hardcoded DEFAULT_ORDER with backend config` — hardcoded Default-Menü-Reihenfolge.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-497: SettingsRechte.tsx — TODO P2-T19 hardcoded PermissionLevelBadge/PrincipalTypeBadge
|
|
- **Datei:** frontend/src/pages/SettingsRechte.tsx:4
|
|
- **Problem:** `// TODO: P2-T19 — Replace hardcoded PermissionLevelBadge/PrincipalTypeBadge with i18n` — hardcoded Badges ohne i18n.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-498: SettingsUsers.tsx — TODO P2-F22 hardcoded LEGACY_ROLES
|
|
- **Datei:** frontend/src/pages/SettingsUsers.tsx:3
|
|
- **Problem:** `// TODO: P2-F22 — Replace hardcoded LEGACY_ROLES with /roles API` — hardcoded Legacy-Rollen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-499: SettingsWebhooks.tsx — TODO P2-F20 hardcoded AVAILABLE_EVENTS
|
|
- **Datei:** frontend/src/pages/SettingsWebhooks.tsx:2
|
|
- **Problem:** `// TODO: P2-F20 — Replace hardcoded AVAILABLE_EVENTS with backend config` — hardcoded verfügbare Webhook-Events.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-500: Trash.tsx — TODO P2-F24 hardcoded ENTITY_TYPES
|
|
- **Datei:** frontend/src/pages/Trash.tsx:2
|
|
- **Problem:** `// TODO: P2-F24 — Replace hardcoded ENTITY_TYPES with dynamic config` — hardcoded Entity-Typen.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-501: Mail.tsx — 1098 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/Mail.tsx
|
|
- **Problem:** 1098 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-502: SettingsBackup.tsx — 797 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/SettingsBackup.tsx
|
|
- **Problem:** 797 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-503: SettingsGroups.tsx — 696 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/SettingsGroups.tsx
|
|
- **Problem:** 696 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-504: Tags.tsx — 594 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/Tags.tsx
|
|
- **Problem:** 594 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-505: SettingsRoles.tsx — 532 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/SettingsRoles.tsx
|
|
- **Problem:** 532 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-506: SettingsStammdaten.tsx — 477 Zeilen (God Object)
|
|
- **Datei:** frontend/src/pages/SettingsStammdaten.tsx
|
|
- **Problem:** 477 Zeilen — God Object.
|
|
- **Schweregrad:** Medium
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-507: NoAccessPage.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/pages/NoAccessPage.tsx:10
|
|
- **Problem:** `'Kein Zugriff'`, `'Sie haben keine Berechtigung...'`, `'Zum Dashboard'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-508: LogsOverview.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/pages/logs/LogsOverview.tsx:5
|
|
- **Problem:** `'Logs Übersicht'`, `'System- und Audit-Logs einsehen...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-509: LogsPlaceholder.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/pages/logs/LogsPlaceholder.tsx:8
|
|
- **Problem:** `'Logs'`, `'Diese Seite wird gerade erstellt...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-510: HelpPlaceholder.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/pages/help/HelpPlaceholder.tsx:8
|
|
- **Problem:** `'Hilfe'`, `'Diese Hilfeseite...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|
|
|
|
### ARCH-511: HelpWelcome.tsx — Hardcoded deutsche Strings
|
|
- **Datei:** frontend/src/pages/help/HelpWelcome.tsx:5
|
|
- **Problem:** `'Willkommen bei LeoCRM'`, `'LeoCRM ist ein selbst-gehostetes CRM-System...'` — hardcoded deutsch ohne t().
|
|
- **Schweregrad:** Low
|
|
- **Status:** ⏳ Nicht gefixt
|