integrated and initial teste unified automation

This commit is contained in:
ValueOn AG 2026-04-07 22:31:57 +02:00
parent 7d1a957f77
commit 7f3170f324
10 changed files with 1270 additions and 178 deletions

View file

@ -1,6 +1,6 @@
<!-- status: canonical -->
<!-- lastReviewed: 2026-04-05 -->
<!-- verifiedAgainst: frontend_nyla (codebase audit 2026-04-05) -->
<!-- lastReviewed: 2026-04-07 -->
<!-- verifiedAgainst: frontend_nyla (codebase audit 2026-04-07, post Automation Unification) -->
# Frontend Nyla -- Architektur
@ -14,8 +14,8 @@ Technologie-Stack (Stand UI-Doku): React 19.x, Vite 5.x, TypeScript 5.8.x, React
| Ordner | Inhalt |
|--------|--------|
| `pages/` | Seiten: `admin/`, `basedata/`, `billing/`, `settings/`, `views/` (workspace, commcoach, chatbot, trustee, automation, automation2, realestate, neutralization, teamsbot) |
| `components/` | Wiederverwendbar: FormGenerator, FolderTree, Navigation, UnifiedDataBar, Automation2FlowEditor, OnboardingAssistant |
| `pages/` | Seiten: `admin/`, `basedata/`, `billing/`, `settings/`, `views/` (workspace, commcoach, chatbot, trustee, graphicalEditor, realestate, neutralization, teamsbot) |
| `components/` | Wiederverwendbar: FormGenerator, FolderTree, Navigation, UnifiedDataBar, FlowEditor (Graphical Editor), OnboardingAssistant |
| `hooks/` | useApiRequest (useApi.ts), useFiles, useNavigation, useConfirm, usePrompt, useResizablePanels, etc. |
| `contexts/` | FileContext, PekContext, ToastContext, WorkflowSelectionContext |
| `api/` | API-Client (`api.ts`) und Feature-spezifische API-Module |
@ -31,11 +31,16 @@ Ergänzend typische Root-Dateien und Bereiche im Repo: `main.tsx`, `App.tsx`, `a
| Komponente | Zweck |
|------------|-------|
| `UnifiedDataBar (UDB)` | Multi-Tab-Panel: Chats, Files, Sources — wird in Workspace und CommCoach genutzt |
| `UnifiedDataBar (UDB)` | Multi-Tab-Panel: Chats, Files, Sources — wird in Workspace, CommCoach und Graphical Editor genutzt |
| `FormGenerator` | Dynamische Formulare/Tabellen aus Backend-Attribut-Definitionen |
| `FolderTree` | Rekursiver Ordnerbaum mit Drag&Drop, Multi-Selection, Inline-Editing |
| `MandateNavigation` | Feature-Baum-Navigation mit Mandanten-Kontext |
| `Automation2FlowEditor` | n8n-style Flow-Builder für Automation2 |
| `Automation2FlowEditor` | Konsolidierter n8n-style Flow-Builder (Graphical Editor) mit 3-Column-Layout: [UDB + Chat/Tracing] [Canvas + Header] [Nodes] |
| `FlowCanvas` | Custom React Canvas fuer Workflow-Graph-Rendering mit Node-Highlighting (SSE Live-Tracing) |
| `RunTracingPanel` | Live-Tracing von Workflow-Runs via SSE mit Fallback-Polling |
| `EditorChatPanel` | AI Chat im Editor mit Drag&Drop-Dateianhang und Source-Picker |
| `CanvasHeader` | Workflow-Metadaten, Versioning (Draft/Publish/Archive), Save-as-Template, New-from-Template |
| `TemplatePicker` | Modal zur Auswahl von Workflow-Vorlagen beim Erstellen neuer Workflows |
| `WorkspacePage` | AI-Workspace mit Chat, UDB, Agent-Streaming |
## Routing
@ -64,6 +69,13 @@ Ergänzend typische Root-Dateien und Bereiche im Repo: `main.tsx`, `App.tsx`, `a
| `core/PageManager/` | State Preservation, Lifecycle, Caching |
| `auth/authConfig`, `authProvider`, `ProtectedRoute` | MSAL, geschützte Routen |
| `contexts/*` | FileContext, PekContext, Toast, Workflow-Auswahl, etc. |
| `components/FlowEditor/editor/Automation2FlowEditor.tsx` | Haupt-Editor-Komponente (3-Column-Layout, State-Management) |
| `components/FlowEditor/editor/FlowCanvas.tsx` | Custom Canvas mit Node-Rendering, Connections, Highlighting |
| `components/FlowEditor/editor/RunTracingPanel.tsx` | SSE Live-Push + Canvas-Highlighting fuer Workflow-Runs |
| `components/FlowEditor/editor/EditorChatPanel.tsx` | AI Chat mit Dateianhang (Drag&Drop) und Source-Picker |
| `components/FlowEditor/editor/CanvasHeader.tsx` | Versioning, Template-Management, Workflow-Aktionen |
| `components/FlowEditor/editor/TemplatePicker.tsx` | Template-Auswahl-Modal |
| `pages/views/graphicalEditor/GraphicalEditorPage.tsx` | Feature-Seite mit KeepAlive, URL-basiertem Workflow-Loading |
| `locales/*` | Übersetzungen (z. B. de / en / fr) |
## Regeln / Invarianten

View file

@ -1,6 +1,6 @@
<!-- status: canonical -->
<!-- lastReviewed: 2026-04-06 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-06, coreTools split) -->
<!-- lastReviewed: 2026-04-07 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-07, post Automation Unification) -->
# AI Agent & Knowledge Store
@ -45,6 +45,37 @@ Pro Request propagiert der **ServiceCenterContext** u. a. `userId`, `mandateId`,
| `toolSet` | Aktives Tool-Set (Default `"core"`) |
| `temperature` | Optional für den Agent-AI-Call |
### Toolbox Registry
**Datei:** `serviceCenter/services/serviceAgent/toolboxRegistry.py`
Statt alle Tools flach zu exponieren, gruppiert die **Toolbox Registry** Tools in thematische Toolboxes. Der Agent startet schlank und kann Spezial-Toolboxes zur Laufzeit nachfordern.
| Toolbox | Anzahl Tools | Default | Requires Connection |
|---------|-------------|---------|-------------------|
| `core` | 20 | Ja | -- |
| `ai` | 9 | Ja | -- |
| `datasources` | 8 | Ja | -- |
| `email` | 5 | Nein | `microsoft` |
| `sharepoint` | 3 | Nein | `microsoft` |
| `clickup` | 3 | Nein | `clickup` |
| `jira` | 3 | Nein | `jira` |
| `workflow` | 9 | Nein | -- (featureCode: graphicalEditor) |
| `trustee` | 1 | Nein | -- (featureCode: trustee) |
**Aktivierung (`_activateToolboxes` in `mainServiceAgent.py`):**
- Default-Toolboxes sind immer aktiv
- Connection-abhaengige Toolboxes werden aktiviert, wenn der User eine passende Connection hat
- Tools aus inaktiven Toolboxes werden aus der Registry entfernt
- `workflow`-Tools werden explizit via `workflowTools.getWorkflowToolDefinitions` registriert
**`requestToolbox` Meta-Tool:**
- Erlaubt dem Agent, zur Laufzeit inaktive Toolboxes anzufordern
- Schema: `{ toolboxId: enum[inactive IDs], reason: string }`
- Handler in `mainServiceAgent._registerRequestToolbox()`
- Nach erfolgreichem Aufruf refresht `agentLoop.py` die `toolDefinitions` fuer die naechste Runde
- Nur Toolboxes, die aktuell nicht aktiv sind, erscheinen als Optionen
### RBAC (Architekturentscheid)
Keine separate Tool-Level-RBAC: Zugriff wird über **Datenbank-RBAC** (z. B. File-Queries), **OAuth/Connections** bei externen Quellen und **`serviceAi`** (Billing, Provider-/Modell-RBAC) sowie **`can_access_service`** für `service.agent` durchgesetzt.
@ -59,6 +90,8 @@ Tools sind registrierte Handler mit JSON-Schema für Argumente, **`readOnly`-Fla
Zusätzlich zu den unten genannten **Kern-Tools** existieren **dynamische Tools** aus dem Workflow-System: `ActionToolAdapter` liest `methodDiscovery.methods` und registriert jede Action mit `dynamicMode=True` unter einem zusammengesetzten Namen (`{methodShort}_{actionName}`); im Adapter sind diese derzeit **alle als nicht-readOnly** registriert.
**Toolbox-Zuordnung:** Kern-Tools sind den Toolboxes `core`, `ai` und `datasources` zugeordnet (siehe Toolbox Registry oben). Connection-abhaengige Tools (`email`, `sharepoint`, `clickup`, `jira`) werden nur aktiviert, wenn der User eine passende Connection hat. Workflow-Editing-Tools (`workflow` Toolbox) werden separat via `workflowTools.py` registriert.
### Kern-Tools (registriert via `registerCoreTools``coreTools/`, 40 Stück)
**Workspace / Dateien**
@ -125,7 +158,7 @@ Zusätzlich zu den unten genannten **Kern-Tools** existieren **dynamische Tools*
| Tool | Kurzbeschreibung |
|------|------------------|
| `queryFeatureInstance` | Abfrage anderer Feature-Instanz (setzt bei Bedarf `requireNeutralization` für Sub-Calls) |
| `queryFeatureInstance` | Abfrage anderer Feature-Instanz (setzt bei Bedarf `requireNeutralization` für Sub-Calls). Sub-Agent hat `browseTable`, `queryTable` und `aggregateTable` (SUM/COUNT/AVG/MIN/MAX mit GROUP BY). DB-Connection-Pooling und Result-Caching (5 Min TTL). |
| `listWorkflowHistory` | Workflow-Historie |
| `readWorkflowMessages` | Nachrichten eines Workflows lesen |
@ -218,6 +251,8 @@ Erweiterte Hilfen (z. B. **`readSection`**, Caching) für selektives Lesen sind
| `gateway/modules/serviceCenter/services/serviceAgent/conversationManager.py` | Kontextfenster, Summarization, Systemprompt |
| `gateway/modules/serviceCenter/services/serviceAgent/datamodelAgent.py` | `AgentConfig`, Events, Trace-Modelle |
| `gateway/modules/serviceCenter/services/serviceAgent/actionToolAdapter.py` | Workflow-Actions → Agent-Tools |
| `gateway/modules/serviceCenter/services/serviceAgent/toolboxRegistry.py` | Toolbox-Definitionen, `requestToolbox` Meta-Tool-Schema |
| `gateway/modules/serviceCenter/services/serviceAgent/workflowTools.py` | Workflow-Editing-Tools (readWorkflowGraph, addNode, ...) |
| `gateway/modules/serviceCenter/services/serviceAgent/sandboxExecutor.py` | `executeCode`-Sandbox |
| `gateway/modules/serviceCenter/services/serviceKnowledge/mainServiceKnowledge.py` | Index, `buildAgentContext`, Workflow-/Round-Memory-Helfer |
| `gateway/modules/interfaces/interfaceDbKnowledge.py` | DB-Zugriff Knowledge / RAG |

View file

@ -1,6 +1,6 @@
<!-- status: canonical -->
<!-- lastReviewed: 2026-04-05 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-05) -->
<!-- lastReviewed: 2026-04-07 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-07, post Automation Unification) -->
# Gateway -- Architektur
@ -18,7 +18,7 @@ Unter `gateway/modules/` (Kontext-Audit):
| `auth/` | Authentifizierung, CSRF, Token-Refresh-Middleware, JWT |
| `connectors/` | DB-Connector (PostgreSQL), Provider-Subpakete (Microsoft, Google, ClickUp, FTP), Ticket/Messaging/Geo-Konnektoren |
| `datamodels/` | Pydantic-Datenmodelle (u. a. Ai, Billing, Chat, Content, Files, Knowledge, Rbac, Subscription, Workflow) |
| `features/` | Feature-Module (autonome Domänen): workspace, automation, automation2, chatbot, commcoach, neutralization, realEstate, trustee, teamsbot |
| `features/` | Feature-Module (autonome Domänen): workspace, graphicalEditor, chatbot, commcoach, neutralization, realEstate, trustee, teamsbot |
| `interfaces/` | DB-Interfaces (App, Billing, Chat, Knowledge, Management, Subscription), AI-Objects, RBAC, Features, Messaging |
| `migration/` | Daten-Migrationen |
| `routes/` | REST-API-Routen (u. a. Admin, Billing, DataFiles, DataSources, Security, Store, System) |
@ -27,7 +27,7 @@ Unter `gateway/modules/` (Kontext-Audit):
| `serviceHub/` | Service-Registry und Dependency Injection (u. a. `PublicService`-Wrapper) |
| `shared/` | Gemeinsame Utilities (attributeUtils, Konfiguration, Logging, …) |
| `system/` | System-Konfiguration, Feature-Discovery (`registry.py`: `loadFeatureMainModules`, `loadFeatureRouters`) |
| `workflows/` | Workflow-Engine mit Methoden und Aktionen |
| `workflows/` | Workflow-Engine mit Methoden, Aktionen, Execution Engine und konsolidiertem Scheduler |
## ServiceCenter (Kern-Orchestrierung)
@ -82,7 +82,7 @@ Weitere Interface-Dateien im Ordner (z. B. Voice, Tickets, Messaging, Bootstrap)
| Datei / Pfad | Rolle |
|--------------|-------|
| `gateway/app.py` | FastAPI-Anwendung, Einbindung von Routen und Middleware |
| `gateway/app.py` | FastAPI-Anwendung (generischer Entry-Point), Routen, Middleware, EventManager, Scheduler-MainLoop |
| `gateway/modules/serviceCenter/__init__.py` | Service Center: `getService`, `preWarm`, RBAC-Registrierung für Service-Objekte |
| `gateway/modules/serviceCenter/context.py` | `ServiceCenterContext` pro Request |
| `gateway/modules/serviceCenter/registry.py` | Service-Registry (CORE / IMPORTABLE) |
@ -95,7 +95,10 @@ Weitere Interface-Dateien im Ordner (z. B. Voice, Tickets, Messaging, Bootstrap)
| `gateway/modules/auth/*` | CSRF, Token-Refresh-Middleware, JWT, OAuth |
| `gateway/modules/shared/*` | Querschnitt: Konfiguration, Audit-Logging, Events, Utilities |
| `gateway/modules/system/registry.py` | Feature-Discovery, Router-Laden, Katalog-Registrierung beim App-Start |
| `gateway/modules/workflows/workflowManager.py` | Zentrale Workflow-Steuerung |
| `gateway/modules/workflows/workflowManager.py` | Zentrale Workflow-Steuerung (Workspace/Chat Workflows) |
| `gateway/modules/workflows/automation2/executionEngine.py` | Graph-Execution-Engine (Graphical Editor) |
| `gateway/modules/workflows/scheduler/mainScheduler.py` | Konsolidierter Workflow-Scheduler |
| `gateway/modules/interfaces/interfaceBootstrap.py` | System-Bootstrap (Templates, Billing, Stripe) |
## Regeln / Invarianten

View file

@ -1,117 +1,211 @@
<!-- status: canonical -->
<!-- lastReviewed: 2026-04-05 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-05) -->
<!-- lastReviewed: 2026-04-07 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-07, post Automation Unification) -->
# Automation
# Automation (Graphical Editor)
## Ueberblick
PowerOn hat **mehrere Automatisierungs-Spuren**, die sich die **gleiche Unified Action Library** (`workflows/methods/` + `ActionExecutor`) teilen, aber unterschiedliche **Persistenz**, **Scheduler** und **Execution Engines** nutzen. Die Business Spec beschreibt eine **Ziel-Architektur**: konsolidierte Plattform mit klarer Trennung Mandant / Feature / Feature-Instanz, skalierbarer **Toolbox**-Schicht fuer Agent-Tools und einem **vereinheitlichten Workflow-Datenmodell** (Draft/Published, Runs, Tracing).
PowerOn hat ein **konsolidiertes Automatisierungssystem** basierend auf dem Feature `graphicalEditor`. Die frueheren separaten Systeme (Automation v1, Automation2) wurden entfernt; der gesamte Workflow-Lebenszyklus laeuft ueber ein einheitliches Datenmodell und eine gemeinsame **Unified Action Library** (`workflows/methods/` + `ActionExecutor`).
**Leitentscheide (Business Spec):**
**Architektur-Saeulen:**
- Keine Migration von Altdaten fuer Automation v1 (nicht produktiv); v1 bleibt bis zur Abloesung.
- **Vier Saeulen:** AI Service (Agent, Streaming, Neutralisierung, Failover), Graphical Editor (Flow + kuenftig Editor-Chat/UDB), Automation Scheduler (Cron/Events/Webhooks), **Unified Action Library** mit Toolboxes.
- **Inkonsistenzen heute:** zwei Workflow-Datenwelten (v1 vs Automation2), zwei DB-Schemas, zwei Scheduler-Patterns, zwei Engines -- Ausrichtung ueber Zielmodell und Uebernahme bewaehrter v1-Scheduler-Patterns in Richtung v2.
1. **AI Service** -- Agent mit Toolbox-Registry, Streaming, Neutralisierung, Failover
2. **Graphical Editor** -- n8n-Style Flow-Builder mit AI Chat, UDB, Tracing, Versioning
3. **Consolidated Scheduler** -- `WorkflowScheduler` mit inkrementellem Sync (v1-Patterns)
4. **Unified Action Library** -- Method/Action-Bibliothek mit Toolbox-Zuordnung
**Leitentscheide:**
- Legacy-Features `automation` und `automation2` entfernt (Gateway + Frontend)
- Greenfield-DB `poweron_graphicaleditor` (keine Migration von Altdaten)
- v1-Scheduler-Patterns (inkrementell, `eventId`, `replaceExisting`, Stale-Removal) in konsolidierten Scheduler uebernommen
- `app.py` als generischer Entry-Point ohne feature-spezifische Imports
---
## Ist-Systeme (Gateway, Stand 2026-04-05)
## Datenmodell (Greenfield DB `poweron_graphicaleditor`)
| System | Kurzbeschreibung |
|--------|------------------|
| **Automation v1** | Template + Cron + Placeholders; robuster inkrementeller Scheduler-Sync; keine visuelle Branching-Logik. |
| **Automation2** | n8n-Style Graph; Run/Task; Pause/Resume; Human-in-the-loop; weniger robuster Scheduler-Sync als v1. |
| **AI Workspace** | Chat-Agent mit vielen Tools + RAG; kein persistiertes Workflow-Modell wie im Graph-Editor. |
| Modell | Datei | Beschreibung |
|--------|-------|-------------|
| `AutoWorkflow` | `features/graphicalEditor/datamodelFeatureGraphicalEditor.py` | Workflow mit `graph`, `invocations`, `active`, `eventId`, Template-Felder (`isTemplate`, `templateScope`, `sharedReadOnly`) |
| `AutoVersion` | gleiche Datei | Immutabler Graph-Snapshot: Status `draft`/`published`/`archived` |
| `AutoRun` | gleiche Datei | Ausfuehrung: Status `running`/`paused`/`completed`/`failed`, `nodeOutputs`, `context`, `runEnvelope` |
| `AutoStepLog` | gleiche Datei | Pro-Node-Log: `inputSnapshot`, `output`, `startedAt`, `completedAt`, `durationMs`, `tokensUsed`, `retryCount`, `error` |
| `AutoTask` | gleiche Datei | Human-Task bei Pause: Status `pending`/`completed`/`rejected`/`expired` |
**Gemeinsame technische Basis:** Alle genannten Pfade fuehren ueber **`ActionExecutor.executeAction()`** zur Method/Action Library; der Workspace-Agent mappt `dynamicMode`-Actions via **`ActionToolAdapter`** auf Tools; Automation2-Nodes tragen `_method` / `_action`.
**Invarianten:**
- Pro Workflow hoechstens **eine** `PUBLISHED` Version; Scheduler bindet an die veroeffentlichte Version
- `templateScope`: `user` | `instance` | `mandate` | `system` -- steuert Sichtbarkeit und RBAC
- System-Templates (`templateScope=system`, `mandateId=None`) werden im Bootstrap erstellt
### Automation v1 vs v2 (Ist-Vergleich)
### Workflow-Vorlagen
| Aspekt | Automation v1 | Automation2 (v2) |
|--------|----------------|------------------|
| Modell | Template/Cron/Placeholders | Graph + Node-Typen (`nodeDefinitions/`) |
| DB / Schema | `poweron_automation` | `poweron_automation2` |
| Scheduler | Inkrementell, Callback `automation.changed`, `eventId` auf `AutomationDefinition` | Full re-register, Callback `automation2.workflow.changed` |
| Engine | `WorkflowManager` + `WorkflowProcessor` + `modeAutomation` | `executionEngine.executeGraph` |
| Staerken | Bewaehrtes Scheduling, Execution-Logs | Branching, Loops, Pause/Resume, visuelles Editing |
**Konsolidierungsrichtung (Spec):** v1-Scheduler-Muster (inkrementell, Job-Handle, Reload+`active`-Check vor Run, capped Logs, `sysCreatedBy` fuer Kontext) in die v2-Welt uebernehmen; einheitliches **Workflow/Version/Run**-Konzept langfristig ueber beide Welten.
| Scope | Sichtbarkeit | Editierbar | Erstellt durch |
|-------|-------------|------------|----------------|
| `user` | Nur Ersteller | Ja | User ("Als Vorlage speichern") |
| `instance` | Alle User der Feature-Instanz | Nein (read-only) | Scope-Erweiterung |
| `mandate` | Alle User des Mandanten | Nein (read-only) | Scope-Erweiterung |
| `system` | Plattformweit | Nein (read-only) | Bootstrap (`_bootstrapSystemTemplates`) |
---
## Datenmodell
## Scheduler (`WorkflowScheduler`)
### Ist: Konkrete Modelle (Gateway, Stand 2026-04-05)
**Datei:** `workflows/scheduler/mainScheduler.py`
| Modell | Datei | DB | Beschreibung |
|--------|-------|-----|-------------|
| `AutomationDefinition` | `features/automation/datamodelFeatureAutomation.py` | `poweron_automation` | v1 Template mit `schedule`, `placeholders`, `eventId` |
| `ChatWorkflow` | `datamodels/datamodelChat.py` | `poweron_chat` | v1 Execution-Artefakt (Status, Tasks, Messages) |
| `Automation2Workflow` | `features/automation2/datamodelFeatureAutomation2.py` | `poweron_automation2` | v2 Graph mit `active`, inline `graph`, `invocations` |
| `Automation2WorkflowRun` | gleiche Datei | `poweron_automation2` | v2 Run: Status `running`/`paused`/`completed`/`failed`, `nodeOutputs`, `context` |
| `Automation2HumanTask` | gleiche Datei | `poweron_automation2` | Human-Task: Status `pending`/`completed`/`rejected` |
Konsolidierter Scheduler mit v1-Patterns:
**Hinweis:** Es gibt **keine** `WorkflowVersion`-Tabelle -- v2 speichert den Graph direkt in `Automation2Workflow`. Tracing ist `nodeOutputs` im Run, nicht ein separates `RunStepLog`-Entity.
| Aspekt | Implementierung |
|--------|----------------|
| Sync-Muster | Inkrementell: nur geaenderte Jobs re-registrieren (`eventId` Tracking) |
| Stale-Removal | Jobs fuer geloeschte/deaktivierte Workflows werden entfernt |
| Re-Registration | `replaceExisting=True` fuer idempotente Updates |
| Active-Check | Vor Execution: Workflow `active` und Entry-Point `enabled` pruefen |
| Cron-Parsing | Einfache Intervalle (*/N) als Sekunden; komplexe Cron via `parse_cron_to_kwargs` |
| Thread-Bridge | `setMainLoop()` fuer async Handler aus Scheduler-Threads |
| Delayed Sync | 5s nach Start fuer spaete DB-Verfuegbarkeit |
| Change-Callback | `callbackRegistry` fuer `graphicalEditor.workflow.changed` |
### Ziel: Vereinheitlichtes Workflow-Modell (Spec -- nicht implementiert)
**Lifecycle:**
- Start: `mainGraphicalEditor.onStart()` -> `startScheduler(eventUser)`
- Stop: `mainGraphicalEditor.onStop()` -> `stopScheduler()`
- Manual Sync: `POST /api/workflows/{instanceId}/schedule-sync` -> `syncNow()`
- Main Loop: `app.py` setzt `setSchedulerMainLoop(main_loop)` beim Start
| Entitaet | Zweck | Heute approximiert durch |
|----------|-------|--------------------------|
| **Workflow** | Metadaten, Mandant/Instanz, `active`, `eventId`, Zeiger auf aktuelle Version | `Automation2Workflow` (ohne Versioning) |
| **WorkflowVersion** | Immutabler Snapshot: `graph`, `invocations`, Status draft/published/archived | *nicht vorhanden* (Graph inline in Workflow) |
| **WorkflowRun** | Ausfuehrung mit Status, Trigger, `nodeOutputs`, Kostenfelder | `Automation2WorkflowRun` (ohne Kostenfelder, Statusmenge abweichend) |
| **RunStepLog** | Pro Node: Input, Output, Dauer, Fehler, Token | *nicht vorhanden* (approximiert durch `nodeOutputs`) |
| **HumanTask** | Menschliche Aufgabe bei Pause; Status pending/completed/cancelled/expired | `Automation2HumanTask` (Status: `pending`/`completed`/`rejected`, kein `expired`) |
**Invarianten (Zielmodell):** Pro Workflow hoechstens **eine** `PUBLISHED` Version; Scheduler bindet an die veroeffentlichte Version.
### Toolbox-Datenmodell (Ziel -- nicht im Gateway implementiert)
`ToolboxDefinition` (id, label i18n, `tools[]`, optional `requiresConnection`), `ToolboxRegistry`, erweiterte `AgentConfig` mit `initialToolboxes` / `availableToolboxes`.
> Kein Match im Gateway-Code fuer `requestToolbox`, `ToolboxDefinition` oder `availableToolboxes` (Stand 2026-04-05).
### Gateway-Schichten
Frontend -> **Features** (instanzgebunden) -> **Services** (request-scoped) -> **Shared Infrastructure** (`workflows/methods`, `workflows/processing`, `workflows/automation2`, `interfaces`, `aicore`, `datamodels`, `security`).
**Feature-Container-Pattern:** `features/<name>/` mit `main*.py` (FEATURE_CODE, UI/RESOURCE/TEMPLATE_ROLES), `routeFeature*.py`, `interfaceFeature*.py`, `datamodelFeature*.py`, optional `nodeDefinitions/`, `service*/`. Discovery ueber `registry.py` / `ServiceHub`.
**Run-Failure-Handling:**
- In-App Notification fuer Workflow-Creator
- Messaging-Subscription (`GraphicalEditorRunFailed`) fuer E-Mail-Benachrichtigung
- Event-Emission (`graphicalEditor.run.failed`)
---
## Ziel-Konzepte (Business Spec, nicht implementiert)
## Execution Engine
**Toolbox-Konzept:** Statt alle Tools flach zu exponieren, **thematische Toolboxes** (`core`, `ai`, `email`, `sharepoint`, `workflow`, ...) mit Meta-Tool **`requestToolbox`** -- Agent startet schlank, fordert Spezial-Toolboxes nach Bedarf; **`availableToolboxes`** ist pro Feature/RBAC/Connections filterbar.
**Datei:** `workflows/automation2/executionEngine.py`
**Sub-Agents:** Datenintensive Features (z. B. Trustee) kapseln Schema-Wissen in einem **Feature Data Agent**; Main-Agent sieht ein aggregiertes Tool (`queryFeatureInstance`), nicht Dutzende Tabellen-Tools.
| Feature | Details |
|---------|---------|
| Graph-Execution | Topologische Sortierung, Branch-Erkennung (ifElse/switch), Loop-Support |
| Pause/Resume | `PauseForHumanTaskError`, `PauseForEmailWaitError` mit Loop-State-Persistenz |
| Retry | Pro-Node Retry-Policy (`retryMaxAttempts`, `retryDelaySeconds`) |
| Step-Logging | `AutoStepLog` mit `inputSnapshot` fuer alle Pfade (inkl. Loops, Skipped) |
| SSE Live-Push | `_emitStepEvent()` sendet Step-Updates an `EventManager`-Queue (`run-trace-{runId}`) |
| Run-Events | `run_complete` / `run_failed` Events am Ende der Execution |
**Agent-Run (State Machine, konzeptionell -- nicht im Code):** `IDLE` -> `THINKING` -> bei Tool-Calls `EXECUTING_TOOLS` -> optional `TOOLBOX_ESCALATION` / `SUB_AGENT_CALL` -> `COMPLETED` / `FAILED` / `CANCELLED` (Limits: `maxRounds`, `maxCostCHF`).
**InputSnapshot-Abdeckung:**
- Regulaere Nodes: Outputs aller Vorgaenger-Nodes
- Loop-Header (`flow.loop`): Vorgaenger-Outputs
- Loop-Body: `_loopItem`, `_loopIndex` + Vorgaenger-Outputs
- Loop-Resume: `_loopItem`, `_loopIndex` + Vorgaenger-Outputs
- Skipped Nodes: `_skipReason: "inactive_branch"` + Vorgaenger-Outputs
**RBAC (Kurz):** Zwei getrennte Template-Systeme -- **System-Template-Rollen** (Mandant: admin/user/viewer) vs **Feature-Template-Rollen** (Instanz: z. B. workspace-admin); keine Vermischung.
---
## Node-Types
Definiert in `features/graphicalEditor/nodeDefinitions/`:
| Kategorie | Nodes |
|-----------|-------|
| **Trigger** | `trigger.manual`, `trigger.schedule`, `trigger.webhook`, `trigger.form`, `trigger.event` |
| **Flow** | `flow.ifElse`, `flow.switch`, `flow.loop`, `flow.merge`, `flow.delay` |
| **Input** | `input.humanTask`, `input.emailWait` |
| **AI** | `ai.prompt`, `ai.classify`, `ai.extract`, `ai.summarize` |
| **Email** | `email.checkEmail`, `email.sendEmail`, `email.draftEmail` |
| **SharePoint** | `sharepoint.listFiles`, `sharepoint.readFile`, `sharepoint.upload` |
| **ClickUp** | `clickup.searchTasks`, `clickup.createTask`, `clickup.updateTask` |
| **File** | `file.create` |
| **Data** | `data.transform`, `data.filter`, `data.aggregate` |
| **Trustee** | `trustee.refreshAccountingData`, `trustee.extractFromFiles`, `trustee.processDocuments`, `trustee.syncToAccounting` |
---
## Toolbox Registry
**Datei:** `serviceCenter/services/serviceAgent/toolboxRegistry.py`
Thematische Tool-Gruppierungen fuer den AI Agent:
| Toolbox | Tools | Default | Requires Connection |
|---------|-------|---------|-------------------|
| `core` | 20 (readFile, listFiles, webSearch, writeFile, ...) | Ja | -- |
| `ai` | 9 (summarizeContent, generateImage, executeCode, ...) | Ja | -- |
| `datasources` | 8 (browseDataSource, searchDataSource, ...) | Ja | -- |
| `email` | 5 (sendMail, outlook_readEmails, ...) | Nein | `microsoft` |
| `sharepoint` | 3 (sharepoint_findDocuments, ...) | Nein | `microsoft` |
| `clickup` | 3 (clickup_searchTasks, ...) | Nein | `clickup` |
| `jira` | 3 (jira_connect, ...) | Nein | `jira` |
| `workflow` | 9 (readWorkflowGraph, addNode, ...) | Nein | -- (featureCode: graphicalEditor) |
| `trustee` | 1 (trustee_refreshAccountingData) | Nein | -- (featureCode: trustee) |
**`requestToolbox` Meta-Tool:**
- Agent kann zur Laufzeit inaktive Toolboxes anfordern
- Handler in `mainServiceAgent._registerRequestToolbox()`
- `agentLoop.py` refresht `toolDefinitions` nach erfolgreichem Aufruf
- Nur inaktive Toolboxes werden als Enum-Optionen angeboten
**Aktivierung:**
- `_activateToolboxes` in `mainServiceAgent.py` prueft User-Connections
- Toolboxes ohne `requiresConnection` sind immer verfuegbar
- Tools aus inaktiven Toolboxes werden aus der Registry entfernt
---
## RBAC
Feature-Code: `graphicalEditor`
| Template-Rolle | UI-Zugriff | Daten-Zugriff |
|----------------|-----------|---------------|
| `graphicalEditor-viewer` | Dashboard, Workflows, Tasks, Templates (view) | Read: Mandate |
| `graphicalEditor-user` | + Editor | CRUD: Mandate |
| `graphicalEditor-admin` | Alle UI/Resource | CRUD: Mandate |
Rollen werden beim Feature-Start via `_syncTemplateRolesToDb()` synchronisiert (inkl. Mandate-Instanz-Rollen).
---
## API-Endpunkte (Auswahl)
| Methode | Pfad | Beschreibung |
|---------|------|-------------|
| POST | `/{instanceId}/execute` | Workflow ausfuehren |
| GET | `/{instanceId}/runs/{runId}/stream` | SSE Live-Tracing fuer einen Run |
| POST | `/{instanceId}/schedule-sync` | Scheduler manuell synchronisieren |
| POST | `/{instanceId}/{workflowId}/chat/stream` | AI Chat SSE Stream |
| GET | `/{instanceId}/node-types` | Verfuegbare Node-Types |
| GET/POST | `/{instanceId}/workflows` | Workflows CRUD |
| GET/POST | `/{instanceId}/templates` | Templates CRUD |
| POST | `/{instanceId}/workflows/{workflowId}/versions/draft` | Draft-Version erstellen |
| POST | `/{instanceId}/workflows/{workflowId}/versions/{versionId}/publish` | Version veroeffentlichen |
---
## Schluessel-Dateien
| Bereich | Typische Pfade (`gateway/modules/`) |
|---------|-------------------------------------|
| Bereich | Pfade (`gateway/modules/`) |
|---------|--------------------------|
| Feature-Definition | `features/graphicalEditor/mainGraphicalEditor.py` |
| API-Routes | `features/graphicalEditor/routeFeatureGraphicalEditor.py` |
| Interface | `features/graphicalEditor/interfaceFeatureGraphicalEditor.py` |
| Datenmodell | `features/graphicalEditor/datamodelFeatureGraphicalEditor.py` |
| Node-Definitionen | `features/graphicalEditor/nodeDefinitions/` |
| Execution Engine | `workflows/automation2/executionEngine.py` |
| Scheduler | `workflows/scheduler/mainScheduler.py` |
| Toolbox Registry | `serviceCenter/services/serviceAgent/toolboxRegistry.py` |
| Action Library | `workflows/methods/`, `workflows/processing/` (`ActionExecutor`, `methodDiscovery`) |
| Automation v1 Feature | `features/automation/` |
| Automation v1 Runtime | `workflows/automation/` (`mainWorkflow.py`, `subAutomationSchedule.py`) |
| Automation2 Feature | `features/automation2/` |
| Automation2 Runtime | `workflows/automation2/` (`executionEngine.py`, `subAutomation2Schedule.py`) |
| Agent <-> Actions | `serviceCenter/services/serviceAgent/` (Tool-Registrierung, `ActionToolAdapter`) |
| Feature-Discovery | `system/registry.py`, `serviceHub/__init__.py` |
| RBAC | `interfaces/interfaceRbac.py`, `security/`, Rollen/AccessRules in Datamodels |
| Agent Tools | `serviceCenter/services/serviceAgent/` (coreTools, actionToolAdapter, workflowTools) |
| Bootstrap | `interfaces/interfaceBootstrap.py` (System-Templates, Billing) |
---
## Regeln / Invarianten
1. **Eine Action Library:** Aenderungen an Methods/Actions betreffen Workspace, Automation v1, Automation2 und Agent-Tools gleichzeitig -- Kompatibilitaet und `actionId`-Stabilitaet beachten.
2. **RBAC strikt trennen:** Mandantenrollen vs Feature-Instanz-Rollen nicht mischen; Permissions ueber AccessRules und Prioritaetsregeln.
3. **Scheduler vs Editor:** Ausfuehrung und Zeitplanung gehoeren zur **Scheduler-Saeule**; der Graph ist **Version**-gebunden (Draft vs Published).
4. **Tool-Skalierung:** Flache Tool-Listen skalieren nicht; Toolbox + `requestToolbox` + connection-basierte Verfuegbarkeit sind das vorgesehene Gegenmittel (Ziel, nicht implementiert).
5. **Zielmodell vs Ist:** `Workflow` / `WorkflowVersion` / `WorkflowRun` in der Spec sind **Zielarchitektur**. Ist-Modelle siehe oben (`Automation2Workflow`, `Automation2WorkflowRun` etc.). Abgleich bei Implementierungsarbeiten erforderlich.
6. **Neutralisierung / KI:** Plattformweit gelten die zentralen KI-Datenpfade (siehe `workflow.md` / Compliance); Automation nutzt dieselben Services wie der Rest des Gateways.
1. **Eine Action Library:** Aenderungen an Methods/Actions betreffen Workspace, Graph-Editor und Agent-Tools gleichzeitig -- `actionId`-Stabilitaet beachten.
2. **RBAC strikt trennen:** Mandantenrollen vs Feature-Instanz-Rollen nicht mischen; Permissions ueber AccessRules.
3. **Scheduler vs Editor:** Ausfuehrung und Zeitplanung gehoeren zum Scheduler; der Graph ist Version-gebunden (Draft vs Published).
4. **Tool-Skalierung:** Toolbox-Konzept mit `requestToolbox` Meta-Tool; connection-basierte Verfuegbarkeit.
5. **`app.py` generisch:** Keine feature-spezifischen Imports in `app.py`; Feature-Lifecycle in `mainGraphicalEditor.onStart/onStop`.
6. **Neutralisierung / KI:** Plattformweit gelten die zentralen KI-Datenpfade; Automation nutzt dieselben Services.
7. **Bootstrap idempotent:** `initBootstrap` mit `_bootstrapDone` Flag; System-Templates, Billing, Stripe-Prices.

View file

@ -1,6 +1,6 @@
<!-- status: canonical -->
<!-- lastReviewed: 2026-04-05 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-05) -->
<!-- lastReviewed: 2026-04-07 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-07, post Automation Unification) -->
# Workflow-Engine
@ -11,10 +11,11 @@ Die Workflow-Engine im Gateway orchestriert KI-gestützte Aufgabenpläne und die
**Einsatzorte (Konsumenten der Action Library):**
- **Workspace (Dynamic Mode):** `WorkflowProcessor` / `modeDynamic` → Planung (Stage 1/2) → `ActionExecutor`
- **Automation v1:** `WorkflowProcessor` / `modeAutomation``ActionExecutor`
- **Automation2:** Graph-Engine mappt Nodes (`_method` / `_action`) auf dieselbe Library
- **Graphical Editor:** `executionEngine.executeGraph` mappt Nodes (`_method` / `_action`) auf dieselbe Library
- **Workspace-Agent:** `ActionToolAdapter` exponiert `dynamicMode=True`-Aktionen als Tools → `ActionExecutor`
*Hinweis:* Die frueheren separaten Systeme Automation v1 und Automation2 wurden im Rahmen der Automation Unification (2026-04) entfernt. Der Graphical Editor ist der einzige Graph-basierte Konsument.
**Ausführungsmodell:** Pro Workflow-Instanz sequentielle Ausführung (kein paralleles Multi-Task-Modell auf einer Instanz). Ausführungszähler (`currentRound`, `currentTask`, `currentAction`) liegen am **`ChatWorkflow`** (Single Source of Truth).
---
@ -54,7 +55,7 @@ Methoden sind Python-Klassen unter `gateway/modules/workflows/methods/`; der **M
| `sharepoint` | `findDocumentPath`, `readDocuments`, `uploadDocument`, `listDocuments`, `analyzeFolderUsage`, `findSiteByUrl`, `downloadFileByPath`, `copyFile`, `uploadFile` |
| `clickup` | `listTasks`, `searchTasks`, `getTask`, `createTask`, `updateTask`, `uploadAttachment` |
| `jira` | `connectJira`, `exportTicketsAsJson`, `importTicketsFromJson`, `mergeTicketData`, `parseCsvContent`, `parseExcelContent`, `createCsvContent`, `createExcelContent` |
| `trustee` | `extractFromFiles`, `processDocuments`, `syncToAccounting` |
| `trustee` | `extractFromFiles`, `processDocuments`, `syncToAccounting`, `refreshAccountingData` (`dynamicMode=True`) |
| `chatbot` | `queryDatabase` |
| `file` | `create` |
@ -76,12 +77,15 @@ Methoden sind Python-Klassen unter `gateway/modules/workflows/methods/`; der **M
| Pfad (unter `gateway/modules/`) | Rolle |
|--------------------------------|--------|
| `workflows/workflowManager.py` | Workflow-Orchestrierung, Einstieg |
| `workflows/workflowManager.py` | Workflow-Orchestrierung fuer Workspace/Chat (Einstieg) |
| `workflows/processing/` | Processor, Modi (`modeDynamic`, `modeAutomation`), `ActionExecutor` |
| `workflows/automation2/executionEngine.py` | Graph-Execution-Engine (Graphical Editor): Branching, Loops, Pause/Resume, Step-Logging, SSE Live-Push |
| `workflows/scheduler/mainScheduler.py` | Konsolidierter Workflow-Scheduler (inkrementeller Sync) |
| `workflows/methods/methodBase.py` | Basis für Methoden, Aktions-Validierung |
| `workflows/methods/method*/` | Konkrete Methoden und Aktionen |
| `datamodels/datamodelChat.py` | `ChatWorkflow`, `TaskContext`, Task-/Plan-Modelle |
| `datamodels/datamodelWorkflowActions.py` | Aktionsdefinitionen |
| `features/graphicalEditor/datamodelFeatureGraphicalEditor.py` | `AutoWorkflow`, `AutoVersion`, `AutoRun`, `AutoStepLog`, `AutoTask` |
| `serviceCenter/services/serviceChat/` | Fortschritt, Logs, Nachrichten/Dokumente am Workflow |
| `serviceCenter/services/serviceAi/` | Planning- und Content-KI (kein direkter Workflow-Import aus Methods zurück) |
| `interfaces/interfaceDbChat*` | Persistenz Workflow/Nachrichten/Dokumente |
@ -95,4 +99,4 @@ Methoden sind Python-Klassen unter `gateway/modules/workflows/methods/`; der **M
3. **Typisierung:** Bevorzugt Pydantic-Modelle für Planungs- und Aktionskontext (`ActionDefinition`, `TaskResult`, …); JSON aus KI-Calls über zentrale Parse-/Repair-Hilfen.
4. **Sequenz:** Ein Workflow läuft in einer Instanz sequentiell ab; parallele Ausführung ist kein Designziel der beschriebenen Engine.
5. **Neutralisierung:** Sensible Daten an **KI-Modelle** laufen über das zentrale Gate in `serviceAi` (`mainServiceAi.py`); die Workflow-Aktion `context.neutralizeData` ist eine **explizite** Neutralisierung extrahierter Inhalte und ersetzt nicht das globale KI-Gate (siehe Compliance-Doku).
6. **Gemeinsame Library:** Dieselben Actions werden von Chat-Workflow, Automation v1/v2 und Agent-Tools genutzt — Änderungen an `actionId` / Parametern wirken quer über alle Konsumenten.
6. **Gemeinsame Library:** Dieselben Actions werden von Chat-Workflow, Graphical Editor und Agent-Tools genutzt — Änderungen an `actionId` / Parametern wirken quer über alle Konsumenten.

View file

@ -0,0 +1,398 @@
<!-- status: draft -->
<!-- lastReviewed: 2026-04-07 -->
# Analyse: Typed Node Handover System für den Graphical Editor
## 1 Problemstellung
Der Graphical Editor besitzt heute **keine formale Typisierung** der Daten, die zwischen Nodes fließen. Jede Node produziert ein freiformiges Dict; die Folge-Node versucht heuristisch, daraus das Passende zu extrahieren. Das führt zu:
| Symptom | Wo sichtbar |
|---------|-------------|
| Spezialcode pro Paar (z.B. `_extractEmailContentFromUpstream`, `_getContextFromUpstream`, `_gatherAttachmentDocumentsFromUpstream`) | `actionNodeExecutor.py` (~860 Zeilen, >50 % handover Heuristik) |
| DataPicker zeigt **hartcodierte** Beispiel-Schemas (`outputPreviewRegistry.ts`) — stimmt oft nicht mit echten Laufzeit-Outputs überein | Frontend `outputPreviewRegistry.ts` |
| Kein `data.transform`, `data.filter`, `data.aggregate` implementiert — nur in `automation.md` als Placeholder aufgelistet | `nodeDefinitions/` hat keine Datei dafür |
| Kein „Aggregate" (Gegenstück zu `flow.loop`'s For-Each) | Engine sammelt Loop-Body-Resultate nicht auf |
| Frontend-Parameter haben **eigene** Typdefinitionen (node-level `type: "string"`) statt der in `MethodBase` etablierten `WorkflowActionParameter` mit `FrontendType`-Enum + Validierung | `ai.py`, `email.py` etc. vs. `methodBase.py` |
**Kern:** Die Method/Action-Schicht hat bereits eine saubere Parameter-Typisierung (`WorkflowActionParameter`, `_validateType`, `_validateParameters`, `FrontendType`). Aber der Graph-Editor nutzt sie weder für Input-Konfiguration noch für die Handover-Logik.
---
## 2 Ist-Zustand (Layer für Layer)
### 2.1 Node-Definitionen (`nodeDefinitions/*.py`)
Jede Node ist ein Dict mit:
```python
{
"id": "email.draftEmail",
"parameters": [
{"name": "subject", "type": "string", "required": True, ...},
],
"inputs": 1, "outputs": 1,
"_method": "outlook", "_action": "composeAndDraftEmailWithContext",
"_paramMap": {"connectionId": "connectionReference", ...},
}
```
**Was fehlt:**
- Kein `outputSchema` — was liefert die Node zurück?
- Kein `inputSchema` — was erwartet die Node am Eingang?
- `type: "string"` ist Node-Editor-intern, nicht identisch mit `WorkflowActionParameter.type` (`str`, `int`, `List[str]`, …).
- Kein `frontendType` (d.h. Frontend baut eigene Config-Components per Node-Typ statt generisch).
### 2.2 Execution Engine (`executionEngine.py`)
- Topologische Sortierung → iteriert Nodes → ruft Executor auf → speichert Output in `nodeOutputs[nodeId]`.
- **Kein Output-Vertrag**: der Executor liefert `Any`, das Dict wird 1:1 in `nodeOutputs` gelegt.
- Folge-Nodes holen via `inputSources[nodeId][0]` den Vorgänger-Output und _hoffen_, dass er das richtige Format hat.
### 2.3 ActionNodeExecutor (`actionNodeExecutor.py`)
- ~860 Zeilen, davon ~60 % dedizierte Merge-Logik für Paare: `email→AI`, `AI→email.draftEmail`, `file.create` content-gathering, ClickUp merge, etc.
- Aufruft am Ende `ActionExecutor.executeAction(method, action, params)` — dessen `MethodBase._validateParameters` prüft die **Action**-Parameter, nicht den Graph-Port-Kontrakt.
- Baut ein Output-Dict mit teilweise inkonsistenten Keys (`documents` vs. `documentList` vs. `data` vs. `context`).
### 2.4 DataPicker + outputPreviewRegistry (Frontend)
- `outputPreviewRegistry.ts` registriert **statische Beispiele** pro Node-Typ.
- DataPicker zeigt daraus einen Baum und erzeugt `DataRef { type: "ref", nodeId, path }`.
- `resolveParameterReferences` (Backend) löst `DataRef` gegen echte `nodeOutputs`.
- **Problem:** Die Preview-Struktur ist manuell gepflegt und **divergiert** vom echten Output. Der User wählt Pfade, die zur Laufzeit nicht existieren oder anders heißen.
### 2.5 Method/Action Parameter-System (bereits existent)
`WorkflowActionParameter` + `MethodBase._validateParameters`:
```python
class WorkflowActionParameter(BaseModel):
name: str
type: str # 'str', 'int', 'List[str]', 'Dict[str, Any]'
frontendType: FrontendType # TEXT, TEXTAREA, SELECT, USER_CONNECTION, …
frontendOptions: Optional[...]
required: bool
default: Optional[Any]
validation: Optional[Dict]
```
`_validateType` konvertiert + prüft: `str→str`, `int→int`, `List[str]→[str,…]`, usw.
**Dieses System funktioniert bereits** für Workspace-Actions. Es wird aber **nicht** für Node-Ein-/Ausgänge genutzt.
---
## 3 Ziel-Architektur: Typed Port System
### 3.1 Kern-Konzept: Port-Schema
Jede Node deklariert **typisierte Ports** für Ein- und Ausgänge — analog zu `WorkflowActionParameter`, aber für den Graphen.
```
┌──────────────────────────────────────────────────────────────────────┐
│ Node Definition (Beispiel: email.draftEmail) │
│ │
│ inputPorts: │
│ [0]: { schema: EmailDraft } ← structured type │
│ EmailDraft = { subject: str, body: str, to: List[str] } │
│ │
│ outputPorts: │
│ [0]: { schema: ActionResult } │
│ ActionResult = { success: bool, error: str?, │
│ documents: List[Document] } │
│ │
│ parameters: (config, unabhängig von Ports) │
│ connectionId: { type: str, frontendType: USER_CONNECTION } │
└──────────────────────────────────────────────────────────────────────┘
```
### 3.2 Port-Schema Definition
```python
class PortField(BaseModel):
name: str
type: str # str, int, bool, List[str], List[Document], Dict[str,Any], …
description: Dict[str, str] # {en, de, fr}
required: bool = True
class PortSchema(BaseModel):
fields: List[PortField]
class NodePortDefinition(BaseModel):
inputPorts: Dict[int, PortSchema] # port-index → schema
outputPorts: Dict[int, PortSchema] # port-index → schema
```
### 3.3 Einheitliche Output-Typen (Port-Typen-Katalog)
Statt freier Dicts gibt es benannte Schemas, die Node-übergreifend wiederverwendbar sind:
| Port-Typ | Felder | Produziert von | Konsumiert von |
|----------|--------|----------------|----------------|
| `DocumentList` | `documents: List[{name, data, mimeType, metadata}]` | sharepoint.readFile, sharepoint.downloadFile, ai.*, file.create, input.upload | ai.*, file.create, email.draftEmail, sharepoint.uploadFile |
| `FileList` | `files: List[{url, name, path, size}]` | sharepoint.listFiles, sharepoint.findFile | sharepoint.readFile, sharepoint.downloadFile, flow.loop |
| `EmailDraft` | `subject: str, body: str, to: List[str], cc?: List[str], attachments?: DocumentList` | ai.prompt (mode=email) | email.draftEmail, email.sendEmail |
| `EmailList` | `emails: List[{subject, from, to, body, date, attachments}]` | email.checkEmail, email.searchEmail | ai.prompt, flow.loop, flow.ifElse |
| `TaskList` | `tasks: List[{id, name, status, url, …}]` | clickup.searchTasks, clickup.listTasks | flow.loop, clickup.updateTask |
| `TaskResult` | `success: bool, taskId: str, task: {id, name, status}` | clickup.createTask, clickup.updateTask | flow.ifElse |
| `FormPayload` | `payload: Dict[str, Any]` (dynamisch, Keys = Feldnamen) | trigger.form, input.form | Alle (via Referenz auf Einzelfelder) |
| `AiResult` | `prompt: str, response: str, context: str, documents: List[Document]` | ai.* | email.draftEmail, file.create, sharepoint.uploadFile |
| `BoolResult` | `result: bool, reason?: str` | input.approval, input.confirmation | flow.ifElse |
| `TextResult` | `text: str` | input.comment | ai.*, file.create |
| `LoopItem` | `currentItem: Any, currentIndex: int, items: List[Any], count: int` | flow.loop (pro Iteration) | Loop-Body Nodes |
| `AggregateResult` | `items: List[Any], count: int` | **data.aggregate** (NEU) | Alle |
### 3.4 Schema auf Node-Definitions
Erweiterung der bestehenden Node-Definitions um `outputPorts` und `inputPorts`:
```python
{
"id": "ai.prompt",
"category": "ai",
"parameters": [...], # Config — bleibt wie bisher
"inputs": 1,
"outputs": 1,
# NEU ─────────────────────────────────────────
"inputPorts": {
0: {"accepts": ["DocumentList", "TextResult", "FormPayload", "EmailList", "AiResult", "Any"]},
},
"outputPorts": {
0: {"schema": "AiResult"},
},
}
```
```python
{
"id": "email.draftEmail",
"inputPorts": {
0: {"accepts": ["EmailDraft", "AiResult", "TextResult"]},
},
"outputPorts": {
0: {"schema": "ActionResult"},
},
}
```
### 3.5 Konsequenzen für bestehende Schichten
#### A) Node-Definitionen — einmalige Migration
Jede Node bekommt `inputPorts` + `outputPorts`. Bestehende `inputs`/`outputs` (Zählwerte) bleiben für Rückwärtskompatibilität, aber die Schemas werden die Quelle der Wahrheit.
#### B) Executors — Output normalisieren
Jeder Executor erhält eine `_normalizeOutput(rawResult, portSchema) → Dict` Funktion. Sie sorgt dafür, dass die Keys/Typen dem deklarierten Schema entsprechen. Für `AiResult` z.B.:
```python
def _normalizeAiResult(raw: Any) -> Dict:
return {
"prompt": raw.get("prompt", ""),
"response": raw.get("response", raw.get("context", "")),
"context": raw.get("context", ""),
"documents": _ensureDocumentList(raw.get("documents", [])),
}
```
Der Spezialcode in `actionNodeExecutor.py` (~400 Zeilen Paar-Heuristik) fällt dann weg und wird durch generische Normalizer pro Port-Typ ersetzt.
#### C) ExecutionEngine — Handover-Validierung
Nach jedem Node-Execute: `nodeOutputs[nodeId]` wird gegen `outputPorts[0].schema` geprüft (Warnung oder Fehler bei Mismatch). Vor jedem Node-Execute: Input-Port-Kompatibilitäts-Check (`accepts` enthält den Schema-Typ des Vorgänger-Outputs).
#### D) Frontend — DataPicker aus Schema generieren
`outputPreviewRegistry.ts` wird ersetzt durch eine generische Funktion, die aus dem PortSchema den Preview-Baum baut. Kein manuelles Pflegen mehr:
```typescript
function buildPreviewFromSchema(schema: PortSchema): Record<string, unknown> {
// Iteriert schema.fields → Beispielwert pro Typ
}
```
#### E) Frontend — Generisches Parameter-Rendering
Statt pro Node-Typ eine eigene Config-Component zu schreiben (aktuell 12+ Dateien), können die meisten Parameter-Felder generisch aus dem `WorkflowActionParameter`-Schema gerendert werden. Spezial-UIs (FormBuilder, ClickUp Browse, etc.) bleiben als Override.
#### F) Verbindungs-Validierung im Editor
Beim Ziehen einer Kante: prüfe `sourceNode.outputPorts[outputIdx].schema``targetNode.inputPorts[inputIdx].accepts`. Falls inkompatibel: Kante rot markieren / verhindern.
---
## 4 Fehlende Nodes / Konzepte
### 4.1 data.aggregate (Gegenstück zu flow.loop)
Loop verteilt Items → Body → aber am Ende gibt es keinen Collector. Heute liegt nur das letzte Body-Ergebnis in `nodeOutputs`.
**Lösung: `data.aggregate`-Node**
```python
{
"id": "data.aggregate",
"category": "data",
"label": {"en": "Aggregate", "de": "Sammeln", "fr": "Agréger"},
"description": {"en": "Collect results from loop body into a list", ...},
"parameters": [
{"name": "mode", "type": "string", "options": ["collect", "concat", "sum", "count"], "default": "collect"},
],
"inputs": 1, "outputs": 1,
"inputPorts": {0: {"accepts": ["Any"]}},
"outputPorts": {0: {"schema": "AggregateResult"}},
"executor": "data",
}
```
**Engine-Änderung:** Im Loop-Body erkennt die Engine eine `data.aggregate`-Node und sammelt pro Iteration das Ergebnis in einer Liste. Nach Loop-Ende: `nodeOutputs[aggregateNodeId] = { items: [...], count: N }`.
### 4.2 data.transform
Reiner Mapping-Node: Felder umbenennen, extrahieren, umstrukturieren. Konfiguration per Key-Value-Mapping oder einfachem Expression-Sprache.
```python
{
"id": "data.transform",
"category": "data",
"parameters": [
{"name": "mapping", "type": "json", "description": "Key-Value Mapping: {outputField: inputRef}"},
],
"inputPorts": {0: {"accepts": ["Any"]}},
"outputPorts": {0: {"schema": "Dict"}},
}
```
### 4.3 data.filter
Filtert Items einer Liste nach Bedingung (wie WHERE in SQL). Eingabe: List, Ausgabe: gefilterter List.
```python
{
"id": "data.filter",
"category": "data",
"parameters": [
{"name": "condition", "type": "string", "description": "Filter expression (z.B. item.status == 'open')"},
],
"inputPorts": {0: {"accepts": ["AggregateResult", "FileList", "TaskList", "EmailList"]}},
"outputPorts": {0: {"schema": "AggregateResult"}},
}
```
### 4.4 flow.merge
Heute in `automation.md` gelistet, aber nicht implementiert. Wartet auf N Eingänge und kombiniert sie.
---
## 5 Migrations-Strategie
### Phase 1: Port-Schema-Deklaration (Backend, kein Breaking Change)
1. `PortSchema` als Pydantic-Modell definieren.
2. Katalog der Port-Typen (`DocumentList`, `AiResult`, `EmailDraft`, …) anlegen.
3. Jede Node-Definition in `nodeDefinitions/*.py` um `inputPorts` / `outputPorts` erweitern.
4. API `GET /node-types` liefert die Schemas mit.
### Phase 2: Output-Normalizer (Backend)
1. Pro Port-Typ einen Normalizer schreiben (1015 Funktionen).
2. In `executionEngine.py`: nach jedem Execute `_normalizeOutput(result, schema)` aufrufen.
3. Spezialcode in `actionNodeExecutor.py` schrittweise durch Normalizer ersetzen.
4. Step-Logs mit normalisiertem Output (Debugging/Tracing sofort besser).
### Phase 3: Frontend — DataPicker aus Schema (Frontend)
1. `outputPreviewRegistry.ts` durch Schema-basierte Preview-Generierung ersetzen.
2. DataPicker zeigt korrekte Felder + Typen an.
3. Verbindungs-Validierung (rote Kanten bei Typ-Mismatch).
### Phase 4: Generisches Parameter-Rendering (Frontend)
1. `NodeConfigPanel` rendert Parameter generisch aus `WorkflowActionParameter`-Schema.
2. Spezial-Components (`FormNodeConfig`, `ClickUpNodeConfig`, …) bleiben als Override für komplexe UIs.
3. Neue Nodes brauchen **keine eigene Config-Component** mehr.
### Phase 5: Neue Data-Nodes
1. `data.aggregate` implementieren (Engine + Node-Definition + Frontend).
2. `data.transform` implementieren.
3. `data.filter` implementieren.
4. `flow.merge` implementieren.
---
## 6 Konkretes Beispiel: AI-Mail-Entwurf → Mail-Versand
### Heute (heuristisch)
```
[email.checkEmail] ──→ [ai.prompt] ──→ [email.draftEmail]
↓ ↓ ↓
freeform Dict freeform Dict ~100 Zeilen Spezialcode
(data.emails…) (context, docs) in actionNodeExecutor:
_extractEmailContentFromUpstream
_getIncomingEmailFromUpstream
_unpackIncomingEmail
_gatherAttachmentDocumentsFromUpstream
```
### Ziel (typisiert)
```
[email.checkEmail] [ai.prompt] [email.draftEmail]
outputPort[0]: outputPort[0]: inputPort[0]:
schema: EmailList schema: AiResult accepts: [EmailDraft, AiResult]
──────────────────→ ──────────────────→ Normalizer kennt AiResult und
Input: EmailList Input: EmailList mapped response → body,
Engine prüft Kompatibilität Engine prüft kein Spezialcode nötig.
```
**Entscheidend:** Der AI-Node kann so konfiguriert werden, dass sein Output-Typ `EmailDraft` statt `AiResult` ist (z.B. via Parameter `outputMode: "emailDraft"` oder via Prompt-Instruktion + structured output). Dann ist der Downstream-Merge trivial.
---
## 7 Offene Fragen / Entscheidungen
| # | Frage | Optionen |
|---|-------|----------|
| 1 | Soll Typ-Mismatch eine Kante verhindern (hard) oder nur warnen (soft)? | **Empfehlung: soft** (Warnung + gelbe Kante). Hard-Block wäre zu restriktiv bei generischen Nodes. |
| 2 | Port-Typ `Any` erlauben? | Ja, als Fallback. Nodes wie `flow.ifElse` leiten den Input transparent durch. |
| 3 | Dynamische Schemas (z.B. `input.form` Payload hängt von Felddefinition ab)? | Ja. `outputPorts` kann eine Funktion referenzieren, die das Schema aus den `parameters` ableitet (wie heute `outputPreviewRegistry`). |
| 4 | Sollen bestehende Workflows beim Upgrade automatisch migriert werden? | **Nein.** Alte Workflows laufen weiter (Normalizer fängt fehlende Keys ab). Neue Workflows profitieren von Validierung. |
| 5 | Separater `data.aggregate`-Node oder implizit in `flow.loop`? | **Empfehlung: separater Node.** Explizit ist klarer; der Loop-Node bleibt rein für Iteration. |
| 6 | Braucht es einen `data.join`-Node (merge zwei Listen)? | Später. Erst aggregate + filter + transform etablieren. |
---
## 8 Aufwand-Schätzung
| Phase | Geschätzter Aufwand | Abhängigkeiten |
|-------|-------------------|----------------|
| 1 — Port-Schema-Deklaration | 23 Tage | Keine |
| 2 — Output-Normalizer | 35 Tage | Phase 1 |
| 3 — Frontend DataPicker aus Schema | 23 Tage | Phase 1 |
| 4 — Generisches Parameter-Rendering | 34 Tage | Phase 1 |
| 5 — Data Nodes (aggregate, transform, filter) | 35 Tage | Phase 2 |
| **Gesamt** | **~1320 Tage** | Phasen 13 sind der kritische Pfad |
---
## 9 Schlüssel-Dateien
| Bereich | Pfade |
|---------|-------|
| Node-Definitionen | `gateway/modules/features/graphicalEditor/nodeDefinitions/*.py` |
| Execution Engine | `gateway/modules/workflows/automation2/executionEngine.py` |
| ActionNodeExecutor (Handover-Heuristik) | `gateway/modules/workflows/automation2/executors/actionNodeExecutor.py` |
| Graph-Utilities | `gateway/modules/workflows/automation2/graphUtils.py` |
| Method/Action Typsystem | `gateway/modules/workflows/methods/methodBase.py`, `gateway/modules/datamodels/datamodelWorkflowActions.py` |
| FrontendType Enum | `gateway/modules/shared/frontendTypes.py` |
| Output-Preview (Frontend) | `frontend_nyla/src/components/FlowEditor/nodes/shared/outputPreviewRegistry.ts` |
| DataPicker (Frontend) | `frontend_nyla/src/components/FlowEditor/nodes/shared/DataPicker.tsx` |
| DataRef/DynamicValue (Frontend) | `frontend_nyla/src/components/FlowEditor/nodes/shared/dataRef.ts` |
| Node Config Registry (Frontend) | `frontend_nyla/src/components/FlowEditor/nodes/configs/index.ts` |
| DataFlow Context (Frontend) | `frontend_nyla/src/components/FlowEditor/context/Automation2DataFlowContext.tsx` |

View file

@ -0,0 +1,256 @@
<!-- status: plan -->
<!-- started: 2026-04-07 -->
<!-- component: frontend-nyla | platform -->
# PORTA UI-Enhancements (Team-Meeting Inputs, 2026-04-07)
## Beschreibung und Kontext
**Quelle:** Transkript POL-Weekly vom 7. April 2026 (`c-work/1-plan/input2026-04-ui-enhancement-inbputs.txt`). Philipp Graf und Dominic Largo haben PORTA als **echte Erstnutzer** (KMU-Perspektive, nicht IT-heavy) getestet; Patrick Motsch und das Team haben Anforderungen präzisiert.
**Produkt:** PowerOn PORTA — Multi-Tenant SaaS mit AI-Agent-Workspace, siehe [wiki/README.md](../../README.md).
**Business-Treiber:** Die **Hürde bis zur ersten sinnvollen Interaktion** muss sinken. Ohne klare Userführung und sichtbares Vertrauen springen potenzielle Kunden ab, bevor sie den Mehrwert (ein Abo statt vieler, Datenkontrolle, Schweizer Gegenpartei) erleben. Das UI ist explizit als **Aushängeschild** und Human-Reaction-Hebel genannt.
**Abhängigkeiten:** Copy und rechtliche Zulässigkeit für Marken-/Partner-Hinweise; Billing-Daten müssen für Transparenz-UI verfügbar sein (Gateway/Billing bereits teilweise vorhanden laut Diskussion).
**Risiko bei Nicht-Umsetzung:** Weiterhin hohe Abbruchrate nach Login; AI-Workspace wirkt «versteckt» in typischen Fensterbreiten; Vertrauen bleibt abstrakt statt greifbar.
## Fokus und kritische Details
### Aus dem Meeting extrahierte UI/UX-Schwerpunkte
| Thema | Nutzerstimme / Intention | Konsequenz für UI |
|-------|--------------------------|-------------------|
| **Vertrauen & Substanz** | Nicht primär ISO-Badge; wichtig ist z. B. «Daten hosted in der Schweiz» (konkreter Anbieter/Standort sichtbar) | Trust-Badges/Copy: Hosting-Ort, ggf. Anbietername; kurze, scanbare Vertrauenszeile |
| **Marken- & Partneranker** | Swiss Registered (®) am Logo; «Recommended by» mit wenigen, kuratierten Partnern (Valion, PamoCreate, Swiss AI Association, Prescos, Soha Treuhand) | Footer/Landing/Login: Partner-Strip; Markenhinweis konsistent |
| **Erste Datenanbindung** | Sorge: «Baue ich Scheisse?» — Encoding/Sicherheit nicht fühlbar | Onboarding-Microcopy: Read-only/sichere Verbindung, «nichts kaputtmachen», Rollback/Wiederherstellung wo zutreffend |
| **AI-Workspace: Eingabe finden** | «Wo tippe ich die Frage?» — kleines Fenster, Plus, Hover; Vergleich zu Cloud/ChatGPT mit klarem Fragebalken | **Primäre Prompt-Zeile** dominant; sekundäre Aktionen nicht vor Eingabe verstecken |
| **Layout / Viewports** | Schmales Fenster (nicht Mobile, nicht Wide): Chat/Input **verschwindet** praktisch | Breakpoints testen; **Mobile (hoch/schmal)** vs **Desktop (breit)** als zwei klare Modi; mittlere Breiten nicht vernachlässigen |
| **Neuer Chat / Kontext** | Erwartung: schnell «neuer Chat» wie gewohnt; fehlte als klare Handlung | Sichtbarer CTA «Neuer Chat» / Kontext-Reset analog Erwartung aus Chat-Tools |
| **Datei / Prompt** | Drag-in-Prompt erwünscht; Entdeckbarkeit war mühsam | Klare Dropzone oder Hinweis in leerem Zustand |
| **Pricing & Billing Auffindbarkeit** | Erste Session: «Wo steht das Pricing?» Pfad Admin → Benutzer → Billing wirkt versteckt | **Ersteinstieg:** Link oder Teaser zu Kosten/Guthaben; ggf. leere States mit «So siehst du dein Budget» |
| **Informationsdichte** | «Flut der Informationen oder der Logik» — Berufsalltag vs. zu viel parallel | IA: Schichten, progressive Offenlegung; weniger gleichzeitig auf Startscreens |
### Kritische Details
- **Int vs. Prod:** Tester war teils auf falscher Instanz — für UX-Tests einheitliche **Test-Links** kommunizieren (Prozess, nicht nur UI).
- **Rollen:** Admin vs. User — Billing nur für Admins sichtbar; Empty States für User müssen trotzdem Orientierung geben («Frag deinen Admin»), ohne frustrierende Sackgassen.
- **Recht/Marken:** Partner-Logos und Formulierungen «Recommended by» mit Partnern abstimmen.
## Ziel und Nicht-Ziele
**Ziel:**
- Nach Login und im **AI-Workspace** ist die **primäre Eingabe** (Frage/Prompt) in typischen Viewports **sofort erkennbar**.
- **Vertrauen** ist ohne Deep-Dive erfassbar: Schweizer Hosting-Hinweis, Marken-/Partner-Elemente wie im Meeting skizziert.
- **Onboarding** zur ersten Connector-/Datenaktion reduziert Angst («sicher verbinden») durch klare Kurztexte.
- **Billing/Usage** ist für berechtigte Rollen **auffindbarer**; erste Orientierung zu Kosten ohne Graben durch Administration.
- **Responsive Verhalten** für schmale Desktop-Fenster und Mobile ist konsistent definiert und getestet.
**Explizit NICHT:**
- Neues Produkt-Splitting (z. B. «Teamspot») oder komplette Pricing-/Usage-Modelle neu erfinden — nur **UI/IA/Discoverability** und Anbindung an bestehende Billing-Fakten.
- ISO-Zertifizierung als Projekt; höchstens spätere Verknüpfung zu Compliance-Docs in `e-compliance/`.
- Vollständige Ersetzung der Produktstory zu externen LLM-Abos (Copy kann ergänzt werden, kein Marketing-Whitepaper im Scope).
## Betroffene Module
- **Frontend Nyla:** AI-Workspace-Layout, globale Shell (Login/Landing), Navigation/Empty States, ggf. Trust-Strip-Komponente, Breakpoints.
- **Gateway:** nur falls neue/angereicherte Felder für Trust-Copy (Hosting-Text) oder Billing-Summary für Dashboard nötig — zunächst statische/config-gestützte Copy prüfen.
- **DB-Migration:** nein (voraussichtlich).
- **Platform / Wiki:** nach Release `b-reference/frontend-nyla/architecture.md` oder `platform/navigation.md` bei Routing-Änderungen.
---
## Codebase-Audit (Ist-Zustand, `frontend_nyla`)
Stand: Abgleich mit Repo-Pfaden unter `poweron/frontend_nyla/src/`. Tiefergehende Systemregeln: [b-reference/frontend-nyla/architecture.md](../../b-reference/frontend-nyla/architecture.md), Navigation: [b-reference/platform/navigation.md](../../b-reference/platform/navigation.md).
### Bereits vorhanden (positiv)
| Bereich | Was existiert | Wo im Code |
|--------|----------------|------------|
| **3-Spalten-Workspace** | Links `UnifiedDataBar` (Chats / Dateien / Quellen), Mitte `ChatStream` + `WorkspaceInput`, rechts Activity/Preview; resize handles; Collapse links/rechts | `pages/views/workspace/WorkspacePage.tsx` |
| **Mobile (≤1024px)** | Oberleiste «Workspace | Activity | Preview»; linke/rechte Panel als Overlay-Drawer; gleicher Breakpoint wie `MainLayout` Sidebar | `WorkspacePage.tsx`, `layouts/MainLayout.tsx` |
| **Dateien per Drag** | Overlay «Dateien hier ablegen» auf der **gesamten** Center-`main`-Fläche; Upload + `pendingFiles` | `WorkspacePage.tsx` (`onDragEnter`/`Drop` auf `<main>`) |
| **Prompt-Zeile** | Textarea, `+` Datei, optional Quellen-Picker, Provider-Multi-Select, Voice, Send/Stop; `@file` Autocomplete | `pages/views/workspace/WorkspaceInput.tsx` |
| **Drag auf Prompt-Bereich** | Nur **`application/tree-items`** (Baum) und **`application/chat-id`** (Chat-Referenz) — kein natives File-Drop im Input-Wrapper (Dateien laufen über Parent-`main`) | `WorkspaceInput.tsx` (`_handlePromptDragOver` / `_handlePromptDrop`) |
| **Neuer Chat** | `workspace.resetToNew` an UDB gebunden; in **Chats-Tab** Toolbar Button `+` mit `title="Neuer Chat"` | `WorkspacePage.tsx``UnifiedDataBar``ChatsTab.tsx` |
| **Billing-Funktionalität** | `BillingDataView`: Tabs Übersicht / Statistik / Transaktionen, Balance Cards, Hinweis auf Admin-Pfad für Aufladung | `pages/billing/BillingDataView.tsx`, `hooks/useBilling.ts`, `api/billingApi.ts` |
| **Guthaben im UI** | User-Menü: Eintrag «Guthaben» → `/billing/transactions` | `components/Navigation/UserSection.tsx` |
| **Quellen / Verbindungen** | Ausführlicher `SourcesTab` (Browse, Active Sources, Neutralize) | `components/UnifiedDataBar/SourcesTab.tsx` |
| **Login** | Logo, Credentials, Microsoft/Google, Registrierung, Kurz-Disclaimer KI/Datenschutz | `pages/Login.tsx`, `Login.module.css` |
| **Rechtstexte** | Modal «Rechtliche Hinweise» + Links zu statischen HTML-Seiten | `UserSection.tsx` |
### Konkrete Issues (Lücken vs. Meeting-Feedback)
| # | Problem | Ursache im Code / Verhalten |
|---|---------|------------------------------|
| I1 | **Eingabe wirkt «versteckt»** | Chat-Fläche frisst vertikal Platz; Prompt unten, enges Fenster + zwei Sidebars → Mittelspalte wird sehr schmal (&gt;1024px, beide Sidebars offen). Kein **Empty-State** in `ChatStream`, der die Eingabe einrahmt oder zur Aktion führt. |
| I2 | **«Wo tippe ich?» / kein ChatGPT-Balken** | Textarea ist funktional, aber **Placeholder auf Englisch** (`Type a message...`); visuell keine «Hero»-Eingabe. Sekundäraktionen (`+`, 🔗, Voice, Provider) stehen **in einer Zeile** neben dem Feld — bei wenig Breite wirkt das «nur ein Plus». |
| I3 | **Neuer Chat unsichtbar** | Nur **`+`** in `ChatsTab` Toolbar; wenn linke Spalte eingeklappt oder Mobile-User nicht auf Tab «Chats» wechselt, fehlt ein **zentrale CTA** in der Mitte. |
| I4 | **Schmale Desktop-Breite (ca. 10251280px)** | `isMobile` ist **false**, also **beide** Sidebars standardmäßig aktiv (280px + 320px + Handles). Zentrum `flex: 1`, `minWidth: 0` — Eingabe bleibt im DOM, wirkt aber «Wischiwaschi» oder abgeschnitten. Meeting: «A4-Fenster» genau diese Zone. |
| I5 | **Dateien: Entdeckbarkeit** | Vollflächen-Drop existiert, aber ohne **dauerhaften Hinweis** im leeren Chat; Nutzer erwarten oft Drop **direkt auf das Textfeld**. |
| I6 | **Vertrauen / Schweiz / Partner** | Login: **kein** Hosting-Hinweis, kein Partner-Strip, kein ® am Logo in der UI (nur Bildasset — rechtlich/Marken separat klären). Compliance-Texte eher in `e-compliance/` und statischen HTML, nicht **scanbar** auf Login. |
| I7 | **Billing / Pricing Auffindbarkeit** | Funktional stark (`BillingDataView`), aber **Einstieg** primär: Nav-Baum (`GET /api/navigation`, siehe Gateway `NAVIGATION_SECTIONS`) + verstecktes User-Menü «Guthaben». Kein **Dashboard-Teaser** nach erstem Login. |
| I8 | **Connector-Sorge** | `SourcesTab` ist technisch mächtig, aber ohne **kuratierte Erstnutzer-Copy** («Verbindung ist read-only / nichts kaputt») am Einstieg — Meeting-Thema «baue ich Scheisse». |
| I9 | **Informationsdichte** | Workspace + UDB + rechte Spalte parallel; kein **progressives** Onboarding in der Mitte (ausser globalem OnboardingWizard nach Google). |
---
## Umsetzungsplan (integriert)
Ziele: Issues I1I9 adressieren, **ohne** Billing-Logik oder Gateway-Tarife neu zu erfinden. Reihenfolge nach **Aufwand × Wirkung** für KMU-Erstnutzung.
### Phase A — Quick Wins (13 Tage)
| Task | Änderung | Dateien / Hinweise |
|------|-----------|-------------------|
| A1 | Placeholder + primäre Labels **DE** (und i18n Keys, falls `locales` für Workspace genutzt werden soll) | `WorkspaceInput.tsx` — z. B. «Frage stellen oder @Dateiname für Kontext» |
| A2 | **Empty State** in der Mitte: kurzer Titel, Bullet «Hier unten Frage eingeben», «Dateien auf die Fläche ziehen», Button **Neuer Chat** (ruft `onCreateNew`/`resetToNew` — Props von `WorkspacePage` durchreichen) | `ChatStream.tsx` + optionell schmale Props von `WorkspacePage.tsx` |
| A3 | **Neuer Chat** zusätzlich: Button in der **mittleren Kopfzeile** (nur Desktop) oder neben Mobile-«Workspace»-Leiste, sichtbar ohne UDB | `WorkspacePage.tsx` |
| A4 | Billing-Hinweis für **Nicht-Admins**: ein Zeiler im Empty State oder unter Prompt mit Link zu Hilfe («Guthaben: Administrator») — Text mit `BillingDataView` / BalanceCard abgleichen | `ChatStream` oder `WorkspacePage`, Copy-only |
### Phase B — Layout & Breakpoints (35 Tage)
| Task | Änderung | Dateien / Hinweise |
|------|-----------|-------------------|
| B1 | **Zwischen-Breakpoint** (z. B. `≤1280` oder `≤1360`): **automatisch linke und/oder rechte Sidebar einklappen** oder nur eine Sidebar standardmäßig offen, damit `mindestens ~480px` für die Mittelspalte garantiert sind | `WorkspacePage.tsx``useEffect` auf `innerWidth` + lokaler State, dokumentierte Schwellwerte |
| B2 | Optional: **minWidth** auf `<main>` mit «Seite zu schmal»-Hinweis statt silent squeeze | `WorkspacePage.tsx` |
| B3 | **Visuelle Hierarchie Prompt**: Eingabezeile leicht hervorgehoben (Schatten/Rand), ggf. erste Zeile höher (`minHeight`) | `WorkspaceInput.tsx` oder ausgelagertes CSS Module |
| B4 | E2E/Visuell: Viewports **1100 / 1200 / 1280 / 1440** in Testplan festhalten | Playwright oder manuelle Matrix |
### Phase C — Vertrauen & Marketing-UI (24 Tage, abhängig von Legal)
| Task | Änderung | Dateien / Hinweise |
|------|-----------|-------------------|
| C1 | Wiederverwendbare **`TrustFooter` / `TrustStrip`**: Zeile Hosting Schweiz (Formulierung mit Legal abgleichen — ggf. Verweis auf [e-compliance/security-overview.md](../../e-compliance/security-overview.md)) | Neue Komponente unter `components/`, einbinden in `Login.tsx`, optional `Register`, optional `MainLayout` Footer |
| C2 | **Recommended by** — statische Logos/Links (max. 5) nur nach **Partner-Freigabe** | Gleiche Komponente; Assets unter `public/` |
| C3 | Swiss **®** am Logo nur nach Markenfreigabe — sonst Textlink «Marke» | `Login.module.css` / Layout-Logo |
| C4 | **SourcesTab** oder erster Besuch «Quellen»: ein **Info-Banner** (12 Sätze) zu sicherer Verbindung / keine Zerstörung von Quelldaten — mit Product Owner fact-checken | `SourcesTab.tsx` oben |
### Phase D — Billing-Discovery (23 Tage)
| Task | Änderung | Dateien / Hinweise |
|------|-----------|-------------------|
| D1 | Nach Login: **einmaliger** Banner oder Home-Teaser «Guthaben & Nutzung» mit Link zu `/billing/transactions` (nur wenn Route erlaubt — Permission prüfen wie andere Nav-Items) | `MainLayout.tsx`, `App.tsx` Home-Route, oder dedizierte `HomePage` — je nachdem wo Landing liegt |
| D2 | Optional: **kleine Balance-Zahl** in UserSection neben Avatar (nur wenn API schon geladen wird und Mandate eindeutig) — Performance/UX mit `useBilling` prüfen | `UserSection.tsx` |
| D3 | Gateway: Navigations-**Label/Reihenfolge** für Billing in «Meine Sicht» nach oben ziehen (wenn gewünscht) — **kein** Frontend-Workaround ohne Backend | `gateway` `NAVIGATION_SECTIONS` / `mainSystem.py` (siehe Wiki navigation.md) |
### Phase E — Feinschliff (laufend)
| Task | Änderung |
|------|-----------|
| E1 | `WorkspaceInput`: optional natives **File** im Prompt-`onDragOver`/`Drop` spiegeln (gleiche Logik wie `WorkspacePage._uploadAndAttach`) — dann expliziter Drop auf Eingabe |
| E2 | i18n: alle neuen Strings in `locales/` |
| E3 | Nach Merge: `b-reference/frontend-nyla/architecture.md` um Workspace-UX-Notizen ergänzen |
### Abhängigkeiten & Risiken
- **D3** erfordert Gateway-Deploy und gehört fachlich zu «IA», nicht nur CSS.
- **C1C3** müssen mit **Legal/Marketing** sign-off; keine konkreten Hosting-Anbieter-Namen ohne Vertragslage.
- **D1** braucht klare Regel, wann der Banner **nicht** nervt (localStorage `dismissed`).
---
## Entscheidungen
| Datum | Entscheidung | Begründung |
|-------|-------------|------------|
| 2026-04-07 | Plan aus Meeting-Transkript abgeleitet; Fokus UI/UX, nicht Pricing-Tarife | Entscheidungen zu Tarifen und Modellen sind separat zu treffen |
| 2026-04-07 | Codebase-Audit gegen `frontend_nyla` — Umsetzung in Phasen AE | Issues I1I9 und bestehende Bausteine im Dokument festgehalten |
*Weitere Einträge nach UX-Review und Abstimmung Partner/Hosting-Formulierung.*
## Umsetzungs-Checkliste
Die detaillierte Aufgabenzerlegung steht in **Umsetzungsplan** (Phasen AE). Hier die Cross-Cutting-Checks:
**Phase A (Quick Wins)**
- [ ] A1: `WorkspaceInput.tsx` — DE-Placeholder / Copy
- [ ] A2: `ChatStream.tsx` + Props — Empty State + Kurzhelp
- [ ] A3: `WorkspacePage.tsx` — «Neuer Chat» sichtbar ohne UDB
- [ ] A4: Copy für Nicht-Admins (Guthaben)
**Phase B (Layout)**
- [ ] B1B2: `WorkspacePage.tsx` — Zwischen-Breakpoint / Sidebar-Strategie
- [ ] B3: `WorkspaceInput.tsx` — visuelle Hierarchie Eingabe
- [ ] B4: Viewport-Testmatrix dokumentiert
**Phase C (Trust)**
- [ ] C1C3: Trust-Komponente + Login/Register/Layout — Legal OK
- [ ] C4: `SourcesTab.tsx` — Sicherheits-Banner
**Phase D (Billing-Discovery)**
- [ ] D1: Home / nach Login — Teaser-Link Billing
- [ ] D2: optional `UserSection.tsx` — Balance-Snippet
- [ ] D3: optional Gateway — `NAVIGATION_SECTIONS` Billing-Prominenz
**Phase E / Plattform**
- [ ] E1: optional File-Drop auf Prompt synchron zu `WorkspacePage`
- [ ] E2: `locales/*` für neue Strings
- [ ] E3: Wiki `b-reference/frontend-nyla/architecture.md` aktualisieren
**Querschnitt**
- [ ] API-Endpunkte: nur bei D2/D3 oder neuen Summary-APIs nötig
- [ ] DB-Migration: nein (Planstand)
- [ ] RBAC: Billing-Routen nur anzeigen wenn wie heute erlaubt
- [ ] Neutralisierung: nur Copy in C4, kein Verhalten
- [ ] Navigation / Routing: nur bei D1/D3
- [ ] Billing-Impact: Darstellung/Auffindbarkeit, keine Tariflogik
## Akzeptanzkriterien
| # | Kriterium (Given-When-Then) | Prio |
|---|---------------------------|------|
| 1 | Given ein eingeloggter User ohne verbundene Datenquellen, When er den AI-Workspace öffnet (Desktop ≥1280px und Mobile-Viewport), Then ist die Haupt-Eingabe für Prompt/Frage ohne Hover oder Scrollen in den ersten sichtbaren 50 % des Hauptbereichs erkennbar | must |
| 2 | Given schmales Desktop-Fenster (z. B. 9001024px Breite), When der AI-Workspace angezeigt wird, Then bleibt die Prompt-Eingabe zugänglich (kein «verschwindendes» Chatfenster ohne Alternativlayout) | must |
| 3 | Given Login- oder Startansicht, When der User die Seite scannt (510 Sekunden), Then sind mindestens ein **Schweiz-Hosting**-Hinweis und der **Partner-/Recommended-by**-Block gemäss kuratierter Liste sichtbar oder mit einem klaren «Vertrauen»-Einstieg erreichbar | should |
| 4 | Given User mit Rolle Admin, When er nach dem ersten Login Orientierung zu Kosten sucht, Then führt ein in der UI sichtbarer Einstieg innerhalb ≤2 Klicks zur Billing-/Usage-Übersicht (bestehender Pfad darf erhalten bleiben, muss aber nicht mehr alleinige Entdeckungsquelle sein) | should |
| 5 | Given AI-Workspace, When der User eine neue Unterhaltung beginnen will, Then ist eine explizite «Neuer Chat»- oder gleichwertige Handlung sichtbar und erklärt sich ohne externe Doku | should |
| 6 | Given leerer Chat ohne Nachrichten, When der User eine Datei einbinden will, Then ist erkennbar, ob und wie Drag-and-Drop in den Prompt funktioniert (Text oder Dropzone) | could |
## Testplan
| ID | AC | Art | Automatisiert | Repo-Pfad | Status |
|----|----|-----|--------------|-----------|--------|
| T1 | 1,2 | e2e / manuell Viewports | teilweise | `frontend_nyla``WorkspacePage.tsx` bei 1100/1200/1280/1440px | pending |
| T2 | 3 | manuell UX-Review | nein | — | pending |
| T3 | 4 | manuell Rolle Admin | nein | — | pending |
| T4 | 5,6 | manuell Explorer/Safari/Edge | nein | — | pending |
## Links
- Input: [input2026-04-ui-enhancement-inbputs.txt](./input2026-04-ui-enhancement-inbputs.txt)
- Produkt-Überblick: [README.md](../../README.md)
- Frontend-Referenz: [b-reference/frontend-nyla/architecture.md](../../b-reference/frontend-nyla/architecture.md)
- Navigation API: [b-reference/platform/navigation.md](../../b-reference/platform/navigation.md)
- Billing (Backend-Kontext): [b-reference/gateway/billing.md](../../b-reference/gateway/billing.md)
- Compliance (Copy-Grundlage): [e-compliance/security-overview.md](../../e-compliance/security-overview.md)
**Code (Haupt-Einstiegspunkte, Repo `frontend_nyla`)**
- `src/pages/views/workspace/WorkspacePage.tsx` — Layout, Mobile, Drag-Drop, UDB
- `src/pages/views/workspace/WorkspaceInput.tsx` — Prompt, Anhänge, STT
- `src/pages/views/workspace/ChatStream.tsx` — Nachrichtenliste
- `src/components/UnifiedDataBar/ChatsTab.tsx` — Chat-Liste, `+` Neuer Chat
- `src/components/UnifiedDataBar/SourcesTab.tsx` — Verbindungen / Quellen
- `src/pages/Login.tsx` — Login-Shell
- `src/components/Navigation/UserSection.tsx` — Guthaben-Menü
- `src/pages/billing/BillingDataView.tsx` — Nutzer-Billing
- PR: …
- Issue: …
## Abschluss
- [ ] b-reference/ aktualisiert (`frontend-nyla/architecture.md`, ggf. `platform/navigation.md`)
- [ ] TOPICS.md aktualisiert (falls neues Thema «Trust-UI» o. ä.)
- [ ] Dieses Dokument → `z-archive/` verschoben (nach Release)

View file

@ -0,0 +1,229 @@
<!-- status: plan -->
<!-- started: 2026-04-07 -->
<!-- component: gateway -->
# Trustee Tooling Overhaul & PWG Demo Preparation
## Beschreibung und Kontext
Für den PWG-Inspirationsworkshop (16. April 2026) werden drei Use Cases in PORTA demonstriert. Use Case 1 (Belegverarbeitung + Budgetkontrolle) und Use Case 3 (Datenneutralisierung) erfordern Code-Anpassungen im Trustee-Feature und im Agent-Tooling.
**Business-Treiber:** PWG AG (gemeinnützige Wohnungsstiftung Zürich, 200+ Liegenschaften, Abacus als Hauptsystem) evaluiert PORTA. Der Workshop ist die erste Live-Demo — Plattform-Tiefgang und funktionierende Schnittstellen sind entscheidend.
**Risiko bei Nicht-Umsetzung:** Demo scheitert an fehlenden Tools (Agent kann keine Buchhaltungsdaten lesen), langsamer Performance (jede Query startet neuen Sub-Agent-Loop) oder fehlendem Workflow im Graphical Editor.
Parallel zur Demo-Vorbereitung wird das Trustee-Tooling grundlegend überarbeitet. Die aktuelle Architektur hat strukturelle Schwächen, die auch im Produktivbetrieb problematisch sind.
**Hinweis:** Die Automation Unification (v1/v2 → Graphical Editor) ist abgeschlossen (siehe `c-work/3-validate/2026-04-automation-unification.md`, Status: done). Dieses Dokument baut auf dem konsolidierten System auf: Feature `graphicalEditor`, DB `poweron_graphicaleditor`, konsolidierter Scheduler.
## Fokus und kritische Details
### Ist-Zustand Trustee-Tooling (Analyse)
| Fähigkeit | Status | Problem |
|-----------|--------|---------|
| **Daten lesen (Agent)** | `queryFeatureInstance` → Sub-Agent mit `browseTable`/`queryTable` | Jeder Call öffnet neue DB-Connection + startet 5-Runden-Agent-Loop mit AI-Calls. Kein Caching. Langsam (~5-15s pro Query). |
| **Daten aus Buchhaltung importieren** | `AccountingDataSync.importData()` via REST-Endpoint | Full-clear + Full-write bei jedem Import. Kein inkrementeller Sync. Kein Agent-Zugriff (nur REST). |
| **Daten schreiben (Agent)** | Nicht vorhanden | Agent kann keine Trustee-Positionen erstellen oder ändern. |
| **Daten aggregieren** | Nicht vorhanden | Sub-Agent hat nur row-level Tools. Keine SQL-Aggregationen (SUM, GROUP BY). Für Budgetvergleiche muss der Agent alle Rows laden und selbst rechnen. |
| **Chart of Accounts** | `AccountingBridge.getChartOfAccounts()` mit Cache auf `TrusteeAccountingConfig` | Funktioniert, aber nur für Bridge-interne Nutzung. Agent hat keinen direkten Zugriff. |
| **Graph-Editor Nodes (Trustee)** | 3 Nodes in `nodeDefinitions/trustee.py`: `extractFromFiles`, `processDocuments`, `syncToAccounting` | Alle `dynamicMode=False` — nicht als Agent-Tools verfügbar. Für Graph-Editor nutzbar. Kein Node für `refreshAccountingData` / Datenimport. |
| **Graph-Editor Nodes (SharePoint)** | 6 Nodes in `nodeDefinitions/sharepoint.py`: findFile, readFile, uploadFile, listFiles, downloadFile, copyFile | Vorhanden und funktional. `listFiles` + `downloadFile` reichen für den Demo-Flow. |
| **Graph-Editor Nodes (Flow)** | 5 Nodes: ifElse, switch, loop, merge, delay | Loop-Node vorhanden (`flow.loop`). Nötig für "für jede Datei aus SharePoint → Trustee-Pipeline". |
| **Node-Kategorie `trustee`** | Nodes nutzen `category: "trustee"` | **Fehlt in `nodeRegistry.getNodeTypesForApi()` Categories-Liste** (Zeile 63-73) — Trustee-Nodes werden im Editor nicht unter eigener Kategorie angezeigt. |
| **Toolbox `trustee`** | Nicht vorhanden | Die Toolbox Registry (`toolboxRegistry.py`) hat Toolboxes für email, sharepoint, clickup, jira, workflow — aber keine für Trustee. Für den Agent-Zugriff auf Trustee-Actions (`dynamicMode=True`) wäre eine Toolbox sinnvoll. |
### Performance-Problem `queryFeatureInstance`
Der Hauptgrund für die langsame Query-Performance:
1. **Neuer Sub-Agent pro Call**`runFeatureDataAgent` startet einen eigenen Agent-Loop (max 5 Runden, je ein AI-Call) für jede Frage. Das bedeutet: Main-Agent stellt Frage → Sub-Agent macht 1-3 AI-Calls um SQL zu generieren → Sub-Agent antwortet → Main-Agent verarbeitet.
2. **Neue DB-Connection pro Call**`DatabaseConnector` wird jedes Mal neu instanziiert und geschlossen.
3. **Kein Result-Cache** — Identische Fragen werden jedes Mal neu beantwortet.
## Ziel und Nicht-Ziele
**Ziel:**
- Agent kann Trustee-Buchhaltungsdaten lesen (gecacht oder frisch vom externen System)
- Agent kann Aggregationen auf Trustee-Daten ausführen (SUM, GROUP BY für Budgetvergleiche)
- Graphical-Editor-Workflow für Belegverarbeitung (SharePoint → Trustee Import+Sync) funktioniert
- Performance von Feature-Data-Queries deutlich verbessert
- Demo für PWG-Workshop läuft stabil end-to-end
**Explizit NICHT:**
- Kein vollständiger Umbau des Sub-Agent-Patterns
- Keine neuen Abacus-API-Endpoints (nutzen bestehenden Connector)
- Keine Frontend-Änderungen am Trustee-UI
## Betroffene Module
- Gateway: `features/trustee/`, `serviceCenter/services/serviceAgent/` (inkl. `toolboxRegistry.py`), `workflows/methods/methodTrustee/`, `features/graphicalEditor/nodeDefinitions/`, `features/graphicalEditor/nodeRegistry.py`
- Frontend: keine Änderungen
- DB-Migration: nein (nutzt bestehende `TrusteeData*`-Tabellen in Feature-DB `poweron_trustee`)
- Graphical Editor: Node-Definitionen + Kategorie-Registry + Workflow-Konfiguration für Demo
## Entscheidungen
| Datum | Entscheidung | Begründung |
|-------|-------------|------------|
| 2026-04-07 | Neues Tool `refreshTrusteeData` statt Erweiterung von `queryFeatureInstance` | Separation of Concerns: Sync ist eine schreibende Operation, Query ist lesend. Agent entscheidet selbst, ob er zuerst refreshen muss. |
| 2026-04-07 | `aggregateTable`-Tool im Sub-Agent statt SQL in `queryTable` | Saubere Trennung: row-level vs. aggregate. Verhindert SQL-Injection-Risiko bei freien GROUP BY-Ausdrücken. |
| 2026-04-07 | DB-Connection-Pooling für Feature-Data-Agent statt Connection-per-Call | Grösster Performance-Hebel. Connection-Aufbau ist teuer (~200ms), Pool eliminiert das. |
| 2026-04-07 | Result-Cache auf WorkflowMemory-Ebene | Nutzt bestehendes Konzept (WorkflowMemory mit Embedding). Agent kann gecachte Ergebnisse aus früheren Runden wiederverwenden. |
## Umsetzungs-Checkliste
### Phase 1: Trustee Agent-Tools (Prio: hoch — Blocker für Demo UC1 Teil B)
- [x] **`refreshTrusteeData`** — Neue Workflow-Action `trustee.refreshAccountingData` mit `dynamicMode=True`
- Prüft `TrusteeAccountingConfig.lastSyncAt` — wenn älter als Schwellwert (z.B. 1h) oder Daten leer → triggert `AccountingDataSync.importData()`
- Parameter: `featureInstanceId` (required), `forceRefresh` (optional, default false), `dateFrom`/`dateTo` (optional)
- Rückgabe: Summary (Anzahl Records pro Tabelle, Sync-Dauer, ob frisch oder gecacht)
- Registrierung in `MethodTrustee.__init__` analog zu bestehenden Actions
- [x] **`aggregateTable`** — Neues Tool im Feature-Data-Sub-Agent (`featureDataAgent.py`)
- SQL-Aggregationen: `SUM`, `COUNT`, `AVG`, `MIN`, `MAX`
- `GROUP BY` auf vordefinierte Felder (Whitelist pro Tabelle)
- Scope-Filter wie bei `queryTable` (featureInstanceId + mandateId)
- Beispiel: `aggregateTable(tableName="TrusteeDataJournalLine", aggregate="SUM", field="debitAmount", groupBy="costCenter")`
### Phase 2: Graphical-Editor Node-Definitionen (Prio: hoch — Blocker für Demo UC1 Teil A)
**Ist-Zustand Node-Registry (`features/graphicalEditor/nodeDefinitions/`):**
| Datei | Nodes | Status |
|-------|-------|--------|
| `trustee.py` | `extractFromFiles`, `processDocuments`, `syncToAccounting` | Vorhanden, aber kein Node für Datenimport/Refresh |
| `sharepoint.py` | `findFile`, `readFile`, `uploadFile`, `listFiles`, `downloadFile`, `copyFile` | Vorhanden, ausreichend für Demo |
| `flow.py` | `ifElse`, `switch`, `loop`, `merge`, `delay` | Vorhanden, Loop-Node nötig für Demo |
**Anpassungen:**
- [x] **Kategorie `trustee` in `nodeRegistry.py` ergänzen**
- In `getNodeTypesForApi()``categories`-Liste (Zeile 63-73) fehlt `{"id": "trustee", "label": {"en": "Trustee", "de": "Treuhand", "fr": "Fiduciaire"}}`
- Ohne diese Kategorie werden die Trustee-Nodes in der Node-Palette des Graphical Editors nicht unter einer eigenen Gruppe angezeigt
- [x] **Neuer Node `trustee.refreshAccountingData`** in `nodeDefinitions/trustee.py`
- Mapped auf neue Workflow-Action `trustee.refreshAccountingData` (Phase 1)
- Parameter: `featureInstanceId` (required), `forceRefresh` (optional), `dateFrom`/`dateTo` (optional)
- Kategorie: `trustee`, Icon: `mdi-database-refresh`, Color: `#4CAF50`
- Damit kann der Datenimport auch als Flow-Node genutzt werden (z.B. "Jeden Morgen Daten aus Abacus importieren")
- [~] **Neuer Node `trustee.importAndProcess`** in `nodeDefinitions/trustee.py` (optional, Convenience) — **übersprungen**: bestehende 3 Nodes funktionieren dank Output-Chaining-Fix (s.u.)
- Kombiniert die Pipeline `extractFromFiles``processDocuments``syncToAccounting` in einem einzigen Node
- Vereinfacht den Demo-Flow auf 2 Nodes statt 4 (SharePoint Download → Trustee Import+Process+Sync)
- Parameter: `connectionId`, `sharepointFolder`, `featureInstanceId`, `prompt`
- Falls zu aufwändig: bestehende 3 Nodes einzeln im Flow verketten (funktioniert, ist aber visuell weniger eindrucksvoll)
- [x] **Toolbox `trustee` in `toolboxRegistry.py` registrieren** (für Agent-Zugriff)
- Analog zu `sharepoint`, `email`, `clickup` — Toolbox mit `requiresConnection: false` (Trustee hat eigene Config)
- Enthält `refreshTrusteeData` (Phase 1) und ggf. weitere Trustee-Actions wenn `dynamicMode=True`
- Ermöglicht dem Agent, Trustee-Tools via `requestToolbox("trustee")` zu aktivieren
- [x] **Bestehende Trustee-Nodes prüfen und angepasst**
- `trustee.extractFromFiles`: `_paramMap` korrekt (`connectionId` → `connectionReference`), Output = `ActionDocument`-Liste → wird via `model_dump()` serialisiert
- `trustee.processDocuments`: **Fix implementiert** — neue `_resolveDocumentList()` Funktion erkennt sowohl Graph-Editor-Output (Liste von Dicts mit `documentData`) als auch Chat-Referenzen (Fallback). Kein Chat-Service im Graph-Editor nötig.
- `trustee.syncToAccounting`: **Fix implementiert** — neue `_resolveFirstDocument()` Funktion mit gleicher Dual-Path-Logik
- [x] **Output-Chaining verifiziert und gefixt:**
- `actionNodeExecutor.py` Zeile 828: `ActionDocument``model_dump()` → Dict mit `documentName`, `documentData`, `mimeType`
- `actionNodeExecutor.py` Zeile 836-837: Output enthält `documents` + `documentList` (identisch)
- `_getDocumentsFromUpstream()` (Zeile 237) liest `documents` oder `documentList` aus dem Output-Dict
- Zeile 569: `resolvedParams.setdefault("documentList", docs)` mergt die Dicts in den nächsten Node
- **Problem war:** `processDocuments` und `syncToAccounting` nutzten `DocumentReferenceList.from_string_list()` + `chat.getChatDocumentsFromDocumentList()` — funktioniert nur im Chat-Kontext, nicht im Graph-Editor
- **Lösung:** Beide Actions erkennen jetzt direkt übergebene Dicts (Graph-Editor-Pfad) und nutzen Chat nur als Fallback — **manuell testen**
### Phase 3: Performance (Prio: hoch — spürbar in jeder Demo)
- [x] **DB-Connection-Pooling** für Feature-Data-Agent
- Singleton `DatabaseConnector` pro Feature-DB (z.B. `poweron_trustee`) statt Connection-per-Call
- Pool in `_featureSubAgentTools.py` oder zentral im ServiceCenter
- Connection-Reuse über `featureDbConnPool[featureDbName]`
- [x] **Sub-Agent Result-Caching**
- Cache-Key: `(featureInstanceId, question_hash, lastSyncAt)`
- Invalidierung bei neuem Sync (`lastSyncAt` ändert sich)
- TTL: 5 Minuten (konfigurierbar)
- Speicherort: In-Memory Dict im Agent-Kontext (pro Workflow-Session)
### Phase 4: Graphical-Editor Workflow für Demo (Prio: hoch — nötig für UC1 Teil A)
- [ ] **Workflow im Graphical Editor bauen:** SharePoint Read Files Loop → Trustee Import+Sync
- Trigger: `trigger.manual` (mit Hinweis "könnte automatisch laufen")
- Node 1: `sharepoint.listFiles` → Ordner mit Belegen
- Node 2: `flow.loop` über die Dateiliste
- Node 3 (im Loop): `sharepoint.downloadFile` → PDF herunterladen
- Node 4 (im Loop): `trustee.extractFromFiles` → Belege extrahieren
- Node 5 (im Loop): `trustee.processDocuments` → Buchungen erstellen
- Node 6 (nach Loop): `trustee.syncToAccounting` → Sync mit Abacus
- Alternativ: `trustee.importAndProcess` Convenience-Node (Phase 2) statt Nodes 4-6
- Testen mit 3-4 Musterbelegen
- Workflow als System-Template speichern (`templateScope: system`)
- [ ] **Musterbelege erstellen:** Handwerkerrechnung, Nebenkostenabrechnung, Bankbeleg, Versicherungsbeleg (PDFs)
### Phase 5: Demo-Daten & Testläufe (Prio: mittel)
- [ ] Budget-Excel erstellen (Soll-Werte 2026 pro Kostenstelle/Liegenschaft)
- [ ] Demo-Prompt für Budgetkontrolle vorbereiten und testen
- [ ] CommCoach-Personas für Immobilien-Kontext erstellen
- [ ] Neutralisierungs-Demo mit fiktivem Mieterdossier testen
- [ ] Demo-Mandant "PWG Demo" sauber aufsetzen
- [ ] Alle 3 Use Cases end-to-end durchspielen
## Akzeptanzkriterien
| # | Kriterium (Given-When-Then) | Prio |
|---|---------------------------|------|
| 1 | Given Trustee-Instanz mit Abacus-Config, When Agent `refreshTrusteeData` aufruft, Then werden Daten aus Abacus in `TrusteeData*`-Tabellen importiert und Summary zurückgegeben | must |
| 2 | Given gecachte Daten (lastSyncAt < 1h), When Agent `refreshTrusteeData` ohne `forceRefresh` aufruft, Then wird kein externer Sync ausgelöst und gecachte Counts zurückgegeben | must |
| 3 | Given Trustee-Daten in DB, When Sub-Agent `aggregateTable` mit SUM/GROUP BY aufruft, Then kommen korrekte Aggregationen zurück (verifiziert gegen manuelle Berechnung) | must |
| 4 | Given identische Query innerhalb 5 Min, When `queryFeatureInstance` erneut aufgerufen wird, Then wird gecachtes Ergebnis zurückgegeben (kein neuer Sub-Agent-Loop) | should |
| 5 | Given Graphical Editor geöffnet, When Node-Palette geladen wird, Then erscheint Kategorie "Treuhand" mit allen Trustee-Nodes (inkl. neuem `refreshAccountingData`) | must |
| 6 | Given Workflow im Graphical Editor mit trigger.manual → sharepoint.listFiles → flow.loop → trustee.extractFromFiles → processDocuments → syncToAccounting, When Workflow manuell gestartet wird, Then werden PDFs aus SharePoint geladen, extrahiert und als Positionen mit Sync-Status im Trustee angezeigt | must |
| 7 | Given Trustee-Pipeline im Flow (extract → process → sync), When Node A Output an Node B weitergereicht wird, Then wird `documentList`-Referenz korrekt aufgelöst (Output-Chaining funktioniert) | must |
| 8 | Given Budget-Excel im Workspace + Trustee-Daten, When Budgetkontrolle-Prompt ausgeführt wird, Then erstellt Agent Soll/Ist-Vergleich mit Charts und sendet per Mail | must |
## Testplan
| ID | AC | Art | Automatisiert | Repo-Pfad | Status |
|----|----|-----|--------------|-----------|--------|
| T1 | 1 | api | nein (manuell mit Abacus-Sandbox) | — | pending |
| T2 | 2 | api | ja | gateway/tests/features/trustee/test_refresh_tool.py | pending |
| T3 | 3 | api | ja | gateway/tests/features/trustee/test_aggregate_table.py | pending |
| T4 | 4 | api | ja | gateway/tests/serviceAgent/test_feature_data_cache.py | pending |
| T5 | 5 | ui | nein (manuell) | — | pending |
| T6 | 6 | e2e | nein (manuell) | — | pending |
| T7 | 7 | api | ja | gateway/tests/workflows/graphicalEditor/test_node_chaining.py | pending |
| T8 | 8 | e2e | nein (manuell) | — | pending |
## Links
- Use Cases: `pamocreate/projects/poweron/customer-pwg/20260407 use-cases-workshop.md`
- Automation Unification (done): `wiki/c-work/3-validate/2026-04-automation-unification.md`
- Trustee Accounting Bridge: `gateway/modules/features/trustee/accounting/accountingBridge.py`
- Accounting Data Sync: `gateway/modules/features/trustee/accounting/accountingDataSync.py`
- Feature Data Agent: `gateway/modules/serviceCenter/services/serviceAgent/featureDataAgent.py`
- Feature Data Provider: `gateway/modules/serviceCenter/services/serviceAgent/featureDataProvider.py`
- Feature Sub-Agent Tool: `gateway/modules/serviceCenter/services/serviceAgent/coreTools/_featureSubAgentTools.py`
- Toolbox Registry: `gateway/modules/serviceCenter/services/serviceAgent/toolboxRegistry.py`
- Abacus Connector: `gateway/modules/features/trustee/accounting/connectors/accountingConnectorAbacus.py`
- Node Registry: `gateway/modules/features/graphicalEditor/nodeRegistry.py`
- Trustee Nodes: `gateway/modules/features/graphicalEditor/nodeDefinitions/trustee.py`
- SharePoint Nodes: `gateway/modules/features/graphicalEditor/nodeDefinitions/sharepoint.py`
- Flow Nodes: `gateway/modules/features/graphicalEditor/nodeDefinitions/flow.py`
- Action Node Executor: `gateway/modules/workflows/automation2/executors/actionNodeExecutor.py`
- Execution Engine: `gateway/modules/workflows/automation2/executionEngine.py`
- Scheduler: `gateway/modules/workflows/scheduler/mainScheduler.py`
- Trustee Workflow Method: `gateway/modules/workflows/methods/methodTrustee/methodTrustee.py`
- Graphical Editor Feature: `gateway/modules/features/graphicalEditor/mainGraphicalEditor.py`
- Graphical Editor Datenmodell: `gateway/modules/features/graphicalEditor/datamodelFeatureGraphicalEditor.py`
## Abschluss
- [x] b-reference/gateway/workflow.md aktualisiert (neue Action `trustee.refreshAccountingData`)
- [x] b-reference/gateway/ai-agent.md aktualisiert (`aggregateTable` Tool im Sub-Agent, Trustee-Toolbox)
- [x] b-reference/gateway/automation.md aktualisiert (neue Trustee-Nodes + Kategorie in Node-Palette)
- [ ] TOPICS.md aktualisiert (falls neues Thema)
- [ ] Dieses Dokument → z-archive/ verschoben

View file

@ -1,5 +1,6 @@
<!-- status: plan -->
<!-- status: done -->
<!-- started: 2026-04-05 -->
<!-- completed: 2026-04-07 -->
<!-- component: gateway | frontend-nyla | platform -->
# Automation Unification -- Konsolidierung v1/v2/Workspace
@ -13,8 +14,8 @@ PowerOn hat drei teilweise ueberlappende Automatisierungssysteme: Automation v1
**Risiko bei Nicht-Umsetzung:** Wachsende Divergenz, doppelter Aufwand bei neuen Aktionen, inkonsistentes Verhalten fuer Endbenutzer.
**Leitprinzipien:**
- Keine Migration von Altdaten -- Automation v1 ist nicht produktiv, wird nicht migriert
- Automation v1 bleibt bestehen, bis es durch das neue Feature abgeloest ist
- Keine Migration von Altdaten -- Automation v1 war nicht produktiv, wurde nicht migriert
- Legacy-Features `automation` und `automation2` wurden entfernt (2026-04-07)
- Klare Datenmodelle mit definierten State Machines als stabile, erweiterbare Grundlage
- Klare Trennung von Mandant/Feature/Feature-Instanz und zugehoeriger RBAC-Logik
- Skalierbare AI-Tool-Architektur mit Toolboxes und Sub-Agents fuer 50-100+ Tools
@ -54,16 +55,16 @@ Die `workflows/methods/` Library (methodAi, methodOutlook, methodSharepoint, etc
### Identifizierte Inkonsistenzen
| # | Inkonsistenz |
|---|-------------|
| **I-1** | Zwei Datenmodelle: `AutomationDefinition` (v1) vs `Automation2Workflow` (v2) -- kein gemeinsames Workflow-Konzept |
| **I-2** | Zwei Datenbanken: `poweron_automation` vs `poweron_automation2` |
| **I-3** | Zwei Scheduler: v1 (inkrementell, callback `automation.changed`) vs v2 (full wipe + re-register, callback `automation2.workflow.changed`) |
| **I-4** | Zwei Execution Engines: `WorkflowManager` + `WorkflowProcessor` vs `executionEngine.executeGraph` |
| **I-5** | Kein AI-Chat im Graphical Editor |
| **I-6** | `WorkspaceInput` ist nicht als wiederverwendbare Komponente extrahiert |
| **I-7** | UDB nur in Workspace und CommCoach, nicht im Graphical Editor |
| **I-8** | AI Tools skalieren nicht: 50+ Tools ohne Gruppierungslogik, alle werden dem LLM gleichzeitig exponiert |
| # | Inkonsistenz | Status |
|---|-------------|--------|
| **I-1** | Zwei Datenmodelle: `AutomationDefinition` (v1) vs `Automation2Workflow` (v2) -- kein gemeinsames Workflow-Konzept | **behoben** -- Unified `AutoWorkflow` in Greenfield DB |
| **I-2** | Zwei Datenbanken: `poweron_automation` vs `poweron_automation2` | **behoben** -- Neue DB `poweron_graphicaleditor`, Legacy entfernt |
| **I-3** | Zwei Scheduler: v1 (inkrementell) vs v2 (full wipe + re-register) | offen (Phase 4) |
| **I-4** | Zwei Execution Engines: `WorkflowManager` + `WorkflowProcessor` vs `executionEngine.executeGraph` | offen (bewusst getrennt) |
| **I-5** | Kein AI-Chat im Graphical Editor | **behoben** -- EditorChatPanel mit SSE |
| **I-6** | `WorkspaceInput` ist nicht als wiederverwendbare Komponente extrahiert | offen (Phase 4) |
| **I-7** | UDB nur in Workspace und CommCoach, nicht im Graphical Editor | **behoben** -- UDB im Editor integriert |
| **I-8** | AI Tools skalieren nicht: 50+ Tools ohne Gruppierungslogik | offen (Phase 4: Toolbox Registry) |
---
@ -108,24 +109,26 @@ Die `workflows/methods/` Library (methodAi, methodOutlook, methodSharepoint, etc
+------------------------------------------------------------------------+
```
### Saeule 1: AI Service (besteht, zu erweitern)
### Saeule 1: AI Service (besteht, zu erweitern in Phase 4)
**Status:** Kern bereit (`serviceAi` + `serviceAgent` + `aicore`).
**Erweiterung:** Toolbox-Architektur fuer 50-100+ Tools (siehe Abschnitt Toolboxes).
**Status:** Kern bereit (`serviceAi` + `serviceAgent` + `aicore`). AI Chat im Editor integriert (EditorChatPanel).
**Offen:** Toolbox-Architektur fuer 50-100+ Tools (siehe Abschnitt Toolboxes, Phase 4).
### Saeule 2: Graphical Editor (Feature "graphicalEditor")
**Status:** Basis vorhanden (Automation2FlowEditor), zu erweitern.
**Status:** Implementiert. Legacy-Features `automation` und `automation2` entfernt.
| # | Funktionalitaet | Status |
|---|-----------------|--------|
| 1 | **Visual Flow Builder** -- Canvas, Nodes, Connections, Branching, Loops | besteht |
| 2 | **Node Palette** -- abgeleitet aus Toolbox-Registry, jede Action kann als Node exponiert werden | besteht |
| 3 | **AI Chat Sidebar** -- Agent mit Toolbox `"workflow"` fuer Graph-Manipulation | neu |
| 4 | **UDB Integration** -- UnifiedDataBar im Editor | neu |
| 5 | **Tracing/Debug Log** -- AutoStepLog mit Input-Snapshot, Duration, Error pro Node | zu erweitern |
| 1 | **Visual Flow Builder** -- Canvas, Nodes, Connections, Branching, Loops | umgesetzt |
| 2 | **Node Palette** -- Trigger, Flow, AI, Email, SharePoint, ClickUp, File, Trustee | umgesetzt |
| 3 | **AI Chat Sidebar** -- EditorChatPanel mit SSE-Streaming, Graph-Manipulation-Tools | umgesetzt |
| 4 | **UDB Integration** -- UnifiedDataBar mit Files + Sources Tabs, Mandate-gefiltert | umgesetzt |
| 5 | **Tracing/Debug Log** -- RunTracingPanel mit AutoStepLog-Anzeige | umgesetzt (Basis) |
| 6 | **Test Runner** -- Visual Highlighting, Step-by-Step, AI-assisted Debugging | zu erweitern |
| 7 | **Version Management** -- Draft/Published Lifecycle | neu |
| 7 | **Version Management** -- Draft/Published/Archived Lifecycle via CanvasHeader | umgesetzt |
| 8 | **Template Management** -- Save as Template, New from Template, Scope-Verwaltung | umgesetzt |
| 9 | **File/Source Attachments** -- Drag&Drop + Source-Picker im AI Chat (wie Workspace) | umgesetzt |
### Saeule 3: Automation Scheduler (zu konsolidieren)
@ -145,7 +148,7 @@ Die `workflows/methods/` Library (methodAi, methodOutlook, methodSharepoint, etc
### Saeule 4: Unified Action Library mit Toolboxes
**Status:** Infrastruktur besteht (`workflows/methods/` + `methodDiscovery` + `ActionExecutor`). Zu erweitern um Toolbox-Konzept (siehe eigener Abschnitt).
**Status:** Infrastruktur besteht (`workflows/methods/` + `methodDiscovery` + `ActionExecutor`). Trustee-Nodes hinzugefuegt. Toolbox-Konzept offen (Phase 4).
---
@ -804,6 +807,9 @@ class AutoWorkflow(PowerOnModel):
| `sharepoint.*` | `sharepoint` | entsprechend | `connectionId->connectionReference` |
| `clickup.*` | `clickup` | entsprechend | `connectionId->connectionReference` |
| `file.create` | `file` | `create` | `template->template` |
| `trustee.extractFromFiles` | `trustee` | `extractFromFiles` | `connectionId->connectionReference` |
| `trustee.processDocuments` | `trustee` | `processDocuments` | `documentList->documentList` |
| `trustee.syncToAccounting` | `trustee` | `syncToAccounting` | `documentList->documentList` |
### Execution-Routing
@ -927,10 +933,9 @@ gateway/modules/
| | +-- interfaceFeatureGraphicalEditor.py (DB: poweron_workflows)
| | +-- datamodelFeatureGraphicalEditor.py
| | +-- nodeDefinitions/
| | triggers.py, flow.py, input.py, ai.py, email.py, sharepoint.py, ...
| | triggers.py, flow.py, input.py, ai.py, email.py, sharepoint.py, clickup.py, file.py, trustee.py
| |
| +-- workspace/ <-- BLEIBT (AI Chat mit UDB)
| +-- automation/ <-- BLEIBT bis Abloesung
| +-- commcoach/ <-- BLEIBT
| +-- chatbot/ <-- BLEIBT
| +-- trustee/ <-- BLEIBT
@ -948,43 +953,45 @@ gateway/modules/
+-- workflows/
| +-- methods/ <-- BLEIBT (Unified Action Library)
| +-- processing/ <-- BLEIBT (ActionExecutor, methodDiscovery)
| +-- automation2/ <-- Graph Engine BLEIBT
| +-- scheduler/ <-- NEU (konsolidierter Scheduler)
| +-- automation2/ <-- Graph Engine BLEIBT (executionEngine)
| +-- scheduler/ <-- NEU (konsolidierter Scheduler, Phase 4)
| | +-- mainScheduler.py
| +-- automation/ <-- BLEIBT bis Abloesung
| +-- workflowManager.py <-- BLEIBT (fuer Workspace Dynamic Mode)
```
---
## Frontend Code-Struktur (Ziel)
## Frontend Code-Struktur (umgesetzt)
```
frontend_nyla/src/
|
+-- components/ <-- SHARED COMPONENTS
| +-- ChatBar/ <-- NEU (extrahiert aus WorkspaceInput)
| | ChatBar.tsx Props: onSend, onStop, onVoice,
| | fileAttachments, showProviderSelector, ...
| +-- ChatStream/ <-- NEU (extrahiert aus workspace/ChatStream)
| | ChatStream.tsx SSE-driven message stream, wiederverwendbar
| +-- UnifiedDataBar/ <-- BLEIBT
| +-- FlowEditor/ <-- RENAMED von Automation2FlowEditor
| +-- UnifiedDataBar/ <-- BLEIBT (Files + Sources Tabs, Mandate-gefiltert)
| +-- FlowEditor/ <-- Umgesetzt (ehemals Automation2FlowEditor)
| +-- editor/
| FlowEditor.tsx + AI Chat Panel
| FlowCanvas.tsx + Visual Run Tracing
| EditorChatPanel.tsx <-- NEU
| Automation2FlowEditor.tsx Hauptkomponente mit 3-Column Layout
| CanvasHeader.tsx Neu/Speichern/Vorlage/Version-Buttons
| EditorChatPanel.tsx AI Chat mit File/Source-Attachments
| RunTracingPanel.tsx Step-Log-Anzeige mit SSE Live-Push + Canvas-Highlighting
| NodeConfigPanel.tsx Node-Konfiguration (inkl. Trustee)
| TemplatePicker.tsx Modal: Vorlage auswaehlen
| +-- nodes/configs/
| TrusteeNodeConfig.tsx Trustee-Node-Konfiguration
| index.ts NODE_CONFIG_REGISTRY
| +-- index.ts Exports (PendingFile, EditorDataSource, etc.)
|
+-- pages/views/
| +-- workspace/
| | WorkspacePage.tsx Nutzt ChatBar, ChatStream, UDB
| +-- graphicalEditor/ <-- RENAMED von automation2
| GraphicalEditorPage.tsx FlowEditor + UDB + ChatPanel
| WorkflowsListPage.tsx
| TasksPage.tsx
| +-- graphicalEditor/ <-- Umgesetzt (ehemals automation2)
| GraphicalEditorPage.tsx FlowEditor + UDB + State-Management
| GraphicalEditorWorkflowsPage.tsx Workflow-Liste mit Umbenennen
| GraphicalEditorTemplatesPage.tsx Vorlagen mit Scope-Verwaltung
| GraphicalEditorTasksPage.tsx
|
+-- api/
workflowApi.ts <-- Konsolidiert (ersetzt automation + automation2 API)
workflowApi.ts <-- Konsolidiert (Templates, Versions, Workflows)
```
---
@ -1028,39 +1035,51 @@ frontend_nyla/src/
## Phasen-Plan
### Phase 1: Foundation
- Unified Workflow Datenmodell (AutoWorkflow + AutoVersion + AutoRun + AutoStepLog + AutoTask)
- Toolbox-Registry implementieren (Abloesung `_CORE_ONLY_TOOLS`)
- ChatBar-Komponente extrahieren
- Feature Rename: `automation2` -> `graphicalEditor`
- Scheduler konsolidieren (v1 Patterns in v2 Engine)
### Phase 1: Foundation -- ABGESCHLOSSEN (2026-04-05 bis 2026-04-07)
- [x] Unified Workflow Datenmodell (AutoWorkflow + AutoVersion + AutoRun + AutoStepLog + AutoTask)
- [x] Greenfield DB `poweron_graphicaleditor`
- [x] Feature Rename: `automation2` -> `graphicalEditor`
- [x] Legacy-Features `automation` und `automation2` entfernt
- [x] Bootstrap-Prozess konsolidiert und idempotent gemacht
- [x] Boot-Performance optimiert (30s -> 22s)
### Phase 2: Editor Enhancement
- AI Chat Sidebar im Editor (Toolbox `"workflow"` + Graph-Manipulation-Tools)
- UDB Integration im Editor
- AutoVersion Lifecycle (Draft/Published)
- Enhanced AutoStepLog + Visual Tracing
### Phase 2: Editor Enhancement -- ABGESCHLOSSEN (2026-04-07)
- [x] AI Chat Sidebar im Editor (EditorChatPanel mit SSE, Graph-Manipulation)
- [x] UDB Integration im Editor (Files + Sources Tabs, Mandate-gefiltert)
- [x] AutoVersion Lifecycle (Draft/Published/Archived) im CanvasHeader
- [x] Tracing Panel im Editor (RunTracingPanel)
- [x] File/Source-Attachments im AI Chat (Drag&Drop + Source-Picker wie im Workspace)
- [x] 3-Column Layout: [UDB] [Chat/Tracing] [Canvas] [Nodes]
### Phase 3: Productization
- Workflow-Vorlagen: Template-Management (Scope `user` | `instance` | `mandate` | `system`), Bootstrap durch `sysadmin`, Kopie-vs-Freigabe, RBAC laut Abschnitt „Workflow-Vorlagen“
- Marketplace / Katalog (optional auf Basis derselben Vorlagen-API)
- Monitoring Dashboard
- Retry Policies pro Node
- Notifications bei Scheduler-Fehlern
- Automation v1 Feature entfernen (wird nicht mehr benoetigt)
### Phase 3: Productization -- ABGESCHLOSSEN (2026-04-07)
- [x] Workflow-Vorlagen: Template-Management mit Scope (user/instance/mandate/system)
- [x] System-Template Bootstrap (2 Vorlagen: Personal Assistant, Treuhand)
- [x] Trustee Node-Types (extractFromFiles, processDocuments, syncToAccounting)
- [x] "Als Vorlage speichern" + "Neu aus Vorlage" im Editor
- [x] Scope-Aenderung (erweitern + zuruecknehmen) in Templates-Verwaltung
- [x] Umbenennen von Workflows und Templates
- [x] KeepAlive-Navigation-Fix (Workflow-Laden bei URL-Parameter-Aenderung)
- [ ] Marketplace / Katalog (optional, auf Basis derselben Vorlagen-API)
- [ ] Monitoring Dashboard
- [ ] Retry Policies pro Node
- [ ] Notifications bei Scheduler-Fehlern
### Phase 4: Advanced
- AI Decision Node (`ai.decide`)
- Custom Script Node (Python Sandbox)
- Dynamische Toolbox-Aktivierung basierend auf Connections
- Sub-Agent Pattern fuer weitere Features
### Phase 4: Advanced -- ABGESCHLOSSEN (2026-04-07)
- [x] Toolbox Registry: Tool-Listen fuer alle 8 Toolboxes befuellt, `requestToolbox` Meta-Tool mit Runtime-Refresh in agentLoop
- [x] Scheduler: `subAutomation2Schedule` aus `app.py` entfernt, `/schedule-sync` auf `WorkflowScheduler.syncNow` migriert, Billing-Init in Bootstrap verschoben
- [x] Enhanced AutoStepLog: InputSnapshot fuer Loops/Skipped/alle Pfade, I/O im UI (CollapsibleSection), Live-Push via SSE, Graph-Hervorhebung pro Step, Timestamps + RetryCount
- [x] `app.py` Cleanup: keine feature-spezifischen Imports/Logik mehr (Scheduler, EmailPoller, Billing)
- [ ] AI Decision Node (`ai.decide`)
- [ ] Custom Script Node (Python Sandbox)
- [ ] Sub-Agent Pattern fuer weitere Features
---
## Betroffene Module
- Gateway: `features/automation/`, `features/automation2/`, `workflows/`, `serviceCenter/services/serviceAgent/`
- Frontend: `components/Automation2FlowEditor/`, `pages/views/automation2/`
- Gateway: `features/graphicalEditor/`, `workflows/`, `serviceCenter/services/serviceAgent/`, `interfaces/interfaceBootstrap.py`
- Frontend: `components/FlowEditor/`, `pages/views/graphicalEditor/`, `components/UnifiedDataBar/`
- Entfernt: `features/automation/`, `features/automation2/`, `components/Automation2FlowEditor/`, `pages/views/automation2/`
- DB-Migration: nein (Greenfield -- neue DB `poweron_graphicaleditor`, keine Migration von `poweron_automation2`)
- Andere: Scheduler (APScheduler/eventManager), RBAC Template-Rollen
@ -1077,18 +1096,45 @@ frontend_nyla/src/
| 2026-04-06 | Workflow-Vorlagen mit Scope + getrenntem RBAC; `my` = nur eigene User-Scope-Vorlagen | Einheitliches Teilen (Kopie vs. read-only Freigabe) ohne Widerspruch zu Mandant/Instanz |
| 2026-04-06 | `Auto`-Prefix fuer alle Datenobjekte (AutoWorkflow, AutoVersion, AutoRun, AutoStepLog, AutoTask) | Eindeutige Erkennbarkeit in der Codebase; kein Namenskonflikt mit bestehenden Modellen |
| 2026-04-06 | Greenfield-Migration statt DB-Schema-Umbau | Neue DB `poweron_graphicaleditor`; `poweron_automation2` bleibt als Archiv; kein Migrationsrisiko |
| 2026-04-07 | Legacy-Features `automation` und `automation2` entfernt | Konsolidierung abgeschlossen; kein Altcode mehr im Gateway/Frontend |
| 2026-04-07 | Bootstrap idempotent gemacht (`_bootstrapDone` Flag) | Verhindert doppelte Ausfuehrung; `_initRecords` Workaround entfernt |
| 2026-04-07 | Stripe/APScheduler Debug-Logging unterdrueckt | Boot-Performance: 30s -> 22s; AI Pre-Warming dedupliziert |
| 2026-04-07 | UDB Data Sources Mandate-gefiltert | Verhindert Cross-Mandate-Datenlecks bei Active Data Sources |
| 2026-04-07 | Trustee Node-Types im Editor | 3 neue Nodes (extract, process, sync) fuer Treuhand-Workflows |
| 2026-04-07 | System-Templates im Bootstrap | 2 Vorlagen (Personal Assistant, Treuhand) als Startpunkt fuer neue User |
| 2026-04-07 | Template Scope-Aenderung bidirektional | Scope kann erweitert und zurueckgenommen werden; `sharedReadOnly` dynamisch |
| 2026-04-07 | `app.py` als generischer Entry-Point | Keine feature-spezifischen Imports; Scheduler/EmailPoller/Billing in Feature-Lifecycle bzw. Bootstrap |
| 2026-04-07 | SSE Live-Push fuer Run-Tracing | `EventManager`-Queue pro Run; Fallback auf Polling bei SSE-Fehler |
| 2026-04-07 | Canvas Graph-Hervorhebung | `highlightedNodeIds` Prop; farbcodiert nach Step-Status; Glow-Animation bei `running` |
| 2026-04-07 | `requestToolbox` als Meta-Tool | Agent kann zur Laufzeit Toolboxes anfordern; `agentLoop` refresht `toolDefinitions` nach Aufruf |
## Umsetzungs-Checkliste
- [ ] Vereinheitlichtes Schema: AutoWorkflow/AutoVersion/AutoRun/AutoStepLog/AutoTask (Greenfield DB)
- [ ] v1-Scheduler-Pattern in v2 Engine
- [ ] Toolbox Registry + requestToolbox Meta-Tool
- [ ] Feature-Code Rename `automation2` -> `graphicalEditor`
- [ ] Frontend: ChatBar + ChatStream extrahieren
- [ ] Frontend: UDB + Chat im Graph-Editor
- [ ] RBAC Template-Rollen konsolidieren
- [ ] Vorlagen: `templateScope`, Ersteller (Basis-Klasse), Freigabe/Kopie, DATA+RESOURCE-Regeln
- [ ] AutoStepLog + Visual Tracing
- [x] Vereinheitlichtes Schema: AutoWorkflow/AutoVersion/AutoRun/AutoStepLog/AutoTask (Greenfield DB `poweron_graphicaleditor`)
- [x] Feature-Code Rename `automation2` -> `graphicalEditor` (Backend + Frontend)
- [x] Frontend: UDB im Graph-Editor (UnifiedDataBar mit Files + Sources Tabs)
- [x] Frontend: AI Chat Sidebar im Editor (EditorChatPanel mit SSE-Streaming, Graph-Manipulation-Tools)
- [x] Frontend: Tracing Panel im Editor (RunTracingPanel mit Step-Log-Anzeige)
- [x] Frontend: Version Management im Editor (Draft/Published/Archived Lifecycle via CanvasHeader)
- [x] Vorlagen: `templateScope` (user/instance/mandate/system), Freigabe/Kopie, Scope-Aenderung
- [x] Vorlagen: System-Template Bootstrap (`_bootstrapSystemTemplates` in `interfaceBootstrap.py`)
- [x] Vorlagen: 2 System-Templates (Personal Assistant E-Mail-Drafting, Treuhand PDF-Klassifizierung)
- [x] Vorlagen: "Als Vorlage speichern" Button im Editor mit Scope-Auswahl
- [x] Vorlagen: "Neu aus Vorlage" Template-Picker-Modal im Editor
- [x] Vorlagen: Scope-Aenderung (erweitern + zuruecknehmen) in Templates-Seite
- [x] Vorlagen: Umbenennen von Workflows und Templates in den jeweiligen Verwaltungsseiten
- [x] Trustee Node-Types: `trustee.extractFromFiles`, `trustee.processDocuments`, `trustee.syncToAccounting`
- [x] Node-Config Frontend: TrusteeNodeConfig.tsx mit Connection/Folder/Prompt-Feldern
- [x] Legacy-Features `automation` und `automation2` aus Gateway und Frontend entfernt
- [x] Bootstrap: Idempotenter `initBootstrap` mit `_bootstrapDone` Flag
- [x] Bootstrap: Redundanter `_initRecords` Fallback in `interfaceDbApp.py` entfernt
- [x] Boot-Performance: Stripe/APScheduler Debug-Logging unterdrueckt, AI Pre-Warming dedupliziert (30s -> 22s)
- [x] UDB: Mandate-Filter fuer Active Data Sources und Feature Data Sources
- [x] KeepAlive: Workflow-Laden bei Navigation von Workflows-Seite zum Editor (URL-Parameter reaktiv)
- [x] RBAC Template-Rollen fuer graphicalEditor (admin/user/viewer)
- [x] Toolbox Registry: Tool-Listen befuellt (core/ai/datasources/email/sharepoint/clickup/jira/workflow), `requestToolbox` Meta-Tool implementiert, `_activateToolboxes` generisch
- [x] Scheduler-Konsolidierung: `subAutomation2Schedule` entfernt, `/schedule-sync` migriert auf `WorkflowScheduler.syncNow`, `app.py` bereinigt
- [x] AutoStepLog + Enhanced Visual Tracing: InputSnapshot fuer alle Pfade (Loops, Skipped), I/O CollapsibleSections im UI, Live-Push via SSE (`/runs/{runId}/stream`), Graph-Hervorhebung (Canvas Highlighting), Timestamps + RetryCount
- [ ] Neutralisierung: keine Aenderung (nutzt gleiche Services)
- [ ] Billing-Impact: pruefen (Automation-Runs zaehlen?)
@ -1140,6 +1186,21 @@ frontend_nyla/src/
## Abschluss
**Vollstaendiger Umbau abgeschlossen am 2026-04-07.** Phasen 1-4 umgesetzt.
**Phase 4 Umsetzung (2026-04-07):**
| Punkt | Umgesetzt |
|-------|-----------|
| **Toolbox Registry** | Tool-Listen fuer alle 8 Toolboxes befuellt (core: 20, ai: 9, datasources: 8, email: 5, sharepoint: 3, clickup: 3, jira: 3, workflow: 9). `requestToolbox` Meta-Tool mit Schema, Handler in `mainServiceAgent._registerRequestToolbox()`, Runtime-Refresh in `agentLoop.py`. `_activateToolboxes` generisch (entfernt inaktive Tools). |
| **Scheduler-Konsolidierung** | `subAutomation2Schedule` komplett aus `app.py` entfernt. `/schedule-sync` Endpoint migriert auf `WorkflowScheduler.syncNow()`. `setMainLoop` in `app.py` fuer Thread-Bridge. Billing-Init in `interfaceBootstrap._bootstrapBilling()` verschoben. EmailPoller-Stop in `mainGraphicalEditor.onStop()`. |
| **Enhanced AutoStepLog + Visual Tracing** | `inputSnapshot` fuer alle Pfade: Loop-Header, Loop-Body (`_loopItem`/`_loopIndex`), Resume-Path, Skipped-Nodes (`_skipReason`). RunTracingPanel: CollapsibleSection fuer Input/Output, Timestamps, RetryCount, Loop-Indikator. Live-Push via SSE (`GET /runs/{runId}/stream`) mit Fallback auf 3s-Polling. Canvas Graph-Hervorhebung: `highlightedNodeIds` Prop auf FlowCanvas, farbcodiert nach Status (running=gelb+Glow, completed=gruen, failed=rot, skipped=grau). |
**Verbleibende optionale Erweiterungen:**
- AI Decision Node (`ai.decide`)
- Custom Script Node (Python Sandbox)
- Sub-Agent Pattern fuer weitere Features
- [ ] b-reference/gateway/automation.md aktualisiert
- [ ] TOPICS.md aktualisiert
- [ ] Dieses Dokument -> z-archive/ verschoben

View file