# Trustee Workflow-Audit (A1) & Generischer Workflow-Run-Workspace (A2) ## Beschreibung und Kontext Der User klickt im Trustee-Dashboard Service-Karten an (Budget-Vergleich, KPI-Dashboard, Cashflow, Forecast, Jahresabschluss-Pruefung) und landet auf Tabs in `TrusteeAnalyseView` / `TrusteeAbschlussView`, wo der jeweilige Workflow gestartet wird. Zwei Themen: - **A1 Audit:** Sind diese Workflows wirklich auf dem aktuellen Pick-not-Push / Typed-Action-Stack? -- **JA, alle GREEN** (siehe Befund unten). Hier wird nur dokumentiert. - **A2 Result-Sichtbarkeit:** Wenn der User waehrend des Runs die Seite wechselt, ist das Resultat (KI-Antwort + generierte Files) anschliessend weg -- es lebt nur im React-State der Source-View. Persistenz existiert zwar in `AutoRun`/`AutoStepLog`, ist aber nirgends als User-UI erschlossen. **Geschaeftstreiber:** UX-Bruch ("ich war kurz auf einer anderen Seite, jetzt ist mein Report weg") + fehlende Single-Source-of-Truth fuer Workflow- Outputs. Plus: User-Anforderung, dass jeder Workflow eine `FeatureInstance` referenziert (auch bei Scheduled-Runs), damit Datenquellen im Editor sauber gefiltert werden koennen. ## Fokus und kritische Details - `POST /api/workflows/{instanceId}/execute` ist heute **synchron** -- der Browser blockiert auf dem Request bis Ende. Der "Workspace" muss diesen Request nicht aendern, er muss nur die persistierten `AutoRun`-Daten verlinkbar/auffindbar machen. - `Workflow.featureInstanceId` ist heute optional (zumindest historisch). Pflicht-Binding ist breakend fuer existierende Workflows ohne Instanz -- Migration noetig. - Scheduler-Pfad muss die Pflicht-Binding **respektieren**, sonst laufen Cron-Workflows ohne Daten-Scope. - Tab-Position: User wuenscht den Workspace explizit unter `/automations` (Seite "Nutzung > Automation") als zusaetzlichen Tab neben Dashboard + Workflows. ## Ziel und Nicht-Ziele - Ziel A1: Audit-Befund GREEN dokumentiert (Wiki-Update). - Ziel A2: Generische Workflow-Run-Workspace-View; jeder Workflow hat Pflicht-FeatureInstance-Binding; Trustee-Views zeigen Resultate ueber Workspace statt eigenem React-State. - NICHT: Async-Umstellung des Execute-Endpoints (eigener Plan, falls noetig). - NICHT: Browser-Push-Notification (User wollte nur Workspace). - NICHT: Aenderung der Workflow-Engine-Logik selbst. ## Betroffene Module - Gateway: - `gateway/modules/features/graphicalEditor/datamodelFeatureGraphicalEditor.py` (`Workflow.featureInstanceId` Pflicht). - `gateway/modules/features/graphicalEditor/routeFeatureGraphicalEditor.py` (Save-Validation, neue Aggregat-Routen unter `/api/automations/runs/...`). - `gateway/modules/features/graphicalEditor/mainScheduler.py` (Schedule- Erstellung uebernimmt Instanz aus Workflow). - `gateway/modules/features/trustee/mainTrustee.py` (Audit-Notiz, sicherstellen dass Templates `featureInstanceId` setzen). - Frontend: - Neuer Tab in `frontend_nyla/src/pages/AutomationsDashboardPage.tsx`. - Neue Komponenten `WorkflowRunWorkspaceView`, `WorkflowRunDetailView`. - FlowEditor-Toolbar bekommt Pflicht-Selector "Feature-Instanz". - `frontend_nyla/src/pages/views/trustee/TrusteeAnalyseView.tsx` und `TrusteeAbschlussView.tsx` schlanker (Verlinkung in den Workspace statt eigene Result-Anzeige; Run-State nicht mehr verloren bei Tab- Wechsel weil Persistenz uebernimmt). - DB-Migration: ja -- Bestand-Workflows ohne `featureInstanceId` brauchen ein Migrations-Skript (interaktiv). - RBAC: Zugriff auf `/automations/workspace` -- prueft pro Run die Mandate/FeatureInstance-Rechte des Users. ## Befund A1 (Audit) -- bereits GREEN | Service | Workflow-ID | Backend-Definition | Status | Beleg | |---------|-------------|---------------------|--------|-------| | Budget-Vergleich | `trustee-budget-comparison` | `mainTrustee.py` 430-461 | GREEN | DataRef Trigger-Payload + Refresh-Output, modern | | KPI-Dashboard | `trustee-kpi-dashboard` | `mainTrustee.py` 463-478 | GREEN | `_buildAnalysisWorkflowGraph` 364-381 | | Cashflow-Rechnung | `trustee-cashflow` | `mainTrustee.py` 480-492 | GREEN | dito | | Prognose | `trustee-forecast` | `mainTrustee.py` 494-507 | GREEN | dito | | Jahresabschluss-Pruefung | `trustee-year-end-check` | `mainTrustee.py` 509-522 | GREEN | dito | Engine-Pipeline: `executeGraph` ruft `materializeFeatureInstanceRefs` + `validateGraph` vor jedem Lauf auf (`gateway/modules/features/graphicalEditor/executionEngine.py` 341-350). Persistierte Graphs nutzen zunaechst nackte UUID fuer `featureInstanceId` (Bootstrap `interfaceFeatures.py` 336-338), Laufzeit-Envelope erfolgt in `executeGraph`. ## Entscheidungen | Datum | Entscheidung | Begruendung | |-------|-------------|------------| | 2026-04-29 | Workspace ist GENERISCH plattformweit, nicht Trustee-spezifisch | Doppelt-Bauen vermeiden; ComCoach/TeamsBot/Workspace profitieren auch | | 2026-04-29 | Workspace lebt unter `/automations` als Tab "Workspace" | User-Vorgabe; Nutzungspfad "Nutzung > Automation > Workspace" | | 2026-04-29 | Workflow-Speicherung verlangt `featureInstanceId` | Datenquellen-Tools im Editor sind nur dann sinnvoll filterbar | | 2026-04-29 | Bestehende Workflows ohne Instanz: interaktives Migrations-Skript pro Mandate | Kein automatischer Default -- der User soll bewusst zuordnen | | 2026-04-29 | Browser-Push-Notification NICHT umgesetzt | User hat nur Workspace gewaehlt; Toast bei Run-Ende reicht | ## Umsetzungs-Checkliste ### Phase 1 -- FeatureInstance-Pflicht-Binding - [ ] Backend: `Workflow.featureInstanceId NOT NULL` (Pydantic + DB-Constraint via Connector-Auto-Init). - [ ] Save-Validation in `routeFeatureGraphicalEditor.py`: Workflow ohne `featureInstanceId` -> 400 mit Error-Detail "Feature-Instanz fehlt". Save-with-errors (AC-9 vom Typed-Action-Plan) bleibt erlaubt -- nur Run-Start blockt. - [ ] Run-Start (`POST .../execute`): Vorab-Check, dass Workflow eine Instanz hat. - [ ] Migrations-Skript `gateway/scripts/script_db_migrate_workflow_feature_instance.py`: listet pro Mandate alle Workflows ohne Instanz, bietet pro Workflow eine Auswahl (CLI prompt). - [ ] Scheduler: Schedule-Erstellung uebernimmt Instanz aus Workflow, Override nicht moeglich. - [ ] FlowEditor-Toolbar: Pflicht-Dropdown "Feature-Instanz" oben links. Datenquellen-Tools (z.B. UDB-Listen, FileItems, SourcesTab) filtern automatisch auf diese Instanz. - [ ] Trustee-Templates pruefen: alle Workflows haben in `mainTrustee.py` bereits `featureInstanceId` als `{{featureInstanceId}}`-Placeholder, der beim `_copyTemplateWorkflows` ersetzt wird (`interfaceFeatures.py` 269-338) -- nur sicherstellen dass jetzt nichts haengen bleibt. ### Phase 2 -- Generischer WorkflowRunWorkspace - [ ] Neue Aggregat-API: `GET /api/automations/runs?scope=mine|mandate|all&status=...&limit=...` und `GET /api/automations/runs/{runId}/detail`. Detail-Payload kombiniert AutoRun + AutoStepLog + Outputs + verlinkte FileItems (joined mit RBAC-Filter). - [ ] Tab "Workspace" in `frontend_nyla/src/pages/AutomationsDashboardPage.tsx` (neben Dashboard, Workflows). - [ ] Komponente `WorkflowRunWorkspaceView`: Liste mit Filter (Status, Workflow-Template, Mandate, Zeitraum), 50-er Pagination. - [ ] Komponente `WorkflowRunDetailView`: Chat-aehnliche Ansicht - Header: Workflow-Name, Status, Start/Ende, FeatureInstance. - Eingabe-Bubble: Trigger-Payload (formatiert). - Step-Bubbles: chronologisch, pro Step-Output kollabierbar. - Final-Bubble: KI-Antwort als Markdown. - Documents-Sektion: alle generierten FileItems als Karten mit Direkt-Download (`a href="/api/files/{id}/download"`). - [ ] Trustee-Views umbauen: - `TrusteeAnalyseView`: Result-Anzeige raus (`resultText` / `resultDocuments` State), stattdessen "Im Workspace ansehen"- Button mit `runId`. - `TrusteeAbschlussView`: dasselbe (heute zeigt der gar nichts). ### Phase 3 -- Notifications - [ ] Toast bei Run-Ende ist heute schon da -- erweitern um Klick-Action zum Detail-View des Runs. - [ ] Sidebar-Badge auf Eintrag "Automation" (Counter "neu seit letztem Besuch", `localStorage`-basiert). ## Akzeptanzkriterien | # | Kriterium (Given-When-Then) | Prio | |---|-----------------------------|------| | 1 | Given Workflow ohne Instanz, When User Save klickt, Then 400 mit klarer Error-Message | must | | 2 | Given Bestand-Workflow ohne Instanz, When Migrations-Skript laeuft, Then User waehlt interaktiv pro Workflow eine Instanz und das Feld wird gesetzt | must | | 3 | Given Trustee-Run gestartet, When User waehrend Lauf die Seite wechselt und zurueck zum Tab "Workspace" geht, Then Run mit allen Outputs sichtbar | must | | 4 | Given Run mit generiertem File, When User auf Document-Karte klickt, Then File wird direkt heruntergeladen | must | | 5 | Given Run-Ende, When Toast erscheint, Then Klick fuehrt direkt zum WorkflowRunDetailView | should | | 6 | Given neue Runs seit letztem Besuch, When User die Sidebar sieht, Then "Automation" hat einen Counter-Badge | should | | 7 | Given FlowEditor offen ohne Instanz-Auswahl, When User Datenquellen-Tool oeffnen will, Then Hinweis "Bitte Feature-Instanz waehlen" | should | ## Testplan | ID | AC | Art | Automatisiert | Repo-Pfad | Status | |----|----|-----|--------------|-----------|--------| | T1 | 1 | api | ja | gateway/tests/features/graphicalEditor/test_workflow_save_requires_instance.py | pending | | T2 | 2 | manual | nein | gateway/scripts/script_db_migrate_workflow_feature_instance.py | pending | | T3 | 3 | e2e | ja | frontend_nyla/tests/e2e/workflow-run-workspace.spec.ts | pending | | T4 | 4 | e2e | ja | wie T3 | pending | | T5 | 5 | manual | nein | -- | pending | | T6 | 6 | unit | ja | frontend_nyla/src/pages/__tests__/AutomationsDashboardPage.test.tsx | pending | | T7 | 7 | unit | ja | frontend_nyla/src/components/flowEditor/__tests__/Toolbar.test.tsx | pending | ## Links - Audit-Quelle: Subagent-Report 2026-04-29. - Wiki: `wiki/b-reference/gateway/workflow.md`, `wiki/b-reference/gateway/features/trustee.md`, `wiki/c-work/4-done/2026-04-typed-action-architecture.md`, `wiki/c-work/4-done/2026-04-automation-central-admin.md`. ## Abschluss - [ ] `wiki/b-reference/gateway/workflow.md` Abschnitt "Workflow-Run-Workspace" anlegen - [ ] `wiki/b-reference/gateway/features/trustee.md` Result-UX-Sektion aktualisieren - [ ] `wiki/TOPICS.md` ggf. Tab-Beschreibung - [ ] Dieses Dokument -> `z-archive/` verschoben