integrated and initial teste unified automation
This commit is contained in:
parent
7d1a957f77
commit
7f3170f324
10 changed files with 1270 additions and 178 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
398
c-work/1-plan/2026-04-analysis-editor.md
Normal file
398
c-work/1-plan/2026-04-analysis-editor.md
Normal 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 (10–15 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 | 2–3 Tage | Keine |
|
||||
| 2 — Output-Normalizer | 3–5 Tage | Phase 1 |
|
||||
| 3 — Frontend DataPicker aus Schema | 2–3 Tage | Phase 1 |
|
||||
| 4 — Generisches Parameter-Rendering | 3–4 Tage | Phase 1 |
|
||||
| 5 — Data Nodes (aggregate, transform, filter) | 3–5 Tage | Phase 2 |
|
||||
| **Gesamt** | **~13–20 Tage** | Phasen 1–3 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` |
|
||||
256
c-work/1-plan/2026-04-porta-ui-enhancements-team-meeting.md
Normal file
256
c-work/1-plan/2026-04-porta-ui-enhancements-team-meeting.md
Normal 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 (>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. 1025–1280px)** | `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 I1–I9 adressieren, **ohne** Billing-Logik oder Gateway-Tarife neu zu erfinden. Reihenfolge nach **Aufwand × Wirkung** für KMU-Erstnutzung.
|
||||
|
||||
### Phase A — Quick Wins (1–3 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 (3–5 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 (2–4 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** (1–2 Sätze) zu sicherer Verbindung / keine Zerstörung von Quelldaten — mit Product Owner fact-checken | `SourcesTab.tsx` oben |
|
||||
|
||||
### Phase D — Billing-Discovery (2–3 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.
|
||||
- **C1–C3** 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 A–E | Issues I1–I9 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 A–E). 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)**
|
||||
|
||||
- [ ] B1–B2: `WorkspacePage.tsx` — Zwischen-Breakpoint / Sidebar-Strategie
|
||||
- [ ] B3: `WorkspaceInput.tsx` — visuelle Hierarchie Eingabe
|
||||
- [ ] B4: Viewport-Testmatrix dokumentiert
|
||||
|
||||
**Phase C (Trust)**
|
||||
|
||||
- [ ] C1–C3: 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. 900–1024px 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 (5–10 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)
|
||||
229
c-work/1-plan/2026-04-trustee-tooling-and-demo-prep.md
Normal file
229
c-work/1-plan/2026-04-trustee-tooling-and-demo-prep.md
Normal 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
|
||||
|
|
@ -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
|
||||
0
f-decisions/platzhalter.txt
Normal file
0
f-decisions/platzhalter.txt
Normal file
Loading…
Reference in a new issue