wiki/c-work/4-done/2026-04-feature-instance-ref-adapter-migration.md
ValueOn AG 24190f532a fixes
2026-04-26 08:36:33 +02:00

9.9 KiB

FeatureInstanceRef-Adapter-Migration & Graph-Editor UI-Cleanup (2026-04-25)

Restbestand aus dem Node-Typisierungs-Audit (jetzt z-archiv). Ziel: keine frontendType: "hidden" Pflichtfelder mehr, klare UI-Texte, theme-konformer DataPicker, optionale Schema-Ansicht fur Sysadmins.

Auslosender Befund

Bei der Audit-Umsetzung wurde die strukturelle Korrektur (PORT_TYPE_CATALOG / Typed Action Architecture) durchgezogen — die Anwendung in den nodeDefinitions/*.py jedoch nur teilweise. Trustee + Redmine fuhren weiter featureInstanceId: string, hidden, required=True, was im Editor zu Phantom-Pflichtfeldern ("Pflichtfelder ohne Quelle: Trustee Feature- Instanz-ID"), unklarer Fehler-Banner und einem nicht-bedienbaren Knoten fuhrt.

Zusatzlich zeigte der Screenshot 2026-04-25 zwei UI-Probleme die unabhangig mitgenommen werden:

  • DataPicker-Modal mit nicht lesbaren Farb-Kombinationen
  • "Schema (Typ-Referenz)" und ausschweifende description-Texte (erarbeitete Dokumentenliste eines Upstream-Producers …) in der End-User-View

Anpassungs-Liste (zum Abhaken)

A. Audit archiviert

  • wiki/c-work/1-plan/2026-04-node-typization-audit.md -> wiki/z-archive/c-work/2026-04-node-typization-audit.md
  • Forward-Link auf Typed Action Architecture + dieses Track-Doc
  • Changelog-Eintrag

B. Backend — featureInstanceId typisieren

B1. Neuer Frontend-Type + Endpoint

  • routeFeatureGraphicalEditor.py: neuer Endpoint GET /api/workflows/{instanceId}/options/feature.instance?featureCode=<code>&enabledOnly=true
    • Antwort: { options: [{ value: "<id>", label: "<label> ([code])" }] }
    • Auflosung uber getRootInterface().getFeatureInstancesByMandate(mandateId, enabledOnly=True)
    • Filter featureCode Pflicht (sonst 400, sonst Datenflut)
  • _LEGACY_RENDERERS_THAT_HANDLE_BINDINGS (NodeConfigPanel.tsx) erweitert: 'featureInstance'

B2. Trustee-Nodes (5 Stuck) — gateway/.../nodeDefinitions/trustee.py

Node aktuell neu
trustee.refreshAccountingData featureInstanceId: string, hidden, required featureInstanceId: FeatureInstanceRef[trustee], frontendType: featureInstance, frontendOptions: {featureCode: trustee}
trustee.extractFromFiles dito dito
trustee.processDocuments dito; documentList description aufraumen (Dev-Justifikation) dito + description = t("Dokumentenliste — gebunden via DataRef.")
trustee.syncToAccounting dito; documentList ebenfalls dito
trustee.queryData dito dito

Alle 5 Nodes umgesetzt via wiederverwendbarem _TRUSTEE_INSTANCE_PARAM-Dict (siehe trustee.py). Bestaetigt durch tests/unit/graphicalEditor/test_featureInstanceRef_node_definitions.py.

B3. Redmine-Nodes (6 Stuck) — gateway/.../nodeDefinitions/redmine.py

  • redmine.readTicket
  • redmine.listTickets
  • redmine.createTicket
  • redmine.updateTicket
  • redmine.getStats
  • redmine.runSync

Alle 6 via _REDMINE_INSTANCE_PARAM-Dict, featureInstanceId -> FeatureInstanceRef[redmine] mit frontendType: "featureInstance", frontendOptions: {"featureCode": "redmine"}.

B4. Beobachtete frontendType: hidden-Restbestande (out-of-scope, in

2026-05 oder eigenem Track-Doc adressieren — hier nur dokumentiert)

Datei Param Typ aktuell Anmerkung
ai.py documentList string Korrekt: ueber dataRef gebunden, string lugt nur den DataPicker
email.py documentList, emailContent string dito
sharepoint.py content string dito
clickup.py content string dito
context.py documentList string dito
file.py context string dito

Diese Faelle sind nicht Phantom-Pflichtfelder (sie sind entweder optional oder werden korrekt via DataRef gebunden), losen aber die "Schema (Typ-Referenz)"-Verwirrung mit aus. Strukturell sind sie Kandidaten fur frontendType: "dataRef" mit prazisem type: "List[ActionDocument]" etc. — eigene Iteration.

C. Frontend — Renderer & Safety Net

  • FeatureInstancePicker.tsx (Modell: ConnectionPicker):
    • Lade /api/workflows/{instanceId}/options/feature.instance?featureCode=<code>
    • 0 Ergebnisse: Hinweis "Keine {code}-Instanz im aktiven Mandanten — bitte in der Admin-Konsole anlegen."
    • 1 Ergebnis: Auto-Pick (autoSingleRef-Guard)
    • N Ergebnisse: <select> mit Default-Option "{code}-Mandant wählen"
  • frontendTypeRenderers/index.tsx:
    • Import + Eintrag in FRONTEND_TYPE_RENDERERS: featureInstance: FeatureInstancePicker
    • Eintrag in _LEGACY_RENDERERS_THAT_HANDLE_BINDINGS (im NodeConfigPanel.tsx-Set)
  • Safety Net direkt in paramValidation.ts/findRequiredErrors: hidden-Pflicht-Parameter werden zentral gefiltert, damit Banner, FlowCanvas-Badges und Run-Button-blockedReason synchron bleiben. Zusatzlich _shouldUseRequiredPicker (NodeConfigPanel.tsx) liefert fruh false fur frontendType === 'hidden' und die Render-Schleife uberspringt die Zeile komplett (return null).

D. Editor-Verbose-Toggle (Issue 1)

  • CanvasHeader.tsx:
    • Sysadmin-Check via getUserDataCache()?.isSysAdmin === true
    • Checkbox "Schema-Details" rechts neben Workspace-Button, nur wenn Sysadmin (gestrichelter Rahmen, Tooltip mit Erklaerung)
    • Wert in localStorage('flowEditor.verboseSchema')
  • Automation2FlowEditor.tsx: verboseSchema state + persist-effekt, als Prop runtergereicht an CanvasHeader und NodeConfigPanel
  • NodeConfigPanel.tsx: <details>-Block "Schema (Typ-Referenz, Sysadmin- Ansicht)" und Parameter-Typ-Badges nur, wenn verboseSchema === true. PortField-Liste + Header-Spans zusatzlich auf CSS-Variablen umgestellt.

E. DataPicker-Theming (Issue 3)

  • DataPicker.tsx: alle hardcoded Farben (#555, #888, #999, #666) -> CSS-Variablen (var(--text-secondary), var(--text-tertiary), var(--bg-secondary), var(--border-color))
  • Inline-Tags (expectedParamType-Badge, "Nur kompatible"-Label, Schema-Hint, Type-Hint hinter Leaves) auf CSS-Klassen dataPickerLeafType, dataPickerNodeSchemaHint umgezogen
  • Automation2FlowEditor.module.css:
    • Hover-Safety-Net .dataPickerLeaf:hover * { color: inherit; } — keine grauen Type-Hints mehr auf blauem Hover-Hintergrund
    • Neue .dataPickerLeafType, .dataPickerNodeSchemaHint, .dataPickerIterateBtn mit theme-konformen Variablen

F. Banner-Klartext (Issue 4)

  • NodeConfigPanel.tsx: Banner "Pflichtfelder ohne Quelle" zeigt jetzt param.name (kurze Maschinenkennung), die volle Beschreibung hangt als mehrzeiliger title=-Tooltip am Banner
  • RequiredAttributePicker.tsx: nutzt getLabel(param.description) bereits korrekt; Justifikationen (erarbeitete Dokumentenliste …) sind fortan nur noch eine Datenfrage in den nodeDefinitions und betreffen diesen Banner nicht mehr (description-Saeuberung in B2/B3 erledigt)

G. Tests

  • gateway/tests/unit/graphicalEditor/test_featureInstanceRef_node_definitions.py: parametrized fuer alle Trustee+Redmine-Nodes — Typ ist FeatureInstanceRef[<code>], frontendType featureInstance, frontendOptions.featureCode korrekt; plus Regression-Guard gegen Re-Einfuehrung der string + hidden-Form (13 Testfaelle)
  • gateway/tests/unit/graphicalEditor/test_route_options_feature_instance.py: Smoke-Test, dass der Endpoint GET /api/workflows/{instanceId}/options/feature.instance registriert ist und featureCode Pflicht ist (2 Testfaelle)
  • frontend_nyla/.../paramValidation.test.ts: neuer Fall "skips required params with frontendType='hidden' (UI safety net)"
  • (Optional, Folge-Iteration) FeatureInstancePicker.test.tsx mit msw fur 0/1/N-Antworten; aktuell durch das Renderer-Pattern abgedeckt (ConnectionPicker hat dasselbe Modell, dort existieren Smoke-Tests)

H. Wrap-up

  • Track-Doc nach c-work/4-done/ verschieben
  • Eintrag in c-work/_CHANGELOG.md
  • (Folge-Aufgabe) b-reference/gateway/workflow.md um Abschnitt "FeatureInstanceRef adapter binding" erweitern; eigenes Mini-Track oder bei naechster Workflow-Doku-Iteration mitnehmen