LeoCRM — System-Audit
Erstellt: 2026-08-19
Methode: grep/import-Analyse, DB-Inspektion, Datei-Scan
Keine Spekulation — nur Fakten
1. BACKEND AI MODULE (app/ai/*.py)
Verbindungs-Status pro Modul
| Modul |
Extern importiert von |
Status |
Begründung |
agent_loop.py |
app.ai.agent_stream, app.plugins.builtins.automation.agent_runner |
✅ Verbunden |
ReAct-Loop wird von Automation-Plugin aufgerufen. Importiert selbst llm_client, error_codes, hooks, audit, approval. Hat require_approval Parameter. |
llm_client.py |
agent_loop, data_policy (intern), ai_assistant.services, ai_assistant.participant_handler, ai_proactive.jobs, ai_proactive.services, ai_proactive.context_tools, unified_search.embedding, unified_search.query_understanding, services.ai_copilot_service |
✅ Verbunden |
Zentraler LLM-Client, von 5+ Plugins und Services genutzt. |
ai_use_case.py |
data_policy (intern), automation.agent_routes |
✅ Verbunden |
AIUseCaseMetadata wird in Automation-Plugin validiert. |
skill_registry.py |
agent_tools (intern), agent_permissions (intern) |
⚠️ Nur intern |
Nur innerhalb app/ai/ genutzt. Kein Plugin oder Route importiert es direkt. |
action_mapper.py |
llm_client (intern, lazy import line 749) |
⚠️ Nur intern |
Wird nur von llm_client.py per Lazy-Import aufgerufen. |
agent_permissions.py |
— |
❌ Unverbunden |
Kein externer Import. Definiert Permission-Checks für Agent-Tools, aber niemand ruft es auf. |
agent_tools.py |
— |
❌ Unverbunden |
Kein externer Import. Definiert Tool-Execution-Logik, wird von keiner Route/Plugin aufgerufen. |
data_policy.py |
— |
❌ Unverbunden |
Kein externer Import. Definiert Data-Policy-Checks (PII-Sanitization, Provider-Compliance), wird nicht aufgerufen. |
transparency.py |
— |
❌ Unverbunden |
Kein externer Import. mark_as_ai_generated() wird von niemandem aufgerufen. |
oversight.py |
— |
❌ Unverbunden |
Definiert DecisionRecordDB Model (__tablename__ = "ai_decision_records"), aber Tabelle existiert NICHT in Test-DB. Kein Import, keine Migration. |
agent_memory.py |
— |
❌ Unverbunden |
app/ai/agent_memory.py wird von niemandem importiert. Es gibt ein separates Plugin app/plugins/builtins/agent_memory/ mit eigenen Models — das ist verbunden, aber das AI-Modul ist verwaist. |
agent_stream.py |
— |
❌ Unverbunden |
Importiert agent_loop intern, aber niemand importiert agent_stream extern. Streaming-Funktionality ungenutzt. |
context_builder.py |
— |
❌ Unverbunden |
Importiert sensitive_data, tenant, user, ai_assistant.contracts intern, aber niemand importiert context_builder extern. build_agent_context() wird nie aufgerufen. |
Zusammenfassung AI Module
- Verbunden (extern): 3 von 13 (
agent_loop, llm_client, ai_use_case)
- Nur intern verbunden: 2 (
skill_registry, action_mapper)
- Komplett unverbunden: 8 (
agent_permissions, agent_tools, data_policy, transparency, oversight, agent_memory, agent_stream, context_builder)
Was verbunden werden muss
context_builder.py → Sollte von agent_loop.py oder automation/agent_runner.py aufgerufen werden, um Agent-Context (User, Tenant, Memory) aufzubauen
agent_tools.py → Sollte von agent_loop.py aufgerufen werden für Tool-Execution (aktuell nur ToolRegistry aus ai_assistant wird genutzt)
agent_permissions.py → Sollte von agent_tools.py oder agent_loop.py aufgerufen werden für Permission-Checks vor Tool-Execution
data_policy.py → Sollte vor LLM-Calls aufgerufen werden (PII-Sanitization, Provider-Compliance)
oversight.py → Braucht Migration + Integration in Agent-Loop für Decision-Records
transparency.py → Sollte bei AI-generierten Inhalten aufgerufen werden
agent_stream.py → Sollte von Routes/Plugins für Streaming-Antworten genutzt werden
agent_memory.py (AI-Modul) → Sollte mit agent_memory Plugin integriert werden oder gelöscht werden (Duplikat)
2. WORKFLOW MODULE (app/workflows/*.py)
| Modul |
Verbunden mit |
Status |
Details |
engine.py |
app.routes.workflows (line 308), app.core.event_bus (line 94) |
✅ Verbunden |
WorkflowEngine wird von Routes und Event-Bus importiert. Verarbeitet Steps sequenziell. |
step_handlers.py |
engine.py (line 33: from app.workflows.step_handlers import StepResult, get_step_handler) |
✅ Verbunden |
10 Step-Typen registriert via @register_step_type: wait, http, mail, calendar, dms, search, agent, crm, event, webhook. get_step_handler() wird in Engine aufgerufen. |
decision_guard.py |
— |
❌ Unverbunden |
NICHT importiert von engine.py oder irgendeinem anderen Modul. Definiert requires_human_review() und check_action_guard() aber niemand ruft diese auf. Konzeptionell für G-HUMAN-DEC gedacht, aber nicht integriert. |
Engine Step-Verarbeitung
- Approval steps: Engine erkennt
step_type == "approval", setzt instance.resume_reason = "approval", pausiert. resume() methode setzt fort nach Approval-Entscheidung.
- Registered handlers: 10 Typen (wait, http, mail, calendar, dms, search, agent, crm, event, webhook)
- Legacy handlers: 3 Typen (action, notification, condition) — direkt in Engine implementiert
- Step-Typen gesamt: 13 (10 registered + 3 legacy)
Was verbunden werden muss
decision_guard.py → Muss in engine.py vor der Ausführung von High-Risk-Actions aufgerufen werden. Aktuell existiert der Guard, wird aber nie aufgerufen.
3. PLUGIN SYSTEM (app/plugins/builtins/)
Plugins mit eigenen Routes
| Plugin |
Routes-Datei |
Router-Prefix |
Registriert via |
agent_memory |
routes.py |
— |
Plugin-Manifest |
ai_assistant |
routes.py |
— |
Plugin-Manifest |
ai_proactive |
routes.py |
— |
Plugin-Manifest |
ai_ui_control |
routes.py |
— |
Plugin-Manifest |
automation |
routes.py, skill_routes.py, agent_routes.py |
/api/v1/automation, /api/v1/skills, /api/v1/agents |
Plugin-Manifest (3 Router) |
calendar |
routes.py |
— |
Plugin-Manifest |
dms |
routes.py |
— |
Plugin-Manifest |
entity_links |
routes.py |
— |
Plugin-Manifest |
forgejo_error_reporter |
routes.py |
/api/v1/forgejo-error-reporter |
Plugin-Manifest |
graph_rag |
routes.py |
— |
Plugin-Manifest |
kommunikation |
routes.py |
— |
Plugin-Manifest |
mail |
routes.py |
— |
Plugin-Manifest |
marketplace |
routes.py |
— |
Plugin-Manifest |
mcp_client |
routes.py |
/api/v1/mcp-client |
Plugin-Manifest |
mcp_server |
routes.py |
— |
Plugin-Manifest |
permissions |
routes.py, public_routes.py |
— |
Plugin-Manifest |
report_generator |
routes.py |
— |
Plugin-Manifest |
tags |
routes.py |
— |
Plugin-Manifest |
tasks |
routes.py |
— |
Plugin-Manifest |
unified_search |
routes.py |
— |
Plugin-Manifest |
wiki |
routes.py |
— |
Plugin-Manifest |
system_notif |
— (keine Routes) |
— |
Event-Bus-only (Participant Handler) |
contacts |
— (keine eigene Routes) |
— |
Core-Plugin ohne eigene Routes |
Plugins mit eigenen Models
Alle 19 Plugins haben models.py:
agent_memory, ai_assistant, ai_proactive, automation, calendar, dms, entity_links, forgejo_error_reporter, graph_rag, kommunikation, mail, marketplace, mcp_client, permissions, report_generator, tags, tasks, unified_search, wiki
Plugins die aus app/ai/ importieren
| Plugin |
Importiert |
Modul |
ai_assistant |
llm_complete |
services.py, participant_handler.py |
ai_proactive |
llm_complete |
jobs.py, services.py, context_tools.py |
automation |
run_react_loop, ReActResult |
agent_runner.py |
automation |
AIUseCaseMetadata, validate_ai_use_case |
agent_routes.py |
unified_search |
get_llm_client, generate_embedding, get_provider_compliance |
embedding.py, query_understanding.py |
Plugins die aus app/workflows/ importieren
KEINE. Kein Plugin importiert aus app.workflows.
Contracts-System
18 Plugins haben contracts.py. Zentrale Registry in app/plugins/builtins/contracts.py mit get_contract() und get_contract_registry().
| Contract-Nutzer |
Importiert Contract von |
Zweck |
dms/routes.py |
permissions.contracts |
Permission-Checks für DMS-Objekte |
mail/routes.py |
calendar.contracts |
Calendar-Integration für Mail-Termine |
kommunikation/dms_bridge.py |
dms.contracts |
DMS-Dateien in Kommunikation anhängen |
kommunikation/search_provider.py |
unified_search.contracts |
Kommunikation in Unified Search einbinden |
unified_search/plugin.py |
ai_assistant.contracts |
AI-Tool-Registry für Search nutzen |
ai_proactive/jobs.py |
unified_search.contracts |
Proactive AI nutzt Unified Search |
report_generator/jobs.py |
dms.contracts (via registry) |
Reports aus DMS-Dateien generieren |
Alle Plugins nutzen get_contract_registry().unregister() in on_deactivate().
4. APPROVAL SYSTEM
app/core/approval.py
- Model:
ApprovalRequest (__tablename__ = "approval_requests")
- Felder:
id, entity_type, entity_id, action, requested_by, requested_by_type, approver_id, approver_group, status, comment, created_at, resolved_at, expires_at, request_metadata
- Status-Lifecycle:
pending → approved | rejected | expired
- Funktionen:
create_approval_request(), resolve_approval_request(), expire_approval_request()
- Tabelle in DB: ✅ Vorhanden (
approval_requests in leocrm_test)
- Migration:
0123_approval_requests.py
app/routes/approvals.py
- Prefix:
/api/v1/approvals
- Endpoints:
POST "" (create), GET "" (list), GET "/{id}" (detail), POST "/{id}/approve", POST "/{id}/reject", POST "/{id}/expire"
- Permissions:
approvals:write, approvals:read, approvals:approve
- Registriert in main.py: ✅ (line 582)
Verbindung mit Agent Loop
✅ Verbunden. agent_loop.py hat:
- Parameter
require_approval: bool = False (line 152)
- Parameter
approval_tools: list[str] | None = None (line 153)
- Wenn
require_approval=True und Tool in approval_tools: erstellt ApprovalRequest via create_approval_request() (line 380-383)
- Setzt
result.status = "waiting_for_approval" (line 405)
- Postet Approval-Request an Workstream (line 395-400)
Verbindung mit Workflows
✅ Verbunden. engine.py behandelt step_type == "approval":
- Setzt
instance.status = "in_progress" und instance.resume_reason = "approval" (line 110-113)
- Pausiert Workflow, wartet auf User-Entscheidung
resume() Methode (line 436+) setzt Workflow fort nach Approval
Verbindung mit Automation Plugin
❌ NICHT verbunden. Kein Import von approval in app/plugins/builtins/automation/. Der Automation-Plugin nutzt agent_loop.run_react_loop() aber gibt require_approval nicht durch.
Verbindung mit decision_guard.py
❌ NICHT verbunden. decision_guard.py referenziert requires_approval und ApprovalRequest konzeptionell, ist aber nicht in Engine oder Agent Loop integriert.
5. FRONTEND (frontend/src/)
Pages mit echter API-Anbindung
| Page |
API-Refs |
Zeilen |
Status |
Communication.tsx |
22 |
859 |
✅ Voll verbunden (apiClient, WebSocket, AI-Streaming) |
Mail.tsx |
12 |
1098 |
✅ Voll verbunden |
SettingsStammdaten.tsx |
17 |
477 |
✅ Voll verbunden (Adressen, Bankkonten) |
Tags.tsx |
8 |
500 |
✅ Voll verbunden (TanStack Query) |
Dms.tsx |
7 |
746 |
✅ Voll verbunden |
SettingsRechte.tsx |
7 |
420 |
✅ Voll verbunden |
Wiki.tsx |
7 |
410 |
✅ Voll verbunden |
ContactsList.tsx |
6 |
787 |
✅ Voll verbunden |
AutomationSettings.tsx |
6 |
326 |
✅ Voll verbunden |
MailSettings.tsx |
5 |
440 |
✅ Voll verbunden |
Calendar.tsx |
4 |
759 |
✅ Voll verbunden |
SettingsGroups.tsx |
4 |
696 |
✅ Voll verbunden |
SettingsWebhooks.tsx |
4 |
630 |
✅ Voll verbunden |
SettingsRoles.tsx |
4 |
532 |
✅ Voll verbunden |
SettingsPlugins.tsx |
4 |
384 |
✅ Voll verbunden |
Workflows.tsx |
4 |
279 |
✅ Voll verbunden |
AgentDashboard.tsx |
3 |
832 |
✅ Voll verbunden |
AutomationDashboard.tsx |
3 |
778 |
✅ Voll verbunden |
AIAssistant.tsx |
3 |
132 |
✅ Verbunden |
CalendarKanban.tsx |
3 |
123 |
✅ Verbunden |
Dashboard.tsx |
2 |
98 |
✅ Verbunden |
SettingsMcp.tsx |
2 |
268 |
✅ Verbunden |
DmsTrash.tsx |
2 |
156 |
✅ Verbunden |
Tasks.tsx |
1 |
419 |
✅ Verbunden |
Reports.tsx |
1 |
433 |
✅ Verbunden |
SettingsBackup.tsx |
1 |
499 |
✅ Verbunden |
CustomFields.tsx |
1 |
521 |
✅ Verbunden |
AISettings.tsx |
9 |
333 |
✅ Verbunden |
SettingsSequences.tsx |
9 |
175 |
✅ Verbunden |
SettingsCurrencies.tsx |
9 |
180 |
✅ Verbunden |
SettingsTaxes.tsx |
9 |
182 |
✅ Verbunden |
SettingsStammdaten.tsx |
17 |
477 |
✅ Voll verbunden |
SettingsProfile.tsx |
1 |
182 |
✅ Verbunden |
SettingsUsers.tsx |
1 |
315 |
✅ Verbunden |
SettingsTheme.tsx |
1 |
346 |
✅ Verbunden |
SettingsFirmendaten.tsx |
1 |
278 |
✅ Verbunden |
SettingsMenuOrder.tsx |
1 |
240 |
✅ Verbunden |
Trash.tsx |
1 |
265 |
✅ Verbunden |
GlobalSearchResults.tsx |
1 |
237 |
✅ Verbunden |
DedupMerge.tsx |
1 |
225 |
✅ Verbunden |
ProactiveAISettings.tsx |
1 |
219 |
✅ Verbunden |
ActivityTimeline.tsx |
1 |
202 |
✅ Verbunden |
AuditLog.tsx |
1 |
167 |
✅ Verbunden |
SettingsNotifications.tsx |
1 |
159 |
✅ Verbunden |
PasswordResetConfirm.tsx |
1 |
106 |
✅ Verbunden |
PasswordResetRequest.tsx |
1 |
90 |
✅ Verbunden |
Login.tsx |
1 |
93 |
✅ Verbunden |
ContactDetailPage.tsx |
1 |
73 |
✅ Verbunden |
Pages ohne API-Anbindung (leer/Placeholders/Navigation)
| Page |
Zeilen |
Status |
SettingsWorkspaces.tsx |
9 |
❌ Leer — nur Redirect/Placeholder |
AIAssistantStandalone.tsx |
10 |
❌ Wrapper ohne API |
CalendarStandalone.tsx |
10 |
❌ Wrapper ohne API |
ContactsStandalone.tsx |
10 |
❌ Wrapper ohne API |
DmsStandalone.tsx |
10 |
❌ Wrapper ohne API |
MailStandalone.tsx |
10 |
❌ Wrapper ohne API |
AgentsPlaceholder.tsx |
12 |
❌ Placeholder |
AutomationPlaceholder.tsx |
12 |
❌ Placeholder |
LogsPlaceholder.tsx |
12 |
❌ Placeholder |
HelpPlaceholder.tsx |
17 |
❌ Placeholder |
GuestContacts.tsx |
19 |
❌ Keine API |
GuestLogin.tsx |
19 |
❌ Keine API |
NoAccessPage.tsx |
22 |
❌ Statische Error-Page |
HelpLogin.tsx |
23 |
❌ Statische Help-Page |
HelpContacts.tsx |
25 |
❌ Statische Help-Page |
HelpMailSetup.tsx |
25 |
❌ Statische Help-Page |
AutomationOverview.tsx |
28 |
❌ Übersicht ohne API |
HelpNavigation.tsx |
29 |
❌ Statische Help-Page |
HelpApiDocs.tsx |
33 |
❌ Statische Help-Page |
HelpWelcome.tsx |
33 |
❌ Statische Help-Page |
AgentsOverview.tsx |
35 |
❌ Übersicht ohne API |
LogsOverview.tsx |
35 |
❌ Übersicht ohne API |
SettingsAI.tsx |
46 |
❌ Keine API (sollte AISettings nutzen) |
SettingsUserManagement.tsx |
48 |
❌ Keine API |
ApiDocs.tsx |
50 |
❌ Statische API-Docs |
ImportExport.tsx |
68 |
❌ Keine API (sollte importExport API nutzen) |
Agents.tsx |
102 |
❌ Keine API (sollte automation API nutzen) |
Settings.tsx |
105 |
❌ Nur Navigation/Tab-Container |
Automation.tsx |
111 |
❌ Nur Navigation/Tab-Container |
Logs.tsx |
119 |
❌ Nur Navigation/Tab-Container |
StartPage.tsx |
150 |
❌ Keine API |
Help.tsx |
164 |
❌ Nur Navigation/Tab-Container |
SettingsSystem.tsx |
175 |
❌ Keine API |
API-Clients (frontend/src/api/)
| API-Client |
Nutzung in Pages/Components |
Status |
hooks.ts |
30 Importe |
✅ Meistgenutzt |
calendar.ts |
16 |
✅ |
mail.ts |
14 |
✅ |
dms.ts |
12 |
✅ |
ai.ts |
10 |
✅ |
client.ts |
10 |
✅ (Basis-Client) |
tags.ts |
8 |
✅ |
automation.ts |
6 |
✅ |
customFieldDefinitions.ts |
6 |
✅ |
workflows.ts |
5 |
✅ |
tasks.ts |
5 |
✅ |
savedFilters.ts |
5 |
✅ |
dedup.ts |
5 |
✅ |
users.ts |
4 |
✅ |
entityHistory.ts |
4 |
✅ |
customFields.ts |
4 |
✅ |
knowledge.ts |
4 |
✅ |
reports.ts |
2 |
✅ |
pluginManifests.ts |
2 |
✅ |
groups.ts |
2 |
✅ |
importExport.ts |
2 |
✅ |
entityPermissions.ts |
2 |
✅ |
entityPermissionHooks.ts |
2 |
✅ |
audit.ts |
2 |
✅ |
webhooks.ts |
1 |
✅ |
settings.ts |
1 |
✅ |
userPreferences.ts |
1 |
✅ |
search.ts |
1 |
✅ |
savedViews.ts |
1 |
✅ |
permissions.ts |
1 |
✅ |
mcpClient.ts |
1 |
✅ |
mcp.ts |
1 |
✅ |
comm.ts |
1 |
✅ |
backups.ts |
1 |
✅ |
aiProactive.ts |
3 |
✅ |
contactFolders.ts |
3 |
✅ |
contacts.ts |
3 |
✅ |
dashboard.ts |
3 |
✅ |
notifications.ts |
3 |
✅ |
unifiedContacts.ts |
3 |
✅ |
aiUIControl.ts |
0 |
❌ Unbenutzt |
attachments.ts |
0 |
❌ Unbenutzt |
auth.ts |
0 |
❌ Unbenutzt (Login nutzt hooks) |
plugins.ts |
0 |
❌ Unbenutzt |
policies.ts |
0 |
❌ Unbenutzt |
policyHooks.ts |
0 |
❌ Unbenutzt |
roles.ts |
0 |
❌ Unbenutzt (SettingsRoles nutzt hooks) |
searchHooks.ts |
0 |
❌ Unbenutzt |
types.ts |
0 |
❌ Unbenutzt (nur Typen) |
Was verbunden werden muss
Agents.tsx (102 Zeilen, 0 API) → Sollte @/api/automation nutzen (AgentDashboard.tsx zeigt wie)
ImportExport.tsx (68 Zeilen, 0 API) → Sollte @/api/importExport nutzen
SettingsAI.tsx (46 Zeilen, 0 API) → Sollte @/api/ai oder AISettings.tsx einbinden
SettingsSystem.tsx (175 Zeilen, 0 API) → Sollte @/api/settings nutzen
SettingsUserManagement.tsx (48 Zeilen, 0 API) → Sollte @/api/users nutzen
- 9 unbenutzte API-Clients prüfen:
aiUIControl, attachments, auth, plugins, policies, policyHooks, roles, searchHooks → Entweder verbinden oder löschen
6. ROUTES (app/routes/ + plugin routes)
Route-Dateien in app/routes/
44 Route-Dateien (inkl. __init__.py). Alle in main.py registriert außer delegations.py (geparkt, line 575: # app.include_router(delegations.router) # ⏸ Parked).
| Route-Datei |
Zeilen |
Registriert |
Status |
workflows.py |
671 |
✅ line 557 |
Echte DB-Daten |
users.py |
397 |
✅ line 541 |
Echte DB-Daten |
workspaces.py |
373 |
✅ line 579 |
Echte DB-Daten |
import_export.py |
371 |
✅ line 554 |
Echte DB-Daten |
plugins.py |
354 |
✅ line 555 |
Echte DB-Daten |
companies.py |
353 |
✅ line 547 |
Echte DB-Daten |
approvals.py |
305 |
✅ line 582 |
Echte DB-Daten |
contacts.py |
318 |
✅ line 548 |
Echte DB-Daten |
entity_permissions.py |
316 |
✅ line 551 |
Echte DB-Daten |
groups.py |
262 |
✅ line 543 |
Echte DB-Daten |
auth.py |
256 |
✅ line 540 |
Echte DB-Daten |
roles.py |
247 |
✅ line 542 |
Echte DB-Daten |
notifications.py |
224 |
✅ line 545 |
Echte DB-Daten |
entity_history.py |
215 |
✅ line 553 |
Echte DB-Daten |
webhooks.py |
206 |
✅ line 573 |
Echte DB-Daten |
custom_fields.py |
201 |
✅ line 570 |
Echte DB-Daten |
saved_views.py |
199 |
✅ line 572 |
Echte DB-Daten |
guests.py |
199 |
✅ line 578 |
Echte DB-Daten |
user_preferences.py |
195 |
✅ line 558 |
Echte DB-Daten |
outbox.py |
162 |
✅ line 580 |
Echte DB-Daten |
saved_filters.py |
160 |
✅ line 571 |
Echte DB-Daten |
attachments.py |
144 |
✅ line 563 |
Echte DB-Daten |
errors.py |
139 |
✅ line 577 |
Echte DB-Daten |
ai_copilot.py |
129 |
✅ line 556 |
Echte DB-Daten |
addresses.py |
123 |
✅ line 564 |
Echte DB-Daten |
permission_templates.py |
114 |
✅ line 574 |
Echte DB-Daten |
custom_field_definitions.py |
110 |
✅ line 569 |
Echte DB-Daten |
contact_folders.py |
110 |
✅ line 549 |
Echte DB-Daten |
contact_folder_permissions.py |
107 |
✅ line 550 |
Echte DB-Daten |
delegations.py |
105 |
❌ Geparkt |
NICHT registriert (line 575 auskommentiert) |
backups.py |
104 |
✅ line 567 |
Echte DB-Daten |
bank_accounts.py |
102 |
✅ line 565 |
Echte DB-Daten |
dashboard.py |
100 |
✅ line 552 |
Echte DB-Daten |
sequences.py |
100 |
✅ line 561 |
Echte DB-Daten |
policies.py |
95 |
✅ line 576 |
Echte DB-Daten |
audit.py |
94 |
✅ line 566 |
Echte DB-Daten |
taxes.py |
85 |
✅ line 560 |
Echte DB-Daten |
currencies.py |
85 |
✅ line 559 |
Echte DB-Daten |
health.py |
81 |
✅ line 538 |
Health-Check |
tenants.py |
77 |
✅ line 544 |
Echte DB-Daten |
api_tokens.py |
77 |
✅ line 581 |
Echte DB-Daten |
owner_transfer.py |
58 |
✅ line 568 |
Echte DB-Daten |
system_settings.py |
56 |
✅ line 562 |
Echte DB-Daten |
metrics.py |
29 |
✅ line 539 |
Metrics |
__init__.py |
28 |
— |
Modul-Init |
Plugin Routes (dynamisch registriert)
Plugin-Routes werden in main.py (lines 602-614) dynamisch via importlib.import_module(route_def.module) registriert. Jeder Plugin-Router bekommt eine Plugin-Dependency.
Stubs/TODOs in Routes
Keine Stubs gefunden. Alle Route-Dateien haben 0 TODO/FIXME/NotImplemented/Placeholder-Marker.
7. TESTS (tests/)
Test-Übersicht
- Anzahl: 98 Test-Dateien
- Test-DB:
leocrm_test auf localhost:5432 (User: leocrm)
- Conftest: Dynamisch importiert alle Plugin-Models für
Base.metadata.create_all()
- Schema: Fresh schema pro Test (created from metadata, nicht via Alembic)
Integration-Tests (mit DB, hohe DB-Nutzung)
| Test-Datei |
DB-Refs |
Mock-Refs |
Typ |
test_workflows.py |
241 |
11 |
Integration |
test_rbac_comprehensive.py |
205 |
11 |
Integration |
test_ai_proactive.py |
192 |
75 |
Mixed (Integration + Mock) |
test_unified_search.py |
124 |
78 |
Mixed |
test_ai_copilot.py |
120 |
18 |
Integration |
test_notification_migration.py |
111 |
0 |
Integration |
test_plugins.py |
99 |
0 |
Integration |
test_outbox_phase5.py |
97 |
0 |
Integration |
test_workspaces.py |
89 |
0 |
Integration |
test_permission_system_live.py |
87 |
0 |
Integration |
test_entity_permissions.py |
78 |
0 |
Integration |
test_abac.py |
62 |
0 |
Integration |
test_commands.py |
59 |
0 |
Integration |
test_backend_coverage_gaps.py |
58 |
3 |
Integration |
test_cross_tenant_security.py |
55 |
1 |
Integration |
test_mail.py |
55 |
16 |
Mixed |
test_unified_search_phase_e.py |
47 |
39 |
Mixed |
test_import_export.py |
44 |
0 |
Integration |
test_tags.py |
42 |
5 |
Integration |
test_tenant.py |
42 |
1 |
Integration |
test_abac_integration.py |
42 |
0 |
Integration |
test_permission_performance.py |
41 |
2 |
Integration |
test_companies.py |
39 |
0 |
Integration |
test_unified_tasks.py |
34 |
0 |
Integration |
test_tasks.py |
32 |
2 |
Integration |
test_entity_links.py |
31 |
0 |
Integration |
test_permissions.py |
29 |
0 |
Integration |
test_notifications.py |
28 |
1 |
Integration |
test_api_tokens.py |
28 |
0 |
Integration |
test_user_preferences.py |
27 |
0 |
Integration |
test_saved_filters.py |
26 |
0 |
Integration |
test_auth.py |
26 |
0 |
Integration |
test_calendar.py |
24 |
5 |
Integration |
test_outbox.py |
23 |
0 |
Integration |
Mock-Dominierte Tests
| Test-Datei |
DB-Refs |
Mock-Refs |
Typ |
test_marketplace.py |
39 |
165 |
Mock-dominiert |
test_agent_memory.py |
32 |
138 |
Mock-dominiert |
test_external_agent_api.py |
28 |
105 |
Mock-dominiert |
test_trigger_core.py |
34 |
89 |
Mock-dominiert |
test_graph_rag.py |
35 |
100 |
Mock-dominiert |
Tests ohne DB oder Mock (Unit-Tests)
| Test-Datei |
DB-Refs |
Mock-Refs |
Typ |
test_recurrence_unit.py |
— |
— |
Unit |
test_semver.py |
— |
— |
Unit |
test_sensitive_data.py |
— |
— |
Unit |
test_resilience.py |
— |
— |
Unit |
test_redis_pool.py |
— |
— |
Unit |
test_rate_limit_policies.py |
— |
— |
Unit |
test_restore_registry.py |
— |
— |
Unit |
test_rls_coverage.py |
— |
— |
Unit |
test_storage.py |
— |
— |
Unit |
test_versioning.py |
— |
— |
Unit |
test_ws_helpers.py |
— |
— |
Unit |
Test-DB Funktionalität
Die Test-DB (leocrm_test) ist erreichbar und hat 120 Tabellen. Tests nutzen Base.metadata.create_all() (nicht Alembic-Migrationen) für Schema-Erstellung.
8. MODELS (app/models/ + plugin models)
Core Models (app/models/)
40 Model-Dateien mit folgenden Tabellen:
| Tabelle |
Model-Datei |
addresses |
address.py |
ai_conversations |
ai_conversation.py |
ai_messages |
ai_conversation.py |
attachments |
attachment.py |
audit_log |
audit.py |
password_reset_tokens |
auth.py |
api_tokens |
auth.py |
backups |
backup.py |
bank_accounts |
bank_account.py |
consumer_inbox |
consumer_inbox.py |
contact_folders |
contact_folder.py |
contact_merge_history |
contact_merge.py |
contacts |
contact.py |
contactpersons |
contact.py |
currencies |
currency.py |
custom_field_definitions |
custom_field_definition.py |
entity_attachments |
entity_attachment.py |
entity_history |
entity_history.py |
entity_permissions |
entity_permission.py |
entity_policies |
entity_policy.py |
groups |
group.py |
user_groups |
group.py |
notifications |
notification.py |
notification_types |
notification.py |
notification_preferences |
notification.py |
outbox_deliveries |
outbox_delivery.py |
event_outbox |
outbox.py |
permission_delegations |
permission_delegation.py |
permission_templates |
permission_template.py |
plugin_allowlist |
plugin_allowlist.py |
plugins |
plugin.py |
plugin_migrations |
plugin.py |
roles |
role.py |
saved_filters |
saved_filter.py |
saved_views |
saved_view.py |
sequences |
sequence.py |
sessions |
session.py |
system_settings |
system_settings.py |
tax_rates |
tax.py |
tenants |
tenant.py |
user_preferences |
user_preference.py |
users |
user.py |
user_tenants |
user.py |
webhooks |
webhook.py |
workflows |
workflow.py |
workflow_instances |
workflow.py |
workflow_step_history |
workflow.py |
workspaces |
workspace.py |
workspace_modules |
workspace.py |
workspace_users |
workspace.py |
workspace_widgets |
workspace.py |
Plugin Models
19 Plugin-Model-Dateien mit ~70 Tabellen (siehe Abschnitt 3).
Tabellen in Test-DB (leocrm_test)
120 Tabellen vorhanden.
Tabellen NICHT in Test-DB (definiert in Models aber fehlend)
| Tabelle |
Model-Datei |
In DB? |
Mögliche Ursache |
ai_decision_records |
app/ai/oversight.py |
❌ Fehlt |
Model nicht in conftest importiert, keine Migration |
document_chunks |
unified_search/models.py |
❌ Fehlt |
Plugin-Model nicht geladen? |
forgejo_reported_errors |
forgejo_error_reporter/models.py |
❌ Fehlt |
Plugin-Model nicht geladen? |
plugin_allowlist |
app/models/plugin_allowlist.py |
❌ Fehlt |
Model nicht in conftest importiert |
unified_search_index_log |
unified_search/models.py |
❌ Fehlt |
Plugin-Model nicht geladen? |
unified_search_providers |
unified_search/models.py |
❌ Fehlt |
Plugin-Model nicht geladen? |
wiki_articles |
wiki/models.py |
❌ Fehlt |
Plugin-Model nicht geladen? |
wiki_article_versions |
wiki/models.py |
❌ Fehlt |
Plugin-Model nicht geladen? |
wiki_categories |
wiki/models.py |
❌ Fehlt |
Plugin-Model nicht geladen? |
9 Tabellen definiert aber nicht in Test-DB vorhanden.
9. MIGRATIONS (alembic/versions/)
- Anzahl Migrationen: 128
- Aktuelle Head-Revision:
0127
- Letzte Migrationen:
0127_drop_tasks_contact_id_fk.py (Aug 19, 2026)
0126_wiki_plugin.py (Aug 18, 2026)
0125_durable_workflow_run.py (Aug 18, 2026)
0124_unified_task_system.py (Aug 17, 2026)
0123_approval_requests.py (Aug 17, 2026)
10. VERBINDUNGS-MATRIX
Backend AI Module
| Modul |
Verbunden mit |
Status |
agent_loop.py |
llm_client, approval, hooks, audit, automation.agent_runner, agent_stream |
✅ Verbunden |
llm_client.py |
agent_loop, data_policy, ai_assistant, ai_proactive, unified_search, ai_copilot_service, action_mapper |
✅ Verbunden |
ai_use_case.py |
data_policy, automation.agent_routes |
✅ Verbunden |
skill_registry.py |
agent_tools, agent_permissions (nur intern) |
⚠️ Nur intern |
action_mapper.py |
llm_client (nur intern, lazy) |
⚠️ Nur intern |
agent_permissions.py |
— |
❌ Unverbunden |
agent_tools.py |
— |
❌ Unverbunden |
data_policy.py |
— |
❌ Unverbunden |
transparency.py |
— |
❌ Unverbunden |
oversight.py |
— |
❌ Unverbunden (Tabelle fehlt in DB) |
agent_memory.py |
— |
❌ Unverbunden (Duplikat mit Plugin) |
agent_stream.py |
agent_loop (importiert, aber niemand nutzt agent_stream) |
❌ Unverbunden |
context_builder.py |
sensitive_data, tenant, user, ai_assistant.contracts (importiert, aber niemand nutzt context_builder) |
❌ Unverbunden |
Workflow Module
| Modul |
Verbunden mit |
Status |
engine.py |
routes/workflows.py, core/event_bus.py, step_handlers, workflow_service, models.workflow, notifications, event_bus |
✅ Verbunden |
step_handlers.py |
engine.py (10 Handler registriert) |
✅ Verbunden |
decision_guard.py |
— |
❌ Unverbunden |
Approval System
| Komponente |
Verbunden mit |
Status |
core/approval.py |
routes/approvals.py, ai/agent_loop.py |
✅ Verbunden |
routes/approvals.py |
main.py (registriert), core/approval.py |
✅ Verbunden |
| Agent Loop ↔ Approval |
require_approval Parameter, create_approval_request() |
✅ Verbunden |
| Workflow Engine ↔ Approval |
step_type == "approval", resume_reason = "approval" |
✅ Verbunden |
| Automation Plugin ↔ Approval |
— |
❌ Nicht verbunden |
decision_guard.py ↔ Approval |
Referenziert konzeptionell, nicht integriert |
❌ Nicht verbunden |
Plugin ↔ AI/Workflow
| Plugin |
Importiert aus app.ai |
Importiert aus app.workflows |
Status |
ai_assistant |
llm_complete |
— |
✅ AI verbunden |
ai_proactive |
llm_complete |
— |
✅ AI verbunden |
automation |
run_react_loop, AIUseCaseMetadata |
— |
✅ AI verbunden, ❌ Workflows nicht verbunden |
unified_search |
llm_client, embedding, provider_compliance |
— |
✅ AI verbunden |
| Alle anderen Plugins |
— |
— |
❌ Weder AI noch Workflows |
Frontend ↔ Backend
| Frontend-Bereich |
API verbunden |
Status |
| Mail |
✅ @/api/mail (14 Importe) |
✅ Vollständig |
| Calendar |
✅ @/api/calendar (16 Importe) |
✅ Vollständig |
| DMS |
✅ @/api/dms (12 Importe) |
✅ Vollständig |
| Communication |
✅ @/api/comm, @/api/ai |
✅ Vollständig |
| Contacts |
✅ @/api/contacts, @/api/hooks |
✅ Vollständig |
| Tasks |
✅ @/api/tasks (5 Importe) |
✅ Vollständig |
| Tags |
✅ @/api/tags (8 Importe) |
✅ Vollständig |
| Wiki |
✅ Direkte API-Calls |
✅ Vollständig |
| Workflows |
✅ @/api/workflows (5 Importe) |
✅ Vollständig |
| Automation |
✅ @/api/automation (6 Importe) |
✅ Vollständig |
| Agents |
❌ 0 API-Refs in Agents.tsx |
❌ Nicht verbunden (aber AgentDashboard.tsx ist verbunden) |
| AI Settings |
✅ @/api/ai in AISettings.tsx |
✅ Verbunden |
| Settings System |
❌ 0 API-Refs in SettingsSystem.tsx |
❌ Nicht verbunden |
| Import/Export |
❌ 0 API-Refs in ImportExport.tsx |
❌ Nicht verbunden |
| Logs |
❌ 0 API-Refs |
❌ Nicht verbunden |
ZUSAMMENFASSUNG: Was funktioniert, was nicht
✅ Funktioniert und ist verbunden
- Core CRM (Contacts, Companies, Tags, Tasks, Calendar, Mail, DMS) — Vollständig verbunden Frontend→API→DB
- LLM Client — Zentraler AI-Client, von 5+ Plugins genutzt
- Agent Loop — ReAct-Loop mit Approval-Integration, von Automation-Plugin aufgerufen
- Workflow Engine — 13 Step-Typen, von Routes und Event-Bus aufgerufen
- Approval System — Mit Agent Loop und Workflow Engine verbunden, eigene API-Routes
- Plugin Contract System — 18 Contracts, aktiv von 7+ Plugins genutzt
- Permission System — ABAC/RBAC, Entity-Permissions, in Routes integriert
- Communication — WebSocket-basiertes Chat-System mit AI-Integration
- Unified Search — Hybrid-Suche mit Embeddings, Query-Understanding
- Audit/Tenant-Isolation — Cross-Tenant-Tests bestätigen Isolation
❌ Nicht verbunden / Muss verbunden werden
decision_guard.py — Guard existiert aber wird nie aufgerufen. Muss in engine.py vor High-Risk-Actions integriert werden.
context_builder.py — Agent-Context-Builder ungenutzt. Muss in agent_loop.py oder agent_runner.py integriert werden.
agent_tools.py — Tool-Execution-Logik ungenutzt. Muss mit agent_loop.py verbunden werden.
agent_permissions.py — Permission-Checks für Agent-Tools ungenutzt. Muss vor Tool-Execution aufgerufen werden.
data_policy.py — PII-Sanitization und Provider-Compliance ungenutzt. Muss vor LLM-Calls aufgerufen werden.
oversight.py — Decision-Records: Model existiert, keine Migration, keine Integration. Braucht beides.
transparency.py — AI-Content-Marking ungenutzt. Muss bei AI-generierten Inhalten aufgerufen werden.
agent_stream.py — Streaming ungenutzt. Sollte für AI-Streaming-Antworten genutzt werden.
agent_memory.py (AI-Modul) — Verwaist. Entweder mit agent_memory Plugin verbinden oder löschen.
- Automation ↔ Approval — Automation-Plugin nutzt Agent Loop aber gibt
require_approval nicht durch.
- Automation ↔ Workflows — Kein Plugin importiert aus
app.workflows. Automation sollte Workflow-Engine nutzen können.
- 9 Frontend Pages ohne API —
Agents.tsx, ImportExport.tsx, SettingsSystem.tsx, SettingsUserManagement.tsx, SettingsAI.tsx brauchen API-Anbindung.
- 9 unbenutzte API-Clients —
aiUIControl, attachments, auth, plugins, policies, policyHooks, roles, searchHooks — Verbinden oder löschen.
- 9 Tabellen fehlen in Test-DB —
ai_decision_records, document_chunks, forgejo_reported_errors, plugin_allowlist, unified_search_index_log, unified_search_providers, wiki_articles, wiki_article_versions, wiki_categories.
delegations.py Route geparkt — Permission-Delegation-Route nicht registriert (line 575 in main.py auskommentiert).
Ende der System-Audit