wiki/c-work/4-done/2026-04-gateway-duplicate-class-names.md
ValueOn AG 93edc94da3 upd
2026-04-10 22:44:27 +02:00

7.4 KiB
Raw Blame History

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:

  1. i18n-Kollision: @i18nModel registriert nach cls.__name__ in einem globalen Dict — bei gleichem Namen überschreibt der letzte Import den ersten.
  2. Lesbarkeit: Import-Aliase (from ... import TaskResult as WorkflowTaskResult) sind fragil und leicht vergessen.
  3. 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 aus datamodelChat
  • workflows/processing/modes/modeDynamic.py — importiert aus datamodelChat
  • workflows/processing/modes/modeAutomation.py — importiert aus datamodelChat + datamodelWorkflow (bereits as WorkflowTaskResult)
  • workflows/workflowManager.py — importiert aus datamodelWorkflow (bereits as WorkflowTaskResult)
  • workflows/processing/workflowProcessor.py — importiert aus datamodelWorkflow
  • tests/unit/datamodels/test_workflow_models.py — importiert aus datamodelWorkflow

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.pyNeutralizationTableData (oder _ParsedTableData). Wird nur modulintern verwendet.

Aufwand: Minimal (1 Datei).

4. Token in jsonContinuation.py → Umbenennen (Priorität: niedrig)

Lösung: TokenJsonToken (passend zu TokenTypeJsonTokenType). 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 TaskResultChatTaskResult / WorkflowTaskResult 8 30 min
2 Inline AiResponse_AiResponseFallback 1 10 min
3 TableDataNeutralizationTableData 1 5 min
4 TokenJsonToken 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
  • getModelAttributeDefinitions für betroffene Modelle prüfen (Labels eindeutig)