feat: workflow graph system — blocks 1-20 complete checkpoint

Full graph-based workflow execution engine with:
- WorkflowGraphRuntime with two-phase dispatch (collect → fire Celery tasks)
- Node registry with contract validation, socket types, execution kinds
- WorkflowRuntimeServices: preflight, context resolution, shadow-mode A/B
- WorkflowRouter: CRUD + dispatch/preflight/run-history API endpoints
- OutputTypeContracts: workflow binding, rollout-mode resolution
- Admin router: output-type workflow binding endpoints
- Frontend: complete workflow editor with drag-drop canvas, node inspector,
  module bundles, reference bundles, preflight panel, validation banner,
  authoring guidance, blueprint templates, shadow/rollout gate UI
- Tests: comprehensive coverage for all workflow modules
- Docs: NODE_CONTRACT_AUDIT and VALIDATION_ERROR_INVENTORY

All 20 blocks from NEXT_20_BLOCK_BATCH_PLAN completed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 19:09:54 +02:00
co-authored by Claude Sonnet 4.6
parent c51dd8cd67
commit d2e4934cca
63 changed files with 7035 additions and 2140 deletions
@@ -0,0 +1,244 @@
# Workflow Node Contract Audit
Stand: April 12, 2026
## Scope
Geprüft wurden:
- [`backend/app/domains/rendering/workflow_node_registry.py`](/home/hartmut/Documents/Copilot/schaefflerautomat/backend/app/domains/rendering/workflow_node_registry.py)
- [`backend/app/domains/rendering/workflow_schema.py`](/home/hartmut/Documents/Copilot/schaefflerautomat/backend/app/domains/rendering/workflow_schema.py)
- [`backend/app/domains/rendering/workflow_graph_runtime.py`](/home/hartmut/Documents/Copilot/schaefflerautomat/backend/app/domains/rendering/workflow_graph_runtime.py)
- [`frontend/src/components/workflows/workflowNodeContracts.ts`](/home/hartmut/Documents/Copilot/schaefflerautomat/frontend/src/components/workflows/workflowNodeContracts.ts)
- [`frontend/src/components/workflows/WorkflowNodeInspector.tsx`](/home/hartmut/Documents/Copilot/schaefflerautomat/frontend/src/components/workflows/WorkflowNodeInspector.tsx)
- [`frontend/src/components/workflows/workflowGraphDraft.ts`](/home/hartmut/Documents/Copilot/schaefflerautomat/frontend/src/components/workflows/workflowGraphDraft.ts)
## Findings
### 1. Root-context inputs were modeled like normal upstream sockets
Betroffen:
- `resolve_step_path` mit `cad_file_record`
- `order_line_setup` mit `order_line_record`
Root cause:
- Das Backend seedingt diese Eingänge implizit aus dem Workflow-Kontext.
- Der Editor behandelte sie trotzdem als normale Canvas-Ports.
Folge:
- Entry-Nodes sahen aus, als müssten sie zusätzlich verkabelt werden.
- Das erzeugte genau die Art von unklaren Input-Anforderungen, die im aktuellen Workflow-Editor stören.
Maßnahme:
- Root-context inputs werden im Frontend separat als Kontextanforderung modelliert.
- Sie werden nicht mehr als normale verkabelbare Upstream-Sockets dargestellt.
### 2. Node authoring semantics were implicit instead of explicit
Root cause:
- Der Editor wusste bislang zwar, welche Felder und Ports existieren, aber nicht, welches Authoring-Muster eine Node eigentlich hat.
Folge:
- `0 inspector vars` oder `1 input socket` war im UI technisch korrekt, aber semantisch oft unverständlich.
Maßnahme:
- Nodes werden jetzt explizit als `Context Entry`, `Connection-Driven`, `Inspector-Driven` oder `Hybrid` beschrieben.
### 3. Registry coverage is broad, but some nodes are intentionally connection-only
Nodes mit `0` Inspector-Feldern:
- `resolve_step_path`
- `occ_object_extract`
- `occ_glb_export`
- `thumbnail_save`
- `order_line_setup`
- `stl_cache_generate`
Bewertung:
- Das ist nicht automatisch ein Defekt.
- Diese Nodes brauchen vor allem klare Authoring-Erklärung und keine künstlichen Dummy-Einstellungen.
### 4. Render/runtime parameter alignment is already strong for core render nodes
Der bestehende Testpfad deckt insbesondere für `blender_still` und `blender_turntable` bereits ab, dass deklarierte Felder von der Runtime unterstützt werden.
Nächste Lücke:
- systematische Prüfung der restlichen Bridge-/Output-Nodes gegen Runtime-Parameter und Template-Inputs
## Current Batch Outcome
Batch A konzentriert sich zuerst auf:
1. sichtbaren 20-Block-Plan
2. Audit-Dokumentation
3. saubere Trennung von Root-Kontext und Upstream-Wiring
4. explizite Authoring-Semantik im Editor
## Block 5 Inventory: Implicit Requirement Nodes
### A. Korrekt feldlose Nodes, die nur bessere Authoring-Semantik brauchten
- `resolve_step_path`
- echter `Context Entry`
- braucht nur `cad_file_record` aus dem Workflow-Kontext
- keine zusätzlichen Inspector-Variablen sinnvoll
- `order_line_setup`
- echter `Context Entry`
- braucht nur `order_line_record` aus dem Workflow-Kontext
- liefert den Großteil des Order-Line-Arbeitskontexts
- `occ_object_extract`
- reine `Connection-Driven` Node
- braucht nur `step_path`
- keine zusätzlichen lokalen Einstellungen in der Runtime vorhanden
- `occ_glb_export`
- reine `Connection-Driven` Node
- braucht nur `step_path`
- Registry beschreibt bereits korrekt, dass per-Node-Tessellation-Overrides noch nicht existieren
- `thumbnail_save`
- reine `Connection-Driven` Node
- braucht nur `rendered_image`
- Verhalten kommt aus dem angeschlossenen Thumbnail-Request, nicht aus lokalen Feldern
- `stl_cache_generate`
- reine `Connection-Driven` Kompatibilitäts-Node
- kein echter Produktionsschritt im HartOMat-Graph
- Runtime ist bewusst ein `compatibility_noop`
### B. Nodes ohne große Feldoberfläche, aber mit wichtiger Laufzeitsemantik
- `output_save`
- hat nur wenige lokale Felder, aber relevante Handoff-Semantik
- Verhalten hängt von angeschlossenen Render-Artefakten, Shadow/Graph-Mode und Publish-Handoff ab
- UI muss klarer kommunizieren, wann diese Node `pending`, `completed` oder `failed` wird
- `notify`
- hat nur minimale lokale Konfiguration, ist aber stark vom bewaffneten Render-Handoff abhängig
- in `shadow` wird die Node bewusst unterdrückt
- braucht vor allem bessere Preflight-/Inspector-Erklärung, nicht mehr Freitextfelder
- `export_blend`
- aktuell nur ein bewusst schmaler Bridge-Export
- nur Dateinamensuffix ist pro Workflow authorbar
- größere Feldoberfläche wäre aktuell Fake-Konfiguration ohne Runtime-Nutzen
### C. Nodes mit dynamischen statt statischen Inputs
- `resolve_template`
- statische Inspector-Felder sind vorhanden
- zusätzliche Inputs entstehen dynamisch über `workflow_input_schema`
- das ist keine 0-Felder-Node, aber eine wichtige Ursache für Verwirrung, wenn Template-Inputs im Editor nicht klar sichtbar werden
### D. Bewertung
- Für Batch A/B ist die Hauptlücke nicht "mehr Felder um jeden Preis".
- Die Hauptlücke ist:
- Root-Kontext korrekt modellieren
- Connection-vs-Inspector-Semantik explizit machen
- Handoff-/Template-/Shadow-Semantik sichtbarer machen
- Echte neue Eingabevariablen werden erst dort ergänzt, wo Runtime und Template-System sie tatsächlich unterstützen.
## Finding 5: `notify` had a real frontend/backend contract drift
Betroffen:
- Frontend-Authoring erlaubte `export_blend -> notify`
- Backend-Schema ließ `notify` bislang nicht auf `blend_asset` reagieren
Root cause:
- Frontend ergänzte `blend_asset` als alternatives `requires_any`
- Backend-Registry führte für `notify` nur Render-Artefakte und `workflow_result`
Folge:
- derselbe Graph konnte im Editor plausibel aussehen, aber beim Backend-Schema scheitern
- besonders Blend-Export-Workflows waren dadurch inkonsistent authorbar
Maßnahme:
- `notify.input_contract.requires_any` enthält jetzt auch `blend_asset`
- Registry führt `blend_asset` auch als konsumiertes Artefakt
- Schema- und Executor-Tests decken `export_blend -> notify` jetzt explizit ab
## Finding 6: Bridge-node runtime params need explicit anti-drift guards
Betroffen:
- `resolve_template`
- `material_map_resolve`
- `auto_populate_materials`
- `glb_bbox`
- `output_save`
- `notify`
Root cause:
- Core-Render-Nodes waren bereits per Runtime-Key-Tests abgesichert.
- Bridge-Nodes hatten zwar Registry-Felder, aber keinen zentralen Runtime-Param-Contract gegen Drift.
Folge:
- zukünftige Änderungen in Runtime oder Registry könnten still auseinanderlaufen
- besonders gefährlich für Inspector-Felder, die klein wirken, aber produktionskritische Handoff-Semantik steuern
Maßnahme:
- Runtime-Key-Sets für die Bridge-Nodes wurden in `workflow_graph_runtime.py` zentralisiert
- Registry-Tests prüfen diese Nodes jetzt 1:1 gegen die Runtime
Ergebnis:
- Block 6 ist auf Contract-Ebene abgeschlossen
- weitere Batch-B-Arbeit kann sich jetzt auf Template-/Output-Semantik statt auf Grundsatzdrift konzentrieren
## Finding 7: Template workflow inputs were only fully visible after forcing a concrete template override
Betroffen:
- `resolve_template` im Workflow-Inspector
Root cause:
- Template-definierte Produktionsvariablen kamen technisch aus `workflow_input_schema`, wurden im Editor aber primär erst nach Auswahl eines festen Template-Overrides sichtbar.
- Damit blieb ein Teil des realen Authoring-Vertrags für automatische Template-Auflösung zu implizit.
Folge:
- Autoren konnten schwer erkennen, welche Workflow-Variablen aktive Templates grundsätzlich bereits verlangen oder anbieten.
- Das machte Template-First-Graphen unnötig intransparent, obwohl die Runtime die Inputs bereits unterstützt.
Maßnahme:
- der Inspector zeigt jetzt zusätzlich eine automatische Abdeckungsansicht über aktive Templates mit Workflow-Inputs
- potenzielle Template-Variablen werden vor Auswahl eines festen Overrides als reale Produktionsvariablen sichtbar
- gezielte Frontend-Tests prüfen sowohl explizite Override-Inputs als auch die automatische Coverage
## Finding 8: Render override fields could be edited although runtime discarded them
Betroffen:
- `blender_still`
- `blender_turntable`
Root cause:
- der Inspector behandelte mehrere renderautoritative Felder wie normale Node-Variablen
- die Runtime verwirft diese Werte jedoch bewusst, solange `use_custom_render_settings` deaktiviert bleibt und Output Type bzw. Template autoritativ sind
Folge:
- Autoren konnten Konfigurationen eingeben, die im Lauf keine Wirkung hatten
- das war eine echte Contract-Lücke zwischen UI und Runtime, nicht nur eine Darstellungsfrage
Maßnahme:
- renderautoritative Felder werden nun gesperrt, bis `use_custom_render_settings` aktiviert ist
- `output_save` und `notify` dokumentieren zusätzlich ihre Handoff-Semantik im Inspector explizit, um Shadow-/Graph-/Legacy-Verhalten klarer zu machen
- fokussierte Frontend- und Backend-Tests sichern diese Contract-Regeln gegen Regressions ab