7.4 KiB
Gateway: Doppelte Klassennamen bereinigen
Beschreibung und Kontext
Beim Aufräumen der @i18nModel-Migration (Phase 2) wurde festgestellt, dass mehrere Python-Klassen im Gateway denselben Namen tragen, obwohl sie in verschiedenen Modulen leben. Das ist problematisch, weil:
- i18n-Kollision:
@i18nModelregistriert nachcls.__name__in einem globalen Dict — bei gleichem Namen überschreibt der letzte Import den ersten. - Lesbarkeit: Import-Aliase (
from ... import TaskResult as WorkflowTaskResult) sind fragil und leicht vergessen. - Tooling: IDE-Suche, Debugging-Stacktraces und
getModelClasses()liefern mehrdeutige Treffer.
Business-Treiber: Saubere Klassennamen verhindern stille Label-Fehler in der UI und reduzieren Wartungsaufwand bei zukünftigen Erweiterungen.
Vollständige Liste der Duplikate
Ermittelt per AST-Scan über gateway/modules/ (nur Klassen, die in mehr als einer Datei vorkommen):
Kritisch: Pydantic-Modelle mit @i18nModel (i18n-Dict-Kollision)
| Klassenname | Datei 1 | Datei 2 | Beschreibung |
|---|---|---|---|
TaskResult |
datamodels/datamodelChat.py |
datamodels/datamodelWorkflow.py |
Chat: Aufgabenergebnis mit Status/Feedback. Workflow: Minimales Ergebnis mit actionResult. Beide haben @i18nModel("Aufgaben-Ergebnis"). |
RequestContext |
datamodels/datamodelWorkflow.py (Pydantic BaseModel) |
auth/authentication.py (plain class) |
Workflow: Normalisierter Benutzer-Input. Auth: Request-Kontext mit User/Mandate/Rollen. Kein i18n-Konflikt (Auth-Klasse ist kein Pydantic-Modell), aber Name ist irreführend. |
Mittel: Lokale Hilfsklassen (kein i18n, aber verwirrend)
| Klassenname | Datei 1 | Datei 2 | Beschreibung |
|---|---|---|---|
AiResponse |
datamodels/datamodelWorkflow.py (Pydantic) |
serviceAi/subStructureFilling.py (inline class in try/except, 4×) |
Workflow: Vollständiges AI-Antwort-Modell. StructureFiller: Minimaler Wrapper AiResponse(content) als Fallback bei Parse-Fehlern. |
TableData |
datamodels/datamodelDocument.py (Pydantic) |
neutralization/.../subProcessList.py (@dataclass) |
Document: Strukturierte Tabelle mit Headers/Rows/Caption. Neutralization: Einfache Tabelle mit source_type. |
Token |
datamodels/datamodelSecurity.py (Pydantic PowerOnModel) |
shared/jsonContinuation.py (@dataclass) |
Security: DB-Token (JWT, Refresh etc.). JsonContinuation: JSON-Parser-Token (internes Parsing). |
Niedrig: Architektur-Helfer (domänengetrennt, kaum Verwechslungsgefahr)
| Klassenname | Dateien | Beschreibung |
|---|---|---|
ChatObjects |
features/chatbot/interfaceFeatureChatbot.py, interfaces/interfaceDbChat.py |
Identische Rolle (Chat-Objekt-Container), ggf. zusammenführbar. |
ConnectionHelper |
workflows/methods/methodOutlook/helpers/connection.py, workflows/methods/methodSharepoint/helpers/connection.py |
Jeweils Outlook- bzw. SharePoint-spezifisch; Name ist generisch, aber Module sind klar getrennt. |
DocumentParsingHelper |
workflows/methods/methodJira/helpers/documentParsing.py, workflows/methods/methodSharepoint/helpers/documentParsing.py |
Jira- bzw. SharePoint-spezifisch; gleiche Situation wie ConnectionHelper. |
StructureGenerator |
serviceAi/subStructureGeneration.py, serviceGeneration/subStructureGenerator.py |
Zwei Services mit ähnlicher Aufgabe; ggf. Konsolidierung prüfen. |
_ResolverDbAdapter |
features/graphicalEditor/routeFeatureGraphicalEditor.py, features/workspace/routeFeatureWorkspace.py |
Interner Adapter (_-Prefix); lebt nur im jeweiligen Route-Modul. |
_ServicesAdapter |
4× in serviceCenter/services/*/main*.py |
Interner Adapter pro Service; bewusst gleichnamig, nie cross-importiert. |
Lösungsvorschlag
1. TaskResult → Umbenennung (Priorität: hoch)
Problem: Beide Klassen haben @i18nModel("Aufgaben-Ergebnis") — der letzte Import gewinnt im Label-Dict.
Lösung:
| Aktuell | Neu | Modul |
|---|---|---|
TaskResult in datamodelChat.py |
ChatTaskResult |
Chat-Domäne: Status, Feedback, Error |
TaskResult in datamodelWorkflow.py |
WorkflowTaskResult |
Workflow-Domäne: taskId + actionResult |
Betroffene Imports (5 Dateien):
workflows/processing/modes/modeBase.py— importiert ausdatamodelChatworkflows/processing/modes/modeDynamic.py— importiert ausdatamodelChatworkflows/processing/modes/modeAutomation.py— importiert ausdatamodelChat+datamodelWorkflow(bereitsas WorkflowTaskResult)workflows/workflowManager.py— importiert ausdatamodelWorkflow(bereitsas WorkflowTaskResult)workflows/processing/workflowProcessor.py— importiert ausdatamodelWorkflowtests/unit/datamodels/test_workflow_models.py— importiert ausdatamodelWorkflow
i18n-Labels anpassen:
ChatTaskResult:@i18nModel("Chat-Aufgabenergebnis")WorkflowTaskResult:@i18nModel("Workflow-Aufgabenergebnis")
Aufwand: Klein (6 Dateien, reine Umbenennung + Import-Anpassung).
2. AiResponse in subStructureFilling.py → Inline-Klasse eliminieren (Priorität: mittel)
Problem: 4× identische class AiResponse inline in try/except-Blöcken als Fallback-Wrapper.
Lösung: Eine private Klasse _AiResponseFallback am Modulanfang definieren, die 4 Inline-Definitionen ersetzen.
@dataclass
class _AiResponseFallback:
content: Any
Aufwand: Klein (1 Datei, 4 Stellen).
3. TableData in subProcessList.py → Umbenennen (Priorität: mittel)
Lösung: TableData in subProcessList.py → NeutralizationTableData (oder _ParsedTableData). Wird nur modulintern verwendet.
Aufwand: Minimal (1 Datei).
4. Token in jsonContinuation.py → Umbenennen (Priorität: niedrig)
Lösung: Token → JsonToken (passend zu TokenType → JsonTokenType). Wird nur modulintern verwendet.
Aufwand: Minimal (1 Datei, rein intern).
5. RequestContext — Kein Handlungsbedarf
Die Auth-RequestContext ist kein Pydantic-Modell und hat kein @i18nModel. Die Workflow-RequestContext ist ein Pydantic-Modell mit @i18nModel. Es gibt keine Import-Überschneidung (Auth wird nie aus datamodelWorkflow importiert und umgekehrt). Kein Refactoring nötig.
6. Niedrige Kategorie — Kein Handlungsbedarf
ChatObjects, ConnectionHelper, DocumentParsingHelper, StructureGenerator, _ResolverDbAdapter, _ServicesAdapter leben in klar getrennten Domänen und werden nie cross-importiert. Umbenennung wäre kosmetisch.
Umsetzungsreihenfolge
| Schritt | Was | Dateien | Aufwand |
|---|---|---|---|
| 1 | TaskResult → ChatTaskResult / WorkflowTaskResult |
8 | 30 min |
| 2 | Inline AiResponse → _AiResponseFallback |
1 | 10 min |
| 3 | TableData → NeutralizationTableData |
1 | 5 min |
| 4 | Token → JsonToken |
1 | 5 min |
Gesamtaufwand: ~50 min, kein Risiko für Laufzeitverhalten (reine Umbenennungen).
Validierung
python -c "import app"muss fehlerfrei durchlaufen- Bestehende Tests (
tests/unit/datamodels/test_workflow_models.py) anpassen und grün halten getModelAttributeDefinitionsfür betroffene Modelle prüfen (Labels eindeutig)