From c3e1eb74e86d94d68cf9d4b728c9a1678507a423 Mon Sep 17 00:00:00 2001 From: ValueOn AG Date: Thu, 4 Jun 2026 23:20:41 +0200 Subject: [PATCH] customer cases soluttion architecture --- ...4-pm-consolidated-customer-requirements.md | 572 ------------- ...026-06-CustomerCases-step1-architecture.md | 291 +++++++ ...tomerCases-step2-communication-mockup.html | 762 ++++++++++++++++++ ...ses-step2-communication-product-summary.md | 82 ++ ...es-step2-communication-product-summary.pdf | Bin 0 -> 35458 bytes ...26-06-CustomerCases-step3-features-plan.md | 191 +++++ ...6-06-CustomerCases-step3-solutions-plan.md | 199 +++++ c-work/1-plan/2026-05-lawyer-feature.md | 195 ----- ...tion-connectors-und-datenquellen-seiten.md | 222 ----- c-work/_CHANGELOG.md | 3 + 10 files changed, 1528 insertions(+), 989 deletions(-) delete mode 100644 c-work/0-ideas/2026-04-pm-consolidated-customer-requirements.md create mode 100644 c-work/0-ideas/2026-06-CustomerCases-step1-architecture.md create mode 100644 c-work/0-ideas/2026-06-CustomerCases-step2-communication-mockup.html create mode 100644 c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.md create mode 100644 c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.pdf create mode 100644 c-work/0-ideas/2026-06-CustomerCases-step3-features-plan.md create mode 100644 c-work/0-ideas/2026-06-CustomerCases-step3-solutions-plan.md delete mode 100644 c-work/1-plan/2026-05-lawyer-feature.md delete mode 100644 c-work/1-plan/2026-06-umsystem-integration-connectors-und-datenquellen-seiten.md diff --git a/c-work/0-ideas/2026-04-pm-consolidated-customer-requirements.md b/c-work/0-ideas/2026-04-pm-consolidated-customer-requirements.md deleted file mode 100644 index 95e00fd..0000000 --- a/c-work/0-ideas/2026-04-pm-consolidated-customer-requirements.md +++ /dev/null @@ -1,572 +0,0 @@ - - - - - -# Konsolidierter Kundenwünsche-Plan — PORTA Umsetzung - -> **Stand:** 16. April 2026 (aktualisiert mit PWG-Workshop-Ergebnissen) -> **Zweck:** Einheitliche Übersicht aller Kundenwünsche, priorisiert und gegen die Codebase abgeglichen. -> **Ersetzt:** `local/notes/demo-tue-use-cases-inputs-customers.md`, `c-work/1-plan/2026-04-demo2-merged-customer-trustee-plan.md`, `c-work/1-plan/2026-04-porta-ui-enhancements-team-meeting.md` - ---- - -## Kunden-Übersicht - -| Kunde | Branche | Kontakte | Hauptinteresse | Status | -|-------|---------|----------|----------------|--------| -| **Bling** | Treuhandbüro | KJS | Belegverarbeitung, Budget, Dashboards, Mandantenmanagement | Trial geplant | -| **PWG** (Stiftung) | Immobilien/Wohnen (~300 Liegenschaften, 7–8 Pers.) | MB | **Pilot: Jahresmietzinsbestätigungen** (3'200/Jahr), Belegverarbeitung Abacus, CommCoach, Neutralisierung, Knowledge-Retrieval | Workshop 16.04.2026 ✅ — Pilot bestätigt, Versand Sommer 2026 | -| **Quid / ServiceHunter** | SaaS/Dienstleistung | DC | KPI-Dashboard, Zeiterfassung, Prognosen, Konsolidierung | Follow-up geplant | - ---- - -## Legende Codebase-Status - -| Symbol | Bedeutung | -|--------|-----------| -| ✅ | Im Code vorhanden und funktional | -| 🔧 | Grundstruktur vorhanden, Anpassung/Ergänzung nötig | -| ❌ | Noch nicht umgesetzt | -| ⏸️ | Bewusst zurückgestellt (wartet auf Input/Entscheid) | - ---- - -## Teil 1: Feature-Anforderungen (Kunden-Use-Cases) - -### 1.1 Automatisierte Belegverarbeitung & Spesenverwaltung - -**Kunden:** Bling (Prio hoch), PWG, Quid (Spesen) - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.1.1 | Spesenbelege per Foto → automatische Klassifikation (Rechnung, Spesenbeleg, Bankauszug) | ✅ | `methodTrustee/actions/extractFromFiles.py` + `processDocuments.py` — Pipeline extrahiert, klassifiziert, verbucht | -| 1.1.2 | SharePoint-Synchronisation (automatisch, z.B. täglich 22:00) | ✅ | `nodeDefinitions/sharepoint.py` — 6 Nodes; `automation2/scheduleCron.py` für Zeitsteuerung; System-Template "Treuhand: PDF-Klassifizierung & Trustee-Import" in `interfaceBootstrap.py` | -| 1.1.3 | Automatische Kontierung basierend auf Kontoplan | ✅ | In `processDocuments.py` — AI-gestützte Kontierung gegen Feature-Daten (Kontoplan via Accounting-Bridge) | -| 1.1.4 | Firmen-Mapping zu Kunden/Lieferanten | 🔧 | Grundstruktur in Accounting-Bridge; kein dediziertes Mapping-UI oder regelbasiertes Matching | -| 1.1.5 | Optionales Tagging (z.B. "Fuel Station") | 🔧 | Tags auf Dokument-Ebene möglich; kein Beleg-spezifisches Tag-System | -| 1.1.6 | Buchungsregeln für wiederkehrende Belege | ❌ | Kein regelbasiertes Booking-Template-System | -| 1.1.7 | Vorsteuer automatisch hinterlegen und auslesen | 🔧 | Accounting-Connectors liefern Steuerdaten; automatische MWST-Zuordnung bei Belegverarbeitung nicht explizit | -| 1.1.8 | Integration RunMyAccounts | ✅ | `accountingConnectorRma.py` | -| 1.1.9 | Integration Bexio | ✅ | `accountingConnectorBexio.py` | -| 1.1.10 | Integration Abacus | ✅ | `accountingConnectorAbacus.py` | -| 1.1.11 | Integration Xero | ❌ | Kein `accountingConnectorXero.py` — kein Code vorhanden | -| 1.1.12 | PDF/Excel/Word/Zip Verarbeitung | ✅ | Extraktoren vorhanden; UDM-Konzept in `0-ideas/unified-document-model.md` | - -### 1.2 Budget / Soll-Ist-Vergleich - -**Kunden:** Bling (Prio hoch), Quid (KPI-Kontext) - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.2.1 | Budget-Excel hochladen und gegen Live-Daten prüfen | 🔧 | Prompt-Template "Budget-Vergleich" in `mainTrustee.py` (Quick Action + Template Workflow); Frontend `TrusteeAnalyseView.tsx` hat Budget-Tab mit Upload; **aber kein Demo-Budget-Excel vorhanden** | -| 1.2.2 | Vergleiche über Perioden (Q1 aktuell vs. Vorjahr vs. Budget) | ✅ | Im Prompt-Template als Anweisung an AI-Agent enthalten | -| 1.2.3 | Automatische Diagramm-Erstellung | ✅ | Agent erzeugt Charts via `aggregateTable` + AI-Prompt | -| 1.2.4 | Live-Daten via API (kein PDF-Export nötig) | ✅ | `refreshAccountingData` Action synct Live-Daten; API-basiert | -| 1.2.5 | Caching konfigurierbar | ✅ | `_featureQueryCache` mit TTL 300s in `_featureSubAgentTools.py` | -| 1.2.6 | Abweichungen mit Begründung | ✅ | Im Prompt-Template: Agent soll Abweichungen erklären | -| 1.2.7 | Vorausschauende Prognosen | ✅ | Separates Prompt-Template "Prognose/Trend-Analyse" | - -### 1.3 Cashflow-Rechnung - -**Kunden:** Bling - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.3.1 | Plausibilisierung und Erstellung Cashflow-Rechnung | ✅ | Prompt-Template "Cashflow-Rechnung" in `mainTrustee.py` | -| 1.3.2 | Nicht-relevante Positionen berücksichtigen | ✅ | Im Prompt-Template als Anweisung | -| 1.3.3 | Warnungen bei kritischen Werten | ✅ | Im Prompt-Template | - -### 1.4 Dashboard — Bilanz- & Erfolgsrechnungsanalyse - -**Kunden:** Bling, Quid - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.4.1 | KPI-Dashboard (Bruttogewinn, ROI, Gewinn etc.) | ✅ | Prompt-Template "KPI-Dashboard" + Quick Action + `TrusteeAnalyseView.tsx` KPI-Tab | -| 1.4.2 | Check hälftiger Kapitalverlust | ✅ | Im Jahresabschluss-Prompt enthalten | -| 1.4.3 | Überschuldungs-Check | ✅ | Im Jahresabschluss-Prompt enthalten | -| 1.4.4 | Durchschnittliche Zahlungsfrist | 🔧 | Nicht als dedizierter KPI; Agent kann es berechnen wenn Daten vorhanden | - -### 1.5 Liquiditätsplanung - -**Kunden:** Bling - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.5.1 | Liquiditätsplanung analog Budgetplanung | 🔧 | Kein dediziertes Prompt-Template; über Prognose-Template teilweise abdeckbar | -| 1.5.2 | Automatische Erstellung aus Vergangenheit | 🔧 | Agent kann historische Daten analysieren; kein dedizierter Workflow | -| 1.5.3 | Zusätzliche Inputs (z.B. ausserordentliche Dividende) | ❌ | Kein Mechanismus für manuelle Zusatz-Inputs in Prognose | - -### 1.6 Gastro-Use-Case — Echtzeit-Rentabilitätsanalyse - -**Kunden:** Bling (Prio hoch, bestes Beispiel für Kunden-Mehrwert) - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.6.1 | Integration Kassensystem + Lohndaten + Buchhaltung | ⏸️ | **Wartet auf Kevin-Input** — kein Connector für Kassensysteme/Virux | -| 1.6.2 | Tagesumsatz vs. Personalkosten vs. Wareneinsatz | ⏸️ | Konzeptionell über generischen Data-Import möglich | - -### 1.7 Abschlussunterstützung - -**Kunden:** Bling, allgemein Treuhand - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.7.1 | Jahresabschluss-Checks | ✅ | Prompt-Template "Jahresabschluss prüfen" in `mainTrustee.py` | -| 1.7.2 | Abgrenzungsbuchungen vorbereiten | 🔧 | Im Prompt adressiert; keine dedizierte Automation | -| 1.7.3 | Bilanzkonti prüfen / Saldovalidierung | ✅ | Im Jahresabschluss-Prompt | -| 1.7.4 | Vorjahresvergleiche | ✅ | In mehreren Prompt-Templates | - -### 1.8 Zentrales Mandantenmanagement - -**Kunden:** Bling (verschiedene Systeme über eine Schaltzentrale) - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.8.1 | Verschiedene Kunden auf verschiedenen Systemen verwalten | ✅ | Multi-Tenant-Plattform ist Kernarchitektur; `accountingRegistry.py` unterstützt verschiedene Connectors pro Mandant | -| 1.8.2 | Ein Login, alle Mandanten | ✅ | Plattform-Feature: Mandantenwechsel im UI | -| 1.8.3 | Strikte Datentrennung | ✅ | Mandantenisolation auf DB- und API-Ebene | - ---- - -### 1.9 PWG — Stiftung für preisgünstiges Wohnen - -**Kontext:** ~300 Liegenschaften, Team 7–8 Personen. IT-Leiter Markus Brütsch (seit 2+ Jahren). Neue Rolle "Organella" für Digitalisierung (Schnittstelle Technologie/Betrieb, kein IT-Hintergrund). PWG evaluiert AI-Lösungen offen, noch keine Entscheidung getroffen. Workshop 16.04.2026 durchgeführt. - -**Pilotprojekt bestätigt:** Jahresmietzinsbestätigungen (siehe 1.9.9). - -#### 1.9a Plattform-Features (bestehend) - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.9.1 | Automatisierte Belegverarbeitung mit Abacus | ✅ | `accountingConnectorAbacus.py` + Trustee-Pipeline | -| 1.9.2 | Kommunikations-Coach für Mietergespräche | ✅ | `features/commcoach/` — komplett inkl. 10+ Personas | -| 1.9.3 | Immobilien-Personas (Zahlungsrückstand, Nebenkosten, Einzug, Lärm) | ✅ | 4 PWG-Personas in `BUILTIN_PERSONAS` + Seeding | -| 1.9.4 | KI-Arbeitsplatz mit Datenneutralisierung | ✅ | `features/neutralization/` — PII-Masking, Playground, Private-LLM; Daten-Residency Schweiz | -| 1.9.5 | PWG-Agent (Stiftungsstil, öffentliche PDFs als Futter) | 🔧 | Knowledge-Base-Feature vorhanden; kein PWG-spezifisches Knowledge-Set (Geschäftsberichte, Vermietungsreglement, Führungshandbuch etc.) | -| 1.9.6 | M365-Anbindung (SharePoint, Outlook, OneDrive, Teams) | ✅ | SharePoint-Nodes + Outlook-Methode in Workflows; nutzt nativen SharePoint-Index | -| 1.9.7 | KI-Auswertung Abacus-Daten/Reports | ✅ | Über Trustee-Feature + `aggregateTable` + AI-Prompts; Read/Write via Abacus-API | -| 1.9.8 | Grundstücksanalyse (öffentliche Daten: GIS, Maps, Grundbuch) | ❌ | Kein Connector/Workflow für öffentliche Geodaten | - -#### 1.9b Neue Anforderungen aus Workshop 16.04.2026 - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.9.9 | **Pilotprojekt: Jahresmietzinsbestätigungen** (ca. 700–800 Schreiben/Quartal, Versand Sommer 2026) | ❌ | Kein dedizierter Workflow — siehe Workflow-Design unten | -| 1.9.10 | FileMaker-Integration (Portfolio, Liegenschaften, Erneuerungsplanung, Bauprojekte, Akquisition) | ❌ | Kein FileMaker-Connector; Datenmenge/-qualität muss geprüft werden | -| 1.9.11 | Template-basierte Dokumentenerstellung (HTML-Templates → Word mit Corporate Design) | 🔧 | Code-Editor mit Claude vorhanden; kein Template-to-Word-Pipeline | -| 1.9.12 | Notification-System (reagiert auf DB-Änderungen, Berichte per E-Mail, Workflow-Trigger) | 🔧 | E-Mail-Versand in Workflows vorhanden (`methodOutlook`); kein generisches DB-Change-Detection-System | -| 1.9.13 | Information Retrieval über diverse Wissensquellen (Guidelines, Handbücher, SharePoint) | 🔧 | Knowledge-Base + SharePoint-Index vorhanden; kein PWG-spezifisches Datenset geladen | -| 1.9.14 | Datenvalidierung als Erst-Schritt (welche Daten korrekt/aktuell?) | ❌ | Kein Daten-Audit-Workflow | -| 1.9.15 | Compliance & Audit: vollständiges Tracking aller AI-Transaktionen | ✅ | `ComplianceAuditPage.tsx` + Gateway-Logging; jede Anfrage protokolliert | -| 1.9.16 | Granulare Neutralisierungs-Kontrolle pro Datenquelle | ✅ | In Neutralisierungs-Feature konfigurierbar pro Source | - -#### 1.9c Pilot-Workflow: Jahresmietzinsbestätigungen - -**Business Case:** 4 × 800 Schreiben/Jahr = 3'200 Schreiben. Aktuell: Serienbrief → manueller Versand → Scan der Rückantworten → manuelle Verarbeitung. Ziel: AI-gestützte Verarbeitung der gescannten Rückantworten mit Antwortvorschlägen. - -**Workflow-Design (6–7 Schritte, davon 1 mit AI):** - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ PWG Pilot: Jahresmietzinsbestätigungen │ -│ │ -│ Phase 1: Generierung (bestehend bei PWG) │ -│ ┌──────────────────────────────────────┐ │ -│ │ System generiert Serienbrief │ (PWG-internes System) │ -│ │ mit aktuellen Mietdaten │ │ -│ └──────────┬───────────────────────────┘ │ -│ ▼ │ -│ Phase 2: Versand & Rücklauf (manuell) │ -│ ┌──────────────────────────────────────┐ │ -│ │ Manueller Versand + Scan der │ │ -│ │ Rückantworten → SharePoint-Ordner │ │ -│ └──────────┬───────────────────────────┘ │ -│ ▼ │ -│ Phase 3: PowerOn-Workflow (automatisiert) │ -│ │ -│ Step 1: trigger.schedule (täglich oder on-demand) │ -│ ▼ │ -│ Step 2: sharepoint.listFiles (Scan-Ordner, neue Dokumente) │ -│ ▼ │ -│ Step 3: flow.loop (für jedes gescannte Dokument) │ -│ ▼ │ -│ Step 4: sharepoint.downloadFile + trustee.extractFromFiles │ -│ → OCR/Extraktion: Mietername, Adresse, Bestätigung, │ -│ Anmerkungen, Unterschrift ja/nein │ -│ ▼ │ -│ Step 5: ai.prompt ← EINZIGER AI-SCHRITT │ -│ → Gescannte Daten gegen Originaldaten prüfen │ -│ → Status klassifizieren (bestätigt / Abweichung / │ -│ fehlende Unterschrift / unleserlich) │ -│ → Antwortvorschlag generieren bei Abweichung │ -│ ▼ │ -│ Step 6: data.writeToTable (Ergebnis in Übersichtstabelle) │ -│ ▼ │ -│ Step 7: email.send (Zusammenfassung an Sachbearbeiter) │ -│ → Audit-Log für jeden Verarbeitungsschritt │ -└─────────────────────────────────────────────────────────────────┘ -``` - -**Benötigte Komponenten für den Pilot-Workflow:** - -| # | Komponente | Codebase-Status | Was zu tun ist | -|---|-----------|-----------------|----------------| -| W1 | `trigger.schedule` oder `trigger.manual` | ✅ | Vorhanden in `nodeDefinitions/triggers.py` | -| W2 | `sharepoint.listFiles` + `sharepoint.downloadFile` | ✅ | Vorhanden in `nodeDefinitions/sharepoint.py` | -| W3 | `flow.loop` | ✅ | Vorhanden in `nodeDefinitions/flow.py` | -| W4 | `trustee.extractFromFiles` (OCR/Extraktion gescannter Dokumente) | ✅ | Vorhanden; OCR für einseitige Scans unterstützt | -| W5 | `ai.prompt` — Prompt-Template "Mietzinsbestätigung prüfen" | ❌ | **Neues Prompt-Template** nötig: Scan-Daten gegen Originaldaten abgleichen, Status klassifizieren, Antwortvorschlag generieren | -| W6 | Ergebnis-Tabelle / Übersichtsliste (verarbeitete Bestätigungen) | 🔧 | `data`-Nodes existieren; kein dedizierter "Mietzinsbestätigungs-Report"-Output | -| W7 | `email.send` (Zusammenfassung an Sachbearbeiter) | ✅ | Vorhanden via `methodOutlook` | -| W8 | Abacus-Referenzdaten (Original-Mietzinsdaten für Abgleich) | 🔧 | Abacus-Connector vorhanden; Abfrage der Mietzins-Stammdaten muss konfiguriert werden | -| W9 | Audit-Logging für gesamten Prozess | ✅ | Plattform-Feature: alle AI-Transaktionen geloggt | -| W10 | Graph-Editor Workflow als Template speichern | ❌ | Workflow muss im Editor gebaut und als System-Template gespeichert werden | - -**Voraussetzungen (Action Items aus Workshop):** - -| # | Action Item | Verantwortlich | Status | -|---|------------|----------------|--------| -| AI1 | API-Zugang zu Abacus-Testmandant einrichten | Patrick Motsch | ❌ offen — Patrick koordiniert mit Abacus | -| AI2 | PWG muss Zugriff auf Testmandant bestätigen | PWG (Markus) | ❌ offen | -| AI3 | Preismodell bereitstellen (Grundgebühr/User/Monat + Token-Gebühr) | PowerOn | ❌ offen | -| AI4 | Datenschutzanforderungen und Vertragsklauseln für Lieferanten prüfen | PWG | ❌ offen | -| AI5 | Prozessschritte Pilot ausarbeiten und Kalkulation erstellen | PowerOn | 🔧 Workflow-Design in diesem Dokument; Kalkulation offen | -| AI6 | FileMaker-Datenmenge und -qualität prüfen (potenzielle Integration) | PWG + PowerOn | ❌ offen | - ---- - -### 1.10 Quid / ServiceHunter Use Cases - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 1.10.1 | KPI-Dashboard (Kundenmargen, ACV, Lifetime Value, Produktionsmarge) | 🔧 | Generisches KPI-Prompt-Template vorhanden; kundenspezifische KPIs brauchen Daten-Import | -| 1.10.2 | Zeiterfassung & Support-Analyse (Zendesk-Verknüpfung) | ⏸️ | **Kein Zendesk-Connector** — bewusst CSV-Upload-Workaround | -| 1.10.3 | Prognosen & Proaktive Steuerung | ✅ | Prognose-Prompt-Template vorhanden | -| 1.10.4 | Konsolidierung international (CH, DE, UK) | ⏸️ | **Wartet auf Lars-Meeting** — hohe Komplexität | -| 1.10.5 | Spesen-Automatisierung (SharePoint/Drive → verbuchen) | ✅ | SharePoint-Pipeline + Trustee-Import vorhanden | - ---- - -## Teil 2: UI/UX-Anforderungen (aus Team-Meeting / Nutzertests) - -### 2.1 AI-Workspace Usability - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 2.1.1 | Primäre Prompt-Zeile dominant sichtbar (kein "Wo tippe ich?") | 🔧 | `WorkspaceInput.tsx` funktional komplett; **Placeholder auf Englisch**, keine Hero-Eingabe, sekundäre Aktionen in einer Zeile | -| 2.1.2 | Empty State im Chat (Orientierung für Erstnutzer) | ❌ | `ChatStream.tsx` zeigt blank area wenn `messages.length === 0` — **kein Welcome/Empty-State** | -| 2.1.3 | "Neuer Chat" sichtbar ohne UDB-Sidebar | ❌ | Nur `+` in `ChatsTab` Toolbar; kein zentraler CTA | -| 2.1.4 | Datei-Drop Entdeckbarkeit | 🔧 | Vollflächen-Drop existiert in `WorkspacePage.tsx`; kein dauerhafter Hinweis im leeren Chat | -| 2.1.5 | DE-Placeholder und i18n | ❌ | Placeholder noch auf Englisch (`Type a message...`) | - -### 2.2 Responsive Layout & Breakpoints - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 2.2.1 | Zwischen-Breakpoint (1025–1280px): Sidebars auto-einklappen | ❌ | `isMobile` nur bei `≤1024px`; schmale Desktop-Fenster → Mittelspalte zu schmal | -| 2.2.2 | Visuelle Hierarchie Prompt (Schatten/Rand, minHeight) | ❌ | `WorkspaceInput.tsx` ohne besondere Hervorhebung | -| 2.2.3 | Viewport-Testmatrix (1100/1200/1280/1440) | ❌ | Kein Test-Setup dafür | - -### 2.3 Vertrauen & Marketing-UI - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 2.3.1 | Trust-Badges (Daten hosted in der Schweiz, Anbieter/Standort) | ❌ | Login: **kein** Hosting-Hinweis; keine `TrustFooter`/`TrustStrip` Komponente | -| 2.3.2 | "Recommended by" Partner-Strip (Valion, PamoCreate, Swiss AI Association etc.) | ❌ | Keine Partner-Logos/Links | -| 2.3.3 | Swiss ® am Logo | ❌ | Nur im Bildasset, nicht in UI sichtbar (Legal klären) | -| 2.3.4 | Sicherheits-Banner in SourcesTab ("Verbindung ist read-only") | ❌ | `SourcesTab.tsx` ohne Info-Banner | - -### 2.4 Billing & Pricing Auffindbarkeit - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 2.4.1 | Billing-Funktionalität (komplett) | ✅ | `BillingDataView.tsx` mit Tabs, Balance Cards, Transaktionen | -| 2.4.2 | Einstieg Billing nach Login (Teaser/Banner) | ❌ | Kein Dashboard-Teaser; Zugang nur via Nav-Baum + User-Menü | -| 2.4.3 | Balance im UserSection (neben Avatar) | ❌ | Nur Menü-Eintrag "Guthaben" | -| 2.4.4 | Billing-Copy für Nicht-Admins | ❌ | Kein Hinweis "Frag deinen Admin" | - -### 2.5 Onboarding & Erstnutzung - -| # | Anforderung | Codebase-Status | Evidenz / Bemerkung | -|---|-------------|-----------------|---------------------| -| 2.5.1 | Connector-Onboarding ("sicher verbinden, nichts kaputt") | ❌ | Keine Microcopy in SourcesTab | -| 2.5.2 | Progressive Offenlegung (weniger gleichzeitig auf Startscreens) | ❌ | Workspace zeigt alles parallel | - ---- - -## Teil 3: Infrastruktur & Demo-Vorbereitung - -### 3.1 Demo-Konfigurationen - -| # | Item | Codebase-Status | Evidenz / Bemerkung | -|---|------|-----------------|---------------------| -| 3.1.1 | Demo-Config-Infrastruktur (Base + Admin API) | ✅ | `_baseDemoConfig.py`, `routeAdminDemoConfig.py` | -| 3.1.2 | Referenz: `investorDemo2026.py` | ✅ | Vollständiges Muster mit Mandant, User, Features, Billing | -| 3.1.3 | Demo-Mandant "Bling Demo" | ❌ | Kein `blingDemo2026.py` | -| 3.1.4 | Demo-Mandant "PWG Demo" | ❌ | Kein `pwgDemo2026.py` | -| 3.1.5 | Demo-Mandant "Quid Demo" | ❌ | Kein `quidDemo2026.py` | - -### 3.2 Testdaten - -| # | Item | Codebase-Status | Evidenz / Bemerkung | -|---|------|-----------------|---------------------| -| 3.2.1 | Fiktives Mieterdossier (Neutralisierung) | ✅ | `demoData/neutralizer/tenant-dossier.pdf` + Generator | -| 3.2.2 | Knowledge-Base Demo-Dateien | ✅ | `demoData/knowledge-base/` — 4 Dateien | -| 3.2.3 | Budget-Excel (Soll-Werte) | ❌ | Kein `.xlsx` im Repo | -| 3.2.4 | Musterbelege (Rechnung, Spesen, Bank, Versicherung) | ❌ | Keine Demo-Belege | -| 3.2.5 | Quid-Testdaten (CSV: Umsatz, Kunden, Support) | ❌ | Keine kundenspezifischen Testdaten | -| 3.2.6 | Bling-Testdaten (Bexio-kompatibel) | ❌ | Keine Bexio-Testdaten | -| 3.2.7 | PWG-Testdaten (Abacus-kompatibel) | ❌ | Keine Abacus-Testdaten | - -### 3.3 Demo-Workflows & Skripte - -| # | Item | Codebase-Status | Evidenz / Bemerkung | -|---|------|-----------------|---------------------| -| 3.3.1 | System-Template "Treuhand: PDF-Klassifizierung" | ✅ | In `interfaceBootstrap.py` | -| 3.3.2 | Demo-Workflow (manual trigger → SharePoint → Trustee Pipeline) | ❌ | System-Template existiert, aber kein dedizierter Demo-Workflow | -| 3.3.3 | Demo-Skript Bling | ❌ | | -| 3.3.4 | Demo-Skript PWG | ❌ | | -| 3.3.5 | Demo-Skript Quid | ❌ | | -| 3.3.6 | Neutralisierungs-Demo-Flow (Schritt-für-Schritt) | ❌ | Kein Skript | - ---- - -## Teil 4: Allgemeine Treuhand-Use-Cases (Prozessdokumentation) - -Diese Use Cases stammen aus der allgemeinen Treuhand-Prozessdokumentation und sind für **alle** Kunden relevant. - -### 4.1 Datenerfassung — Kleine Unternehmen - -| # | Anforderung | Codebase-Status | -|---|-------------|-----------------| -| 4.1.1 | Belege sortieren & mit Banktransaktionen referenzieren | 🔧 — Belegverarbeitung vorhanden; kein Bank-Statement-Matching | -| 4.1.2 | Import Banktransaktionen via Excel/CSV | 🔧 — File-Upload + Extraktion vorhanden; kein dedizierter Bank-Import | -| 4.1.3 | Automatisierte Rückfragen an Kunden bei fehlenden Belegen | ❌ | - -### 4.2 Lohnbuchhaltung - -| # | Anforderung | Codebase-Status | -|---|-------------|-----------------| -| 4.2.1 | Überleitung Lohnaufwand (Fibu vs. Lohnbuchhaltung) | ❌ — Kein Lohn-Feature | -| 4.2.2 | Nicht-lohnwirksame Buchungen identifizieren | ❌ | -| 4.2.3 | Fehlende Lohnmeldungen erkennen | ❌ | - -### 4.3 Steuererklärung - -| # | Anforderung | Codebase-Status | -|---|-------------|-----------------| -| 4.3.1 | Belege nach Kategorien ordnen | 🔧 — Klassifikation vorhanden | -| 4.3.2 | Steuererklärung erstellen | ❌ — Kein Steuer-Feature | -| 4.3.3 | Vorjahresvergleich und Plausibilisierung | ✅ — In Analyse-Prompts | - -### 4.4 Jahresabschluss (Mittlere/Grosse Unternehmen) - -| # | Anforderung | Codebase-Status | -|---|-------------|-----------------| -| 4.4.1 | Banksalden abgleichen (Buchhaltung vs. Bank) | 🔧 — Konzeptionell via Agent; kein dedizierter Check | -| 4.4.2 | PayPal, Revolut, ausländische Konten nachbuchen | ❌ | -| 4.4.3 | Wertschriftendepot nachbuchen | ❌ | -| 4.4.4 | Fehlerkonto-Transaktionen bereinigen | ❌ | -| 4.4.5 | Kreditkartenkonto abstimmen | ❌ | -| 4.4.6 | Zahlungsanbieter prüfen (Stripe, Amex) | ❌ | -| 4.4.7 | Nebenbücher mit Fibu abstimmen | ❌ | -| 4.4.8 | Skonto-Differenzen ausbuchen | ❌ | -| 4.4.9 | Konzerninterne Abstimmung | ❌ | -| 4.4.10 | Darlehenskonten abgleichen, Zinsen berechnen | ❌ | -| 4.4.11 | Fremdwährungsbewertung gemäss ESTV | ❌ | -| 4.4.12 | Eigenkapitalveränderungen mit HR abgleichen | ❌ | -| 4.4.13 | Umsatz-/Aufwandsplausibilisierung | ✅ — Im Jahresabschluss-Prompt | -| 4.4.14 | Rechnungsabgrenzungen (aktiv/passiv) | 🔧 — Im Prompt adressiert | -| 4.4.15 | Abschreibungen erfassen | ❌ | -| 4.4.16 | MWST-Jahresabstimmung | ❌ | -| 4.4.17 | Steueraufwand-Rückstellungen berechnen | ❌ | -| 4.4.18 | Bilanz und ER plausibilisieren | ✅ — Im Jahresabschluss-Prompt | -| 4.4.19 | Analyse gesetzliche Bestimmungen (Kapitalverlust, Überschuldung) | ✅ — Im Jahresabschluss-Prompt | - -### 4.5 Finanzielle Führung & Controlling - -| # | Anforderung | Codebase-Status | -|---|-------------|-----------------| -| 4.5.1 | Businessplan → Absatzplanung → Ertragsplanung | ❌ | -| 4.5.2 | Investitionsplan und Finanzplan | ❌ | -| 4.5.3 | Budget mit Szenarien | 🔧 — Budget-Prompt vorhanden; Szenarien via Chat | -| 4.5.4 | Soll/Ist-Vergleich mit Abweichungsanalyse | ✅ — Budget-Vergleich Prompt-Template | -| 4.5.5 | Deckungsbeitragsrechnung | ❌ | -| 4.5.6 | Projekt-Controlling | ❌ | -| 4.5.7 | Benchmarkanalyse | ❌ | -| 4.5.8 | KPI-Monitoring mit proaktiver Benachrichtigung | 🔧 — KPIs via Agent; kein proaktives Alert-System | - -### 4.6 Revisionen - -| # | Anforderung | Codebase-Status | -|---|-------------|-----------------| -| 4.6.1 | Ordentliche Revisionen unterstützen | ❌ — Kein Revisions-Feature | - -### 4.7 Steueroptimierung & Simulationen - -| # | Anforderung | Codebase-Status | -|---|-------------|-----------------| -| 4.7.1 | Jahresrechnung auf steuerliche Probleme prüfen | ❌ | -| 4.7.2 | Simulationen (Lohn vs. Dividende, Umzug, 3. Säule, BVG) | ❌ | -| 4.7.3 | MWST-Prüfung, VST-Korrekturen | ❌ | -| 4.7.4 | Steuerausscheidungen auf verschiedene Kantone | ❌ | - -### 4.8 Interdisziplinäre Themen - -| # | Anforderung | Codebase-Status | -|---|-------------|-----------------| -| 4.8.1 | Umstrukturierungen | ❌ | -| 4.8.2 | Steuer-/Vorsorgestrategien | ❌ | -| 4.8.3 | Nachfolgeplanung | ❌ | -| 4.8.4 | Unternehmensbewertungen | ❌ | - ---- - -## Zusammenfassung: Status-Überblick - -### Fertig (✅) — Kernplattform funktioniert - -| Bereich | Was steht | -|---------|-----------| -| **Trustee Agent-Tools** | `refreshTrusteeData`, `aggregateTable`, Connection-Pooling, Result-Caching | -| **Graph-Editor** | Trustee-Kategorie + 4 Nodes, SharePoint-Nodes, Flow-Nodes (Loop, If/Else, Switch, Merge) | -| **Prompt-Templates** | 5 Analyse-Typen (Budget, KPI, Cashflow, Prognose, Jahresabschluss) als Quick Actions + Template Workflows | -| **Accounting-Connectors** | Bexio, Abacus, RunMyAccounts | -| **Belegverarbeitung** | Extraktion → Klassifikation → Kontierung → Sync (end-to-end) | -| **CommCoach** | Feature komplett, 10+ Personas inkl. 4 Immobilien-Personas (PWG), Gamification, Seeding | -| **Neutralisierung** | PII-Masking, Playground, Private-LLM, Mieterdossier-PDF | -| **Multi-Tenancy** | Mandantenisolation, Datentrennung, Rollenwechsel | -| **Billing** | BillingDataView, Balance, Transaktionen, useBilling | -| **SharePoint-Integration** | 6 Workflow-Nodes + Automation | -| **Demo-Infrastruktur** | Base-Config, Admin-API, Investor-Demo als Referenz | - -### Teilweise (🔧) — Grundstruktur steht, Erweiterung nötig - -| Bereich | Was fehlt | -|---------|-----------| -| Firmen-Mapping Kunden/Lieferanten | Regelbasiertes Matching-UI | -| Beleg-Tagging | Beleg-spezifisches Tag-System | -| Vorsteuer-Automatisierung | MWST-Zuordnung bei Belegverarbeitung | -| Liquiditätsplanung | Dediziertes Prompt-Template | -| Workspace-Prompt | DE-Placeholder, visuelle Hervorhebung | -| Datei-Drop | Hinweis im Empty State | -| Budget-Prompt | Demo-Excel-Datei fehlt | - -### Offen (❌) — Noch zu bauen - -#### Prio 0: PWG-Pilot (Versand Sommer 2026 — Deadline-gebunden) - -| Item | Aufwand | Beschreibung | -|------|---------|-------------| -| Abacus-Testmandant API-Zugang | Extern | Patrick koordiniert mit Abacus; PWG muss Zugriff bestätigen | -| Prompt-Template "Mietzinsbestätigung prüfen" | Mittel | Neues Template: Scan vs. Originaldaten, Status-Klassifikation, Antwortvorschlag | -| Pilot-Workflow im Graph-Editor | Mittel | trigger → sharepoint.listFiles → loop → download → extract → ai.prompt → report → email | -| Abacus-Mietzins-Stammdaten-Abfrage | Klein | Konfiguration im Abacus-Connector für Mietzins-Referenzdaten | -| Demo-Mandant PWG | Mittel | `pwgDemo2026.py` — Trustee (Abacus), CommCoach, Neutralisierung, Workspace | -| PWG Knowledge-Set | Klein | Öffentliche PDFs (Geschäftsberichte, Vermietungsreglement) in Knowledge-Base laden | -| Preismodell / Kalkulation Pilot | Extern | Grundgebühr/User/Monat + Token-Gebühr; basierend auf 4×800 Schreiben/Jahr | - -#### Prio 1: Demo-Blocker / Weitere Kunden-Demos - -| Item | Aufwand | Beschreibung | -|------|---------|-------------| -| Demo-Mandant Bling | Mittel | `blingDemo2026.py` — Trustee (Bexio), Workspace, Graph-Editor | -| Demo-Mandant Quid | Klein | `quidDemo2026.py` — Workspace, Graph-Editor, CSV-Upload | -| Budget-Excel | Klein | Soll-Werte 2026 für Demo | -| Musterbelege (PDFs) | Klein | 3–5 Belege (Rechnung, Spesen, Bank, Versicherung) | -| Demo-Skripte | Klein | Schritt-für-Schritt pro Kunde | -| Neutralisierungs-Demo-Flow | Klein | Dokumentation | -| Demo-Workflow Graph-Editor (generisch) | Mittel | trigger.manual → SharePoint → Trustee Pipeline | - -#### Prio 2: UI/UX-Verbesserungen (Erstnutzer-Hürde senken) - -| Item | Aufwand | Beschreibung | -|------|---------|-------------| -| Empty State ChatStream | Klein | Titel, Bullets, "Neuer Chat" Button | -| DE-Placeholder + i18n | Klein | `WorkspaceInput.tsx` | -| "Neuer Chat" CTA in Mitte | Klein | `WorkspacePage.tsx` | -| Zwischen-Breakpoint (1025–1280px) | Mittel | Sidebar-Auto-Collapse | -| Trust-Strip/Footer (Login, Landing) | Mittel | Hosting Schweiz, Partner-Logos (Legal nötig) | -| Billing-Teaser nach Login | Klein | Link oder Banner | -| Connector-Onboarding Copy | Klein | Sicherheits-Banner in SourcesTab | -| Balance im UserSection | Klein | Zahl neben Avatar | - -#### Prio 3: Feature-Erweiterungen (Roadmap) - -| Item | Aufwand | Beschreibung | -|------|---------|-------------| -| Xero-Connector | Gross | Neuer Accounting-Connector | -| FileMaker-Connector (PWG) | Gross | Portfolio, Liegenschaften, Erneuerungsplanung; Datenmenge/-qualität erst prüfen | -| Buchungsregeln für wiederkehrende Belege | Mittel | Regel-Engine | -| Liquiditätsplanungs-Template | Klein | Neues Prompt-Template | -| KPI-Monitoring mit Alerts | Gross | Proaktives Benachrichtigungssystem | -| Template-basierte Dokumentenerstellung (HTML → Word) | Mittel | Erneuerungsstrategien, Corporate Design | -| DB-Change-Detection / Notification-Trigger | Mittel | Reagiert auf Datenbank-Änderungen, triggert Workflows | -| Datenvalidierungs-Workflow | Klein | Erst-Audit: welche Daten korrekt/aktuell | - -#### Prio 4: Zurückgestellt (wartet auf externen Input) - -| Item | Wartet auf | Kunde | -|------|-----------|-------| -| Gastro-Echtzeit-Integration | Kevin (Bling) soll UC ausformulieren | Bling | -| Zendesk-Connector | Bewusst CSV-Workaround | Quid | -| Regelbasierte Konsolidierung | Lars-Meeting | Quid | -| Grundstücksanalyse (GIS etc.) | Kundenpräzisierung | PWG | -| FileMaker-Integration (PWG) | Datenmenge/-qualität prüfen (PWG + PowerOn) | PWG | -| PWG Datenschutz-/Vertragsklauseln | PWG prüft intern (genossenschaftliche Struktur) | PWG | - -#### Langfristig: Allgemeine Treuhand-Automatisierung - -Die Use Cases aus Teil 4 (Lohnbuchhaltung, Steuererklärung, detaillierter Jahresabschluss, Revisionen, Steueroptimierung, interdisziplinäre Themen) sind **konzeptionell dokumentiert** aber noch **nicht in der Codebase**. Diese bilden die Langfrist-Roadmap und werden schrittweise über AI-Prompt-Templates und dedizierte Workflows umgesetzt, sobald die Kern-Use-Cases bei den ersten Kunden validiert sind. - ---- - -## Entscheidungen - -| Datum | Entscheidung | Begründung | -|-------|-------------|------------| -| 2026-04-07 | Prompt-Templates als Code in `mainTrustee.py` | Wartbar und versioniert statt externe Dateien | -| 2026-04-07 | `refreshTrusteeData` als separate Action | Separation of Concerns: Sync = schreibend, Query = lesend | -| 2026-04-07 | DB-Connection-Pooling statt Connection-per-Call | Grösster Performance-Hebel (~200ms pro Connection) | -| 2026-04-09 | Quid ohne Zendesk-Connector — CSV-Upload | Gleicher Analyse-Mehrwert, viel weniger Aufwand | -| 2026-04-09 | Gastro-UC und Konsolidierung auf Prio 4 | Warten auf Kunden-Input | -| 2026-04-09 | CommCoach-Personas als schnellster Wow-Effekt für PWG | Feature gebaut, nur Persona-Definitionen nötig | -| 2026-04-07 | UI-Enhancements: Fokus Erstnutzer-Hürde | Ohne klare Userführung springen Kunden ab | -| 2026-04-07 | Trust-Badges: kein ISO, sondern "Daten in CH" | Konkreter Nutzen > abstraktes Zertifikat | -| 2026-04-16 | PWG-Pilot = Jahresmietzinsbestätigungen als erster Produktiv-UC | Konkreter, messbarer Business Case (4×800 Schreiben); Deadline Sommer 2026 | -| 2026-04-16 | Workflow-Philosophie PWG: erst manuell testen, dann automatisieren | Agent wird aus manuell getesteten Prozessen erstellt; Workflows für wiederkehrende Aufgaben | -| 2026-04-16 | FileMaker-Integration auf Prio 4 | Datenmenge/-qualität muss erst geprüft werden; kein Blocker für Pilot | -| 2026-04-16 | Abacus-Testmandant als Voraussetzung für Pilot | Patrick koordiniert API-Zugang direkt mit Abacus | - ---- - -## Betroffene Module - -- **Gateway:** `features/trustee/` (Prompts, Quick Actions, Connectors), `features/commcoach/` (Personas), `features/neutralization/` (Demo-Config), `features/graphicalEditor/` (Nodes), `serviceCenter/services/serviceAgent/` (Tools, Caching), `demoConfigs/` (neue Configs), `workflows/methods/methodTrustee/` (Actions), `demoData/` (Testdaten) -- **Frontend Nyla:** `WorkspacePage.tsx` (Layout, Breakpoints, Empty State), `WorkspaceInput.tsx` (Prompt, i18n), `ChatStream.tsx` (Empty State), `Login.tsx` (Trust-UI), `UserSection.tsx` (Balance), `SourcesTab.tsx` (Onboarding-Copy), `BillingDataView.tsx` (Discovery) -- **DB-Migration:** Nein -- **Platform/Wiki:** Nach Release `b-reference/` aktualisieren - -## Links - -- PWG Workshop-Inputs (16.04.2026): `pamocreate/projects/poweron/customer-pwg/20260415-inputs-pwg.txt` -- Originale Kunden-Inputs: `local/notes/demo-tue-use-cases-inputs-customers.md` -- Merged Demo-Plan (ersetzt): `c-work/1-plan/2026-04-demo2-merged-customer-trustee-plan.md` -- UI-Enhancements Plan (ersetzt): `c-work/1-plan/2026-04-porta-ui-enhancements-team-meeting.md` -- Investor-Demo (Referenz): `platform-core/modules/demoConfigs/investorDemo2026.py` -- Frontend-Referenz: `b-reference/ui-nyla/architecture.md` -- Trustee Main (Prompts): `platform-core/modules/features/trustee/mainTrustee.py` -- CommCoach Personas: `platform-core/modules/features/commcoach/serviceCommcoachPersonas.py` -- Neutralisierung: `platform-core/modules/features/neutralization/` -- Graph-Editor Nodes: `platform-core/modules/features/graphicalEditor/nodeDefinitions/` -- Demo-Daten: `platform-core/demoData/` -- UDM-Konzept: `c-work/0-ideas/unified-document-model.md` - -## Abschluss - -- [ ] Quell-Dokumente als "superseded by this document" markieren -- [ ] b-reference/ aktualisiert nach Umsetzung -- [ ] TOPICS.md aktualisiert -- [ ] Dieses Dokument → `1-plan/` verschieben wenn Umsetzung startet diff --git a/c-work/0-ideas/2026-06-CustomerCases-step1-architecture.md b/c-work/0-ideas/2026-06-CustomerCases-step1-architecture.md new file mode 100644 index 0000000..d178977 --- /dev/null +++ b/c-work/0-ideas/2026-06-CustomerCases-step1-architecture.md @@ -0,0 +1,291 @@ + + + + +# Architektur: Vom Kundenbedürfnis zur Lösung — generische Workflow-/Solution-Schicht + +> **Ebene:** App-/Plattform-Architektur (eine Stufe über den Feature-/Connector-Plänen). +> **Frage, die wir lösen:** Wie erfüllt PORTA *jedes* wiederkehrende Kundenbedürfnis **ohne kundenspezifischen Code** — als konfigurierte Komposition vorhandener Bausteine? + +## Vision: Konfigurierte Use Cases statt geschriebener Applikationen + +Der eigentliche Paradigmenwechsel hinter diesem Plan: + +**Klassische Software ist von gestern.** Bisher löst man ein Geschäftsproblem, indem jemand eine Applikation *schreibt* — pro Problem, pro Kunde, in Wochen/Monaten. Die Software ist das Asset; jede Anpassung kostet Engineering. + +**Wir drehen das um: wir *konfigurieren* komplexe Use Cases, statt Applikationen zu schreiben.** Genau das, was eine AI heute schon tut, wenn sie assistiert: Du beschreibst eine *Absicht*, das System *komponiert* vorhandene Fähigkeiten (Tools, Daten, Logik) zu einem Ergebnis — niemand baut dafür eine App. Diese Architektur ist dieses Prinzip, **produktisiert**: + +| AI-Assistenz (heute, z. B. Cursor) | PORTA Solution-Schicht | +|---|---| +| Du beschreibst die Absicht | Business-User beschreibt den Use Case (L4) | +| AI plant die Schritte | Workflow-Agent komponiert den Graph (L2/L3) | +| AI nutzt Tools (lesen, schreiben, ausführen) | Graph nutzt Actions/Connectors (L1) | +| Ergebnis: einmalig, im Chat | Ergebnis: **dauerhaft** — konfiguriert, geplant, governt, mandantenfähig, dem Kunden gehörend | + +**Was das für Kunden bedeutet — «next level»:** +- **Massgeschneidert ohne Massanzug-Kosten:** der exakte Fall (Plings 5 Stores, ihre Konten-Ranges) ohne bespoke Entwicklung. +- **Tage statt Monate**, Self-Service statt Vendor-Backlog. +- **Grenzkosten eines neuen Use Cases → nahe null:** Konfiguration, nicht Code. + +**Zu Ende gedacht (ehrlich, kein Hype):** +- Es verschwindet *nicht* alle Software. Die **Bausteine** (Connectors, Actions, Engine) und einige **tiefe Features** (eigenes Datenmodell/UI, z. B. `lawyer`) bleiben klassisch geschriebene Software. Der Wechsel passiert in der **Mitte**: die vielen massgeschneiderten Einzellösungen, die man bisher pro Kunde gebaut hat, werden zu **Konfiguration**. Engineering wandert nach **unten** (haltbare, wiederverwendbare Primitive) und nach **oben** (AI-gestützte Konfiguration) — und verschwindet aus der teuren Mitte. Das ist exakt die Feature-vs-Solution-Grenze. +- **Vertrauen ist Voraussetzung, kein Nachgedanke.** Wenn AI/Konfiguration komponiert, braucht es Leitplanken — typisierte Actions, Neutralisierung, Review-vor-Aktivierung, Testlauf ohne Versand. Im Treuhand-/Finanzkontext ist das Pflicht. PORTA hat diese Leitplanken bereits — das macht «konfigurieren statt coden» hier *seriös* möglich. +- **Der Moat** ist nicht ein einzelnes Feature, sondern die **Toolbox + Kompositions-Engine + die AI, die Absicht → Komposition** übersetzt. + +**In einem Satz:** PORTA verkauft künftig nicht «eine App», sondern die **Fähigkeit, jeden wiederkehrenden Geschäfts-Use-Case zu konfigurieren** — der konfigurierte Use Case ist das Asset, nicht der handgeschriebene Code. + +## Beschreibung und Kontext + +Viele Kunden (v. a. im Feature **Trustee**) haben **dasselbe Grundmuster** an Bedürfnissen. Die Kern-Logik: + +> Ein Kunde hat kein «Workflow-Problem», sondern ein **Bedürfnis**. Dieses Bedürfnis lässt sich als **Use Case** formulieren, daraus wird — AI-gestützt — ein **Workflow** aus vorhandenen Bausteinen komponiert, **einmal konfiguriert**, **getriggert** (manuell oder per Zeitplan) und dessen **Ergebnis angesehen**. Drumherum braucht es eine **Verwaltung**, mit der ein Business-User genau das selbst tut — ohne dass wir pro Kunde Code schreiben. + +Konkrete Bedürfnisse, immer dieselbe Logik: +- Zwei Systeme synchronisieren, einmal einstellen, täglich um 06:00 via Scheduler (Solution S1, → `0-ideas/2026-06-CustomerCases-step3-solutions-plan.md`). +- **Monatsreporting über mehrere Buchhaltungen** (Pling «Kaffee-Klatsch»): am 15. des Monats aus 5 RMA-Buchhaltungen konsolidieren, 6 PDF-Reports erzeugen, **rollenbasiert** per Mail verteilen (Solution S2, → `0-ideas/2026-06-CustomerCases-step3-solutions-plan.md`; Spec: `pamocreate/projects/poweron/customer-pling/20-spezifikation/20260522-workflow-spec-kaffee-klatsch.md` + Anhang). +- Gescannte Jahresmietzinsbestätigungen verarbeiten + Antwortvorschläge (PWG-Pilot, Solution S3, → `0-ideas/2026-06-CustomerCases-step3-solutions-plan.md`). +- Mandatsvorbereitung + Dashboards (Feature, → `0-ideas/2026-06-CustomerCases-step3-features-plan.md`, B1). + +**Beobachtung:** Alle vier Beispiele sind **Instanzen desselben Musters**: ein Bedürfnis wird durch eine **Komposition vorhandener Bausteine** (Connectors, Actions/Nodes, AI, Neutralisierung, Dashboards) erfüllt — nicht durch neuen, kundenspezifischen Code. Die Bausteine existieren bereits (Action Library, Graphical Editor, Scheduler, Templates, Connectors, Toolbox). **Was fehlt, ist die Schicht darüber:** eine generische, **kundentaugliche** Oberfläche, mit der ein Business-User (kein Techniker) eigene Workflows **anlegen lässt (AI), konfiguriert, testet, ausführt, ansieht und verwaltet**. + +Business-Treiber: +- Skaliert ohne Engineering pro Kunde/Workflow (das eigentliche Plattform-Versprechen). +- Verwandelt jedes Kunden-«Bedürfnis» in ein Self-Service-Produkt → kürzeres Onboarding, höhere Marge. +- Macht die bereits gebauten Bausteine endlich für Endkunden zugänglich (heute nur über den technischen Editor). + +## Fokus und kritische Details + +- **Das Problem ist NICHT «noch ein Feature», sondern eine fehlende Produkt-Schicht.** Wir bauen kein viertes Buchhaltungs-Detail, sondern die generische **Lifecycle-Verwaltung** für kundeneigene Workflows. +- **Trennung Baustein ↔ Kundenlogik ist Plattform-Gesetz** (gilt schon für Connectors): Bausteine = Code; konkrete Kundenlösung = **Daten** (Graph + Settings + Trigger + Output-Bindung). +- **«Settings in den Notes» ist die falsche Abkürzung.** Einstellungen in Freitext-Notes abzulegen ist verlockend, aber ein Hack. Architektonisch braucht es ein **strukturiertes, validiertes Settings-Modell** pro Workflow (typisiert, versioniert). +- **Feature vs. Solution — die wichtigste Grenze.** Nicht jedes Bedürfnis rechtfertigt ein Code-Feature (wie `lawyer`). Default ist eine **konfigurierte Solution** (Template + Settings). Ein Code-Feature nur, wenn eigene Datenmodelle / tiefe opinionated UI / Domänenlogik nötig sind, die der Graph nicht ausdrücken kann (siehe Entscheidungstabelle). +- **Zwei Personas, zwei Oberflächen:** Der **Graphical Editor** bleibt das technische Authoring-Tool (n8n-Stil). Neu kommt eine **Business-Oberfläche** (Lösungen verwalten), die den Graph *kapselt*. Sie ist die Antwort auf «wo stelle ich meine Sachen ein?». +- **Fragile/relevante Stellen:** `AutoWorkflow/AutoVersion/AutoRun` (Greenfield-DB `poweron_graphicaleditor`), Scheduler (`mainScheduler.py`), Template-Scopes (`user|instance|mandate|system`), Action-Catalog (`/api/automation2/catalog`), Workflow-Agent-Toolbox (`workflow`-Tools: `addNode`, `bindNodeParameter`, …). Wir bauen **auf** diesen, nicht daneben. + +## Ziel und Nicht-Ziele + +- **Ziel:** Ein generisches **Solution-Konzept** definieren: «konfigurierte, getriggerte, kundentaugliche Verpackung eines Workflows», mit Settings-Schema, Trigger-Policy und Output-/Dashboard-Bindung — als **Daten pro Feature-Instanz**. +- **Ziel:** Eine **kundenseitige Verwaltungs-Oberfläche** (Lifecycle: anlegen → konfigurieren → testen → aktivieren → ausführen → ansehen → verwalten), zuerst im Feature Trustee, dann feature-übergreifend wiederverwendbar. +- **Ziel:** **AI-gestützte Erzeugung** «Use Case → Workflow» über den bestehenden Workflow-Agent. +- **Ziel:** Ein **Use-Case-Katalog** (kuratierte System-Templates) als Startpunkt für die häufigsten Bedürfnisse. +- **Ziel:** Architektur so, dass die vier Beispiele sauber als Spezialfälle abbildbar sind (Validierung unten). +- **Explizit NICHT:** kundenspezifischer Code pro Workflow. +- **Explizit NICHT:** den Graphical Editor ersetzen — wir kapseln ihn. +- **Explizit NICHT:** Settings in Notes/Freitext. +- **Explizit NICHT (jetzt):** Marktplatz/Sharing zwischen Mandanten, Billing-Redesign — später. + +## Das wiederkehrende Muster (Kern der Architektur) + +Jedes Kundenbedürfnis hat dieselbe Form: + +``` +BEDÜRFNIS ──(als Use Case formuliert)──► WORKFLOW (Komposition von Bausteinen) + │ + ┌───────────────┬───────────────┬────┴────────┬──────────────┐ + SETTINGS TRIGGER DATENQUELLEN AI/LOGIK OUTPUT/VIEW + (einmal einst.) (manuell/Zeit/ (Connectors; (Nodes/ (Dashboard/ + Event/Form) eigener Plan) Agent) Report/Mail/Tabelle) +``` + +Beispiele auf dieselbe Form gebracht: + +| Bedürfnis | Trigger | Bausteine (Nodes) | Settings | Output | +|---|---|---|---|---| +| 2 Systeme synchronisieren | `trigger.schedule` 06:00 | source-connector → `mapAccounts` → target-connector | Quelle/Ziel, Mapping | Sync-Log/Status | +| **Monatsreporting 5 Buchhaltungen (Pling)** | `trigger.schedule` 15./06:00 + `trigger.manual` (rollen-beschränkt) | `loop`(5 Instanzen) → `refreshAccountingData` → `queryData`(Salden akt.+VJ) → `data.consolidate` → `ai.generateDocument`×6 → `rbac.queryUsersByRole` → `outlook.send` → `file.create` | Perioden, Konten-Ranges, Empfänger-Rollen, Cron, Branding | 6 PDFs + Mails + Lauf-Protokoll | +| Mietzinsbestätigungen (PWG) | `trigger.schedule` | `sharepoint.listFiles` → `loop` → `extractFromFiles` → `ai.prompt` → `data.write` → `email.send` | Ordner, Abacus-Mandant, Empfänger | Übersichtstabelle + Mail | +| Matter Preparation (Lawyer) | `trigger.manual/form` | `lawyer.prepareMatter` (Agent über Quellen) | Lookback, Quellen | Briefing + Dashboards | + +→ **90 % des Kundenwerts ist Komposition, nicht Code.** Die Bausteine sind da. Die **Verpackung + Verwaltung** fehlt. + +### Was der Pling-Fall zusätzlich schärft + +Der Pling-«Kaffee-Klatsch»-Fall (vollständig spezifiziert inkl. Graph, Configs, Build-Items) zeigt zwei Verfeinerungen, die das Schema bestätigen statt es zu brechen: + +1. **Eine Solution kann über mehrere Feature-Instanzen fan-out-en.** Ein Mandant hat hier **5 Trustee-Instanzen** (1 pro Store); die Solution läuft per `flow.loop` über alle. → Solution-**Scope** ist nicht zwingend «1 Instanz», sondern «ein Set von Instanzen eines Mandanten». Das Settings-Modell muss eine Instanz-Auswahl tragen. +2. **Die «Kundenspezifika» sind durchweg Daten — die Lücken sind generische Bausteine.** Was Pling besonders macht (5 Stores, Konten-Ranges 3000–3999/6000–6299/5000–5099, Empfänger, Cron), ist **Settings**. Was im Code fehlt, sind **zwei generische Plattform-Bausteine**, kein Kunden-Code: + - `rbac.queryUsersByRole` — **rollenbasierte Empfänger-Auflösung** (Verteiler aus Trustee-Rollen statt gepflegter Listen). Wiederverwendbar für jedes Report-/Notification-Bedürfnis. + - **Trigger-Zugriffskontrolle** (`accessControl.requiredRoles` im `triggerExecutor`) — damit nur z. B. `trustee-admin` den manuellen Lauf auslösen darf. + + Genau diese Trennung ist die Architektur-These: *Kundenspezifika → Settings/Graph (Daten); was fehlt → generische L1/L2-Bausteine.* + +Weitere wiederverwendbare Muster aus dem Fall: **Konsolidierung** mehrerer Instanzen (`data.consolidate` sumByKey), **selektive Neutralisierung** (nur Namen/Beschreibungen pseudonymisiert, Zahlen/Konten lesbar), **Teil-Resultat-Toleranz** (unvollständige Buchhaltung → durchlaufen mit Markierung, steuerbar per Settings-Flag `stopOnIncomplete`), **Archivierung** der Outputs als `TrusteeDocument`. + +## Schichten-Modell (Zielarchitektur) + +``` +┌───────────────────────────────────────────────────────────────────────────┐ +│ L4 SOLUTION SURFACE (kundentaugliche UX, pro Feature-Seite) NEU │ +│ «Lösungen»: Katalog · Anlegen(AI) · Settings · Test · Runs · View │ +├───────────────────────────────────────────────────────────────────────────┤ +│ L3 SOLUTION DEFINITION (Use Case → konfigurierter Workflow) NEU │ +│ Solution = Template/Version + Settings-Schema + Trigger-Policy + Output │ +│ Use-Case-Katalog · AI-Generierung · strukturierte Settings (kein Notes) │ +├───────────────────────────────────────────────────────────────────────────┤ +│ L2 COMPOSITION (Graph) VORHANDEN │ +│ AutoWorkflow/Version/Run · Graphical Editor · Templates (scopes) │ +├───────────────────────────────────────────────────────────────────────────┤ +│ L1 PLATTFORM-TOOLBOX (Bausteine) VORHANDEN │ +│ Connectors/Datenquellen · Action Library (Methods/Actions=Nodes) · │ +│ AI/Agent+Toolbox · Neutralisierung · Knowledge/RAG · Scheduler · │ +│ Dashboards-Primitive · RBAC · Multi-Tenancy │ +└───────────────────────────────────────────────────────────────────────────┘ +``` + +**L1/L2 existieren** (siehe `b-reference/platform-core/workflow.md`, `automation.md`). **L3/L4 sind neu** und der eigentliche Gegenstand dieses Dokuments. + +### L3 — Solution Definition (das neue Kern-Konzept) + +Eine **Solution** ist die kundentaugliche Verpackung eines Workflows: + +| Bestandteil | Inhalt | Baut auf | +|---|---|---| +| **Workflow-Bindung** | Referenz auf `AutoWorkflow` + `PUBLISHED` `AutoVersion` | vorhanden | +| **Settings-Schema** | typisierte, validierte Parameter, die der Kunde einstellen darf (z. B. «SharePoint-Ordner», «Empfänger», «Periode», «Konten-Mapping») | `FrontendType`/Typed-Action-System, `trigger.form`-Schema | +| **Settings-Werte** | konkrete Belegung pro Solution (inkl. **Instanz-Auswahl** bei Multi-Instanz-Fan-out, z. B. Pling 5 Stores) | neu (Record) | +| **Trigger-Policy** | manuell / Zeitplan / Event / Form, inkl. **Zugriffskontrolle** (welche Rolle darf manuell auslösen) | Scheduler + Trigger-Nodes (+ `accessControl`) | +| **Output-/View-Bindung** | was der Kunde nach dem Lauf sieht — `kind: file \| table \| summary` (Dashboard später); siehe «Output-Bindung — Empfehlung» | `file.create`/Datenraum, FormGenerator/Data-Tables, `AutoRun`/`AutoStepLog` | +| **Katalog-Herkunft** | aus Use-Case-Template instanziiert ODER per AI generiert | System-Templates + Workflow-Agent | + +**Designentscheidung (bestätigt 2026-06-04):** Solution **nicht** als grosse neue Parallel-Welt bauen, sondern als **dünne Erweiterung** auf `AutoWorkflow` (Settings-Schema + Presentation-Binding + «is customer-facing»-Flag) plus einen **Settings-Record**. Das hält eine einzige Workflow-Wahrheit (Scheduler, Runs, Versioning greifen unverändert). + +**Settings statt Notes:** Das Settings-Schema wird aus dem Graphen abgeleitet (Trigger-Form / als «exposed» markierte Node-Parameter) und/oder kuratiert. Validierung + Verschlüsselung (für Secrets) wie bei Connector-Configs. Das ist die saubere, wartbare Alternative zu Einstellungen in Freitext-Notes. + +### L4 — Solution Surface (kundentaugliche UX) + +Eine **Seite pro Feature** (Start: Trustee), Name «**Lösungen**», mit dem Lifecycle: + +``` +[Katalog/Neu] [Meine Lösungen] [Detail einer Lösung] + ├─ Use-Case wählen ├─ Liste (aktiv/inaktiv) ├─ Settings (Formular) + ├─ oder beschreiben (AI) ├─ Status letzter Lauf ├─ Test / Probelauf + └─ → erzeugt Workflow ├─ nächster geplanter Lauf ├─ Aktivieren + Zeitplan + └─ Run-Historie ├─ Run-Trace (lesbar) + ├─ Output/Dashboard + └─ «Im Editor öffnen» (Advanced) +``` + +- **UI-Struktur (Antwort auf Frage 1):** **Eine** Seite «Lösungen» pro Feature — *kein* Seiten-Wildwuchs und keine Aufblähung der technischen Automation-UI. Diese eine Seite hat **Unteransichten** (Liste · Katalog/Neu · Detail) und das **Detail hat Tabs**: *Einstellungen · Testlauf · Läufe · Ausgabe*. +- Business-User bleibt in L4; «Im Editor öffnen» ist die **Escape-Hatch** nach L2 für Power-User/uns. +- Wiederverwendung: Run-Historie/Trace existiert (`AutoRun`/`AutoStepLog`, SSE `runs/{runId}/stream`); wir rendern es nur **kundentauglich** statt technisch. +- Verknüpfung zum Datenquellen-Plan: «Datenquellen» (Connectors) ist eine Schwester-Seite; «Lösungen» nutzt die dort konfigurierten Quellen. + +### AI: Use Case → Workflow + +Der bestehende **Workflow-Agent** (Toolbox `workflow`: `readWorkflowGraph`, `addNode`, `bindNodeParameter`, `listUpstreamPaths`, …) ist bereits der Mechanismus, um aus einer Beschreibung einen Graphen zu bauen/ändern. L3 stellt ihm: +1. den **Use-Case-Text** des Kunden, +2. den **Action-Catalog** (verfügbare Bausteine, `/api/automation2/catalog`), +3. die **konfigurierten Datenquellen** der Instanz, +bereit und lässt ihn einen Graphen erzeugen → als Draft-Version speichern → der Kunde konfiguriert nur noch die Settings. Kuratierte **System-Templates** decken die häufigsten Fälle deterministisch ab (kein AI-Risiko); AI nur für Neues/Abweichendes, **mit Review-/Freigabe-Schritt vor Aktivierung**. + +## Feature vs. Solution — die Architektur-Entscheidung + +| Kriterium | → **Solution** (Daten/Config) | → **Feature** (Code) | +|---|---|---| +| Eigene Datenmodelle nötig? | nein (nutzt bestehende) | ja (z. B. `LawyerMatter`) | +| Tiefe, opinionated UI? | nein (generische Solution-UX) | ja (z. B. Matter-Preparation-View) | +| Aus Bausteinen komponierbar? | ja | nein (Domänenlogik) | +| Time-to-value | Tage | Wochen | +| Beispiel | SelectLine→RMA-Sync, Monatsbericht, PWG-Pilot | `lawyer`, `commcoach`, `trustee` selbst | + +**Leitsatz:** *Solution-first.* Ein Code-Feature wird nur gebaut, wenn die Solution-Schicht es nachweislich nicht trägt. So bleibt die Plattform schlank und die «keine Kundenlogik im Code»-Regel real. + +## Validierung an den Beispielen + +| Beispiel | Abbildung in dieser Architektur | +|---|---| +| **Umsystem-Integration** (SelectLine→RMA) | L1: SelectLine/RMA-Connectors · L2: Import-Graph · L3: Solution «Systeme synchronisieren» (Settings: Quelle/Ziel/Mapping/Zeitplan) · L4: erscheint unter «Lösungen» neben «Datenquellen» | +| **Pling Kaffee-Klatsch** (Monatsreporting) | L1: 5× RMA-Connector, Outlook, `data.consolidate`, `ai.generateDocument` · L2: Fan-out-Graph (`loop` über 5 Instanzen, Konsolidierung, 2 Report-Loops, Verteilung) · L3: Solution mit Settings (5 Instanzen, Konten-Ranges, Cron, Empfänger-Rollen, `stopOnIncomplete`) + Output (6 PDFs, archiviert) · L4: «Jetzt ausführen» (rollen-beschränkt), Run-Historie, Status. **Deckt 2 generische Bausteinlücken auf** (`rbac.queryUsersByRole`, Trigger-`accessControl`) — kein Kunden-Code. | +| **PWG-Pilot** (Mietzinsbestätigungen) | L1: SharePoint/Abacus/Email/extract/ai · L2: 7-Schritt-Graph · L3: Solution mit Settings (Ordner, Mandant, Empfänger) + Output-Tabelle · L4: Test/Aktivieren/Run-Historie | +| **Lawyer-Feature** | Mischfall: **Feature** (eigene Modelle + opinionated UI) **plus** Solutions darin (Matter-Prep, Dashboard-Refresh). Bestätigt die Feature-vs-Solution-Grenze. | + +→ Alle vier passen ohne Architektur-Bruch. Das Muster trägt. Der Pling-Fall ist der **stärkste Beleg**: vollständig spezifiziert, ~2 Wochen Build, fast ausschliesslich vorhandene Bausteine — und die einzigen Code-Lücken sind **generisch**, nicht kundenspezifisch. + +## Betroffene Module (Skizze) + +- **Gateway:** + - `features/graphicalEditor/` — `AutoWorkflow` um Settings-Schema + Presentation-Binding + `customerFacing`-Flag erweitern; Settings-Record-Modell. **DB-Migration: ja (Greenfield, additiv).** + - `workflows/scheduler/mainScheduler.py` — unverändert nutzbar (Trigger-Policy mappt auf bestehende Schedule-Logik). + - `interfaces/interfaceBootstrap.py` — Use-Case-Katalog als System-Templates. + - `serviceCenter/services/serviceAgent/` (Toolbox `workflow`) — Use-Case→Graph-Generierung; ggf. Prompt/Guardrails ergänzen. + - Solution-Routes (CRUD Settings, Test-Run, Activate) — dünn über bestehende Editor-/Run-Routes. + - **Generische Bausteine aus dem Pling-Fall** (wiederverwendbar, kein Kunden-Code): neue Action `rbac.queryUsersByRole` (rollenbasierte Empfänger-Auflösung) und `triggerExecutor`-Erweiterung um `accessControl.requiredRoles` (Rollen-Check beim manuellen Trigger). + - **Testlauf-Modus:** run-level `testMode` im Run-Context; kommunikations-/seiteneffekt-Actions (Mail/Outlook/Teams/Webhook) prüfen das Flag und unterdrücken den ausgehenden Versand (loggen «würde senden an …»). Reports/Dateien werden trotzdem erzeugt (siehe Frage 7). + - Solution-Scope: Settings müssen ein **Set von Feature-Instanzen** referenzieren können (Multi-Instanz-Fan-out, z. B. 5 Stores). +- **Frontend (ui-nyla):** + - Neue generische **`SolutionsView`** (Katalog · Liste · Detail mit Settings-Formular · Test · Runs · Output), als Feature-Seite registriert (analog `FeatureView.tsx` VIEW_COMPONENTS + UI-Areas in `main.py`). + - Settings-Formular-Renderer aus dem Settings-Schema (FrontendType-getrieben). +- **DB-Migration:** ja (additiv auf Greenfield-DB). +- **Andere:** RBAC (neue UI-Area, customer-facing Rollen), Neutralisierung (unverändert über Services), Billing (Run-Volumen). + +## Entscheidungen (Vorschläge — zu bestätigen) + +| Datum | Entscheidung | Begründung | +|-------|-------------|------------| +| 2026-06-04 | Neue **Solution-Schicht (L3/L4)** statt neues Feature pro Bedürfnis | Skaliert ohne Code pro Kunde | +| 2026-06-04 | Solution = **dünne Erweiterung von `AutoWorkflow`** + Settings-Record (keine Parallel-Welt) | Eine Workflow-Wahrheit; Scheduler/Runs/Versioning unverändert | +| 2026-06-04 | **Strukturierte Settings** statt Notes | Validierbar, versioniert, sicher (Secrets) | +| 2026-06-04 | **Solution-first**, Feature nur bei eigenem Datenmodell/Tiefe | «keine Kundenlogik im Code» real halten | +| 2026-06-04 | Start im Feature **Trustee**, Schicht aber **feature-übergreifend** designen | breiteste Wiederverwendung | +| 2026-06-04 | Solution-Scope = **Set von Feature-Instanzen** (nicht nur eine) | Pling-Fan-out (5 Stores) bricht sonst das Modell | +| 2026-06-04 | Rollenbasierte Verteilung als **generischer Baustein** (`rbac.queryUsersByRole`) | aus Pling abgeleitet, wiederverwendbar für jedes Report-/Notification-Bedürfnis | +| 2026-06-04 | UI = **eine «Lösungen»-Seite pro Feature** mit Unteransichten (Liste/Detail) + Tabs im Detail | kein Seiten-Wildwuchs; Technik-UI bleibt unangetastet (Frage 1) | +| 2026-06-04 | Settings-Schema **automatisch abgeleitet** (aus `trigger.form`/exposed Params) | minimaler Pflegeaufwand; Overrides später (Frage 2) | +| 2026-06-04 | **AI-Generierung ja** — Templates deterministisch, AI nur für Neues + Review vor Aktivierung | Geschwindigkeit ohne Kontrollverlust (Frage 3) | +| 2026-06-04 | RBAC: **bestehende Feature-Rollen** nutzen, keine neuen customer-facing Rollen | weniger Komplexität; konsistent zu Feature (Frage 5) | +| 2026-06-04 | Naming: **«Lösungen»** (engl. *Solutions*) | bestätigt (Frage 6) | +| 2026-06-04 | Testlauf = **realer Lauf mit `testMode`** (Kommunikation unterdrückt, Artefakte erzeugt) | echtes Verhalten testen, ohne ungewollte Mails (Frage 7) | +| 2026-06-04 | Output-Bindung **gestuft** (`file`/`table`/`summary` jetzt, `dashboard` später) | nutzt Vorhandenes; keine BI-Engine bauen (Frage 4 — Detail offen) | + +## Beantwortete Fragen (Entscheid 2026-06-04) + +1. **Daten-Heimat:** ✅ **`AutoWorkflow` erweitern** (kein eigenes Solution-Modell). + *UI-Konsequenz (deine Frage):* Die Backend-Erweiterung berührt die technische Automation-UI (Graphical Editor / Ops) **nicht** — es entstehen **nicht** «viele Automation-Seiten». Stattdessen **eine** neue kundentaugliche Seite **«Lösungen» pro Feature**, die denselben `AutoWorkflow` nur anders *präsentiert*. Aufbau: **Liste** (aktiv/inaktiv, letzter/nächster Lauf) · **Katalog/Neu** (Vorlage oder AI) · **Detail mit Tabs** (*Einstellungen · Testlauf · Läufe · Ausgabe*). Also: **eine Seite pro Feature, Unteransichten + Tabs im Detail** — siehe Mockup. +2. **Settings-Schema-Quelle:** ✅ **Automatisch abgeleitet** aus `trigger.form` + als «exposed» markierten Node-Parametern. (Kuratierte Overrides bei Bedarf später.) +3. **AI-Generierung:** ✅ **Ja.** Katalog-Templates deterministisch; AI nur für Neues, mit Review-/Freigabe-Schritt vor Aktivierung. +4. **Output/Dashboard:** ⚠️ **Richtung entschieden, Detail offen — Empfehlung im nächsten Abschnitt.** +5. **RBAC:** ✅ **Bestehende Feature-Rollen** (z. B. `trustee-admin` anlegen/aktivieren/manuell starten; `trustee-*` ansehen). Keine neuen customer-facing Rollen. +6. **Naming:** ✅ **«Lösungen»** (engl. *Solutions*). +7. **Test/Probelauf:** ✅ **Realer Lauf, Kommunikation blockierbar.** Der Testlauf läuft echt (echte Daten/Bausteine), nur **ausgehende Kommunikation wird unterdrückt** via run-level **`testMode`**: Mail/Outlook/Teams/Webhook-Actions prüfen das Flag und senden nicht (loggen «würde senden an …»). Reports/Dateien entstehen trotzdem. Sauberer als ein vollständig isolierter Mock-Run. + +## Output-Bindung — Empfehlung (Frage 4) + +Der schwierigste Punkt, weil «Output» von «PDF im Mail-Anhang» bis «interaktives Dashboard» reicht. **Empfehlung: gestuft, kleinster tragfähiger Kern zuerst — keine generische Dashboard-Engine bauen.** Eine Solution deklariert eine `outputBinding` mit einem `kind`: + +| `kind` | Was der Kunde sieht | Baut auf (vorhanden) | deckt ab | +|---|---|---|---| +| `file` | Liste erzeugter Dokumente (PDF/XLSX), Öffnen/Download | `file.create` → `TrusteeDocument` / Datenraum | Pling, SelectLine-Log | +| `table` | Ergebnis-Tabelle (sortier-/filterbar) | FormGenerator / Data-Tables (`queryData`) | PWG-Übersicht | +| `summary` | Status/Kennzahlen + Lauf-Protokoll | `AutoRun`/`AutoStepLog` (Run-Trace) | jeder Sync/Lauf | +| `none` | nur Lauf-Status | — | reine Mail-Workflows | + +- **Jetzt bauen:** `file`, `table`, `summary` — alle nutzen Vorhandenes, kein neuer Renderer-Stack. Deckt alle vier Cases ab. +- **Später:** Rich-Dashboards über die **bestehende AI-Report-/Canvas-Pipeline** wiederverwenden (`kind: dashboard`), nicht neu erfinden. +- **Abgrenzung (wichtig):** Braucht ein Kunde eine **tiefe, opinionated Dashboard-UI**, ist das das Signal für ein **Feature** (Code), nicht für eine Solution. Die Output-Bindung bleibt bewusst schlank — sie *zeigt* Ergebnisse, sie ist keine BI-Engine. +- **Detail beim Bauen (offen):** genaues `outputBinding`-Schema (wie referenzieren wir das Artefakt — Run-Output-Key vs. Document-Query) und ob `table`-Spalten frei konfigurierbar sind oder aus dem Node-Output abgeleitet werden. *Vorschlag:* aus Node-Output ableiten (konsistent zu Frage 2). + +## Meine Gedanken / Empfehlung + +- **Das ist kein Feature, das ist *die* Produktisierung der Plattform.** Bisher ist PORTA ein Werkzeugkasten mit zwei Enden (technischer Editor + Ops-Dashboard). Die fehlende Mitte — eine kundentaugliche **Solution-Schicht** — ist der Hebel, der aus «wir bauen pro Kunde» ein skalierendes SaaS macht. +- **Nichts Neues erfinden, verpacken.** Alle Bausteine (Graph, Templates, Scheduler, Agent, Connectors) sind da. Der Aufwand liegt in **L3 (Settings/Trigger/Output als Daten)** und **L4 (eine gute, einfache UX)** — nicht in neuer Engine. +- **Die wichtigste Disziplin ist die Feature-vs-Solution-Grenze.** Ohne sie bauen wir wieder pro Kunde ein Feature (siehe die Klassifikationstabelle im `CustomerCases-step3-solutions-plan`). Mit ihr wird der Default «konfigurieren statt coden». +- **Settings strukturieren, nicht in Notes.** Das ist die kleine Entscheidung mit grosser Wirkung: sie macht Solutions wartbar, sicher und versionierbar. +- **Pling als idealer erster realer Beleg.** Der Fall ist bereits voll spezifiziert (~2 Wochen Build) und braucht nur zwei *generische* Ergänzungen (`rbac.queryUsersByRole`, Trigger-`accessControl`). Er beweist die These am konkreten Geld-Use-Case und liefert nebenbei wiederverwendbare Bausteine. +- **Inkrementeller erster Schnitt:** (1) `AutoWorkflow` um Settings-Schema + `customerFacing` + Instanz-Set erweitern; (2) 1–2 kuratierte System-Templates (z. B. «Systeme synchronisieren» und «Periodisches Reporting» aus Pling); (3) minimale `SolutionsView` (Liste + Settings + Test + Aktivieren + Run-Historie) im Trustee. Damit ist das Muster end-to-end belegt — demonstrierbar am SelectLine→RMA- **und** am Pling-Fall. +- **Verhältnis zu den anderen Plänen:** Der Umsystem-/Datenquellen-Plan liefert **L1-Connectors**; dieser Plan liefert **L3/L4**. Lawyer ist ein **Feature**, das L1–L4 konsumiert. Drei Pläne, eine Architektur. + +## Links + +- Beispiel Reporting/Fan-out (Pling): `pamocreate/projects/poweron/customer-pling/20-spezifikation/20260522-workflow-spec-kaffee-klatsch.md` (+ `-anhang.md`) +- Umsetzungsplan Solutions (alle konfigurierten Use Cases): `c-work/0-ideas/2026-06-CustomerCases-step3-solutions-plan.md` +- Umsetzungsplan Features & Bausteine (der Code dahinter): `c-work/0-ideas/2026-06-CustomerCases-step3-features-plan.md` +- Kommunikation: Product Summary `c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.md` (+ `.pdf`), Mockup `c-work/0-ideas/2026-06-CustomerCases-step2-communication-mockup.html` +- Bausteine: `b-reference/platform-core/workflow.md`, `b-reference/platform-core/automation.md` +- Datenquellen-Trennung: `b-reference/platform/unified-data-bar.md` + +## Abschluss + +- [x] Offene Fragen beantwortet (Entscheid 2026-06-04); Detail Output-Bindung beim Bauen +- [ ] Bei Annahme → Plan-Dokument in `c-work/1-plan/` (erster Schnitt, Trustee) +- [ ] `b-reference/` Kanon-Seite «Solutions / Customer Workflows» nach Umsetzung +- [ ] `TOPICS.md` Eintrag diff --git a/c-work/0-ideas/2026-06-CustomerCases-step2-communication-mockup.html b/c-work/0-ideas/2026-06-CustomerCases-step2-communication-mockup.html new file mode 100644 index 0000000..08bf59b --- /dev/null +++ b/c-work/0-ideas/2026-06-CustomerCases-step2-communication-mockup.html @@ -0,0 +1,762 @@ + + + + + +PORTA · Lösungen (Solution-Schicht Mockup) + + + + + +
+ + + + +
+
+
Trustee · Lösungen
+
Kaffee-Klatsch Holding·◑ Hell
+
+
+
+ + +
+
+
+

Lösungen

+

Wiederkehrende Aufgaben als konfigurierte Workflows — einmal einstellen, automatisch laufen lassen, Ergebnisse ansehen. Kein Code nötig.

+
+ +
+ +
+ +
+ + + +
+
+ +
+
+ + + + +
+
+
+
+ + +
+ +
+ +
Gespeichert
+ + + + diff --git a/c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.md b/c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.md new file mode 100644 index 0000000..7b6ef58 --- /dev/null +++ b/c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.md @@ -0,0 +1,82 @@ + + + + +# Solution-Schicht — Product Summary + +> **In einem Satz:** Wir verpacken den vorhandenen Workflow-Stack in eine **Solution-Schicht**, mit der ein Business-Kunde seine wiederkehrenden Aufgaben selbst **anlegt, einstellt, testet, startet und ansieht** — ohne Code pro Kunde. +> +> Volldokument: `2026-06-CustomerCases-step1-architecture.md` · Mockup: `2026-06-CustomerCases-step2-communication-mockup.html` · Umsetzung: `2026-06-CustomerCases-step3-solutions-plan.md` / `-step3-features-plan.md` + +## Die Idee dahinter + +**Klassische Software ist von gestern.** Statt pro Problem eine Applikation zu *schreiben*, **konfigurieren** wir komplexe Use Cases aus vorhandenen Bausteinen — genau das, was eine AI heute schon tut, wenn sie assistiert: Absicht beschreiben → System komponiert das Ergebnis. + +Die Solution-Schicht **produktisiert** das: Der Kunde beschreibt seinen Use Case, der Workflow-Agent komponiert den Graph, das Ergebnis läuft **dauerhaft, geplant und governt**. Massgeschneidert ohne Massanzug-Kosten, Tage statt Monate, Self-Service statt Vendor-Backlog. **Grenzkosten eines neuen Use Cases → fast null.** + +Ehrlich zu Ende gedacht: Es verschwindet nicht *alle* Software — die **Bausteine** und einige **tiefe Features** bleiben Code. Aber die vielen massgeschneiderten Einzellösungen, die man bisher pro Kunde gebaut hat, werden zu **Konfiguration**. Genau das ist «konfigurieren statt coden» — der Hebel, der Kunden aufs nächste Level bringt. + +## Das SaaS-Asset: Solution vs. Feature + +PORTA hat heute zwei Enden: den technischen **Workflow-Editor** und das **Ops-Dashboard**. Es fehlt die **Mitte** — die kundentaugliche Schicht. Genau das ist das Produkt-Asset: + +- **Solution = konfigurierter Workflow (Daten).** Aus Bausteinen komponiert, vom Kunden per Settings eingestellt. Time-to-value: **Tage**. Skaliert **ohne** Engineering pro Kunde. +- **Feature = Code.** Eigene Datenmodelle + tiefe, eigene UI (z. B. `lawyer`). Time-to-value: **Wochen**. Nur wo nötig. + +**Leitsatz: Solution-first.** Ein Feature bauen wir nur, wenn die Solution-Schicht es nachweislich nicht trägt. So wird «konfigurieren statt coden» der Default — und das macht aus «wir bauen pro Kunde» ein skalierendes SaaS. + +| | Solution (Daten) | Feature (Code) | +|---|---|---| +| Datenmodell | nutzt bestehende | eigenes | +| UI | generische «Lösungen»-Seite | eigene, opinionated | +| Erstellung | Settings + Graph | Engineering | +| Beispiele | Pling-Reporting, SelectLine→RMA, PWG | lawyer, commcoach, trustee | + +## Die vier Schichten + +| | Schicht | Inhalt | Status | +|---|---|---|---| +| **L4** | Solution Surface | Kundentaugliche UX: «Lösungen»-Seite (Liste · Katalog/AI · Detail mit Tabs) | **NEU** | +| **L3** | Solution Definition | Use Case → konfigurierter Workflow: Settings-Schema + Werte + Trigger + Output | **NEU** | +| **L2** | Composition | Graph: AutoWorkflow/Version/Run, Editor, Templates | vorhanden | +| **L1** | Plattform-Toolbox | Connectors, Actions/Nodes, AI, Neutralisierung, Scheduler, RBAC | vorhanden | + +→ **Unsere Arbeit liegt in L3 + L4.** L1/L2 nutzen wir unverändert. + +## Grundlage: die Kunden-Cases + +Wir bauen aus realen Cases, nicht aus einer Idee. Sie sind die **Akzeptanzkriterien**: trägt der Entwurf den Fall, ist er richtig. + +| Case | Bedürfnis | Settings (= Kundenspezifika, Daten) | Output | +|---|---|---|---| +| **Pling** (Leit-Case) | 5 Buchhaltungen → 6 PDFs, rollenbasiert mailen, monatlich | 5 Instanzen, Konten-Ranges, Cron, Empfänger-Rollen | 6 PDFs + Mails | +| **SelectLine→RMA** | Rechnungen täglich ins RMA buchen | Quelle/Ziel, Mapping | Sync-Log | +| **PWG** | Mietzins-Belege verarbeiten + Antwort | Ordner, Mandant, Empfänger | Tabelle + Mail | +| **Lawyer** | Mandatsvorbereitung + Dashboards | — | = **Feature**, nicht Solution | + +Was die Cases erzwingen: **Multi-Instanz-Fan-out** (Pling: 1 Solution über 5 Instanzen) und zwei **generische** Bausteine (`rbac.queryUsersByRole`, Trigger-`accessControl`) — wiederverwendbar, kein Kunden-Code. + +## L3 — Datenmodell (kurz) + +Solution = **dünne Erweiterung von `AutoWorkflow`** + Settings-Record (keine Parallel-Welt → Scheduler/Runs/Versioning greifen unverändert). Felder: + +`workflowRef` · `settingsSchema` (auto aus `trigger.form`/exposed Params) · `settingsValues` (inkl. **Instanz-Set**) · `triggerPolicy` (+ `accessControl.requiredRoles`) · `outputBinding` (`file | table | summary`) · `customerFacing`. + +## L4 — UI (kurz) + +**Eine** «Lösungen»-Seite pro Feature (Start: Trustee) — kein Seiten-Wildwuchs: + +- **Liste** (aktiv/inaktiv, letzter/nächster Lauf) +- **Katalog/Neu** (Vorlage wählen oder per AI beschreiben) +- **Detail** mit Tabs: **Einstellungen · Testlauf · Läufe · Ausgabe** + +Settings-Formular wird aus dem `settingsSchema` gerendert (FrontendType). «Im Editor öffnen» bleibt die Escape-Hatch nach L2. + +## Bauen — erster Schnitt + +1. `AutoWorkflow` um `settingsSchema` + `customerFacing` + Instanz-Set erweitern (+ Settings-Record, Migration). +2. 2 System-Templates: «Systeme synchronisieren» (SelectLine→RMA) + «Periodisches Reporting» (Pling). +3. Generische `SolutionsView` im Trustee: Liste + Settings + Testlauf + Aktivieren + Läufe. +4. Generische Bausteine: `rbac.queryUsersByRole`, Trigger-`accessControl`, run-level `testMode` (Kommunikation im Testlauf unterdrücken). + +→ End-to-end belegt an **SelectLine→RMA** und **Pling**. diff --git a/c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.pdf b/c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..390448daa73234e033262d61101b6af587c866a1 GIT binary patch literal 35458 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 TQq#DMO$|+qxKveL{oS|#4Z2+$ literal 0 HcmV?d00001 diff --git a/c-work/0-ideas/2026-06-CustomerCases-step3-features-plan.md b/c-work/0-ideas/2026-06-CustomerCases-step3-features-plan.md new file mode 100644 index 0000000..ed81a14 --- /dev/null +++ b/c-work/0-ideas/2026-06-CustomerCases-step3-features-plan.md @@ -0,0 +1,191 @@ + + + + + +# Plan: Features & Plattform-Bausteine — der Code hinter den Solutions + +> **Baut auf:** `2026-06-CustomerCases-step1-architecture.md` (Schichten L1–L4, Feature-vs-Solution-Grenze). +> **Schwester-Plan:** `2026-06-CustomerCases-step3-solutions-plan.md` (die konfigurierten Use Cases, die diesen Code konsumieren). +> **Konsolidiert/ersetzt:** Lawyer-Feature-Plan + die Code-/Plattform-Teile aus Umsystem-Integration und konsolidiertem Kundenwünsche-Plan. + +## Beschreibung und Kontext + +Ein **Feature** ist **Code**: eigenes Datenmodell und/oder tiefe, opinionated UI / Domänenlogik, die ein Graph nicht ausdrücken kann (step1-architecture, Entscheidungsmatrix). Dazu zählen auch die **Plattform-Bausteine**, die die Solutions erst möglich machen — sie sind generischer Code (L1/L2/L3/L4), **ohne Kundennamen**. + +Dieser Plan bündelt allen **Code**, der zu bauen ist, in zwei Teilen: + +- **Teil A — Plattform-Enabler:** die Solution-Schicht selbst (L3/L4), generische Workflow-Bausteine, Connectors, das «Datenquelle = Seite»-Muster. Voraussetzung für *alle* Solutions. +- **Teil B — Vertikale Code-Features:** Module mit eigenem Datenmodell/UI (`lawyer`), bestehende Features (`commcoach`, `trustee`, `neutralization`) und ihre Erweiterungen. + +**Leitsatz (step1-architecture):** Solution-first. Code bauen wir nur, wenn (a) es ein generischer Baustein ist, den viele Solutions teilen, oder (b) der Use Case nachweislich nicht als Solution trägt. + +## Fokus und kritische Details + +- **Generisch, nie kundenspezifisch.** Connectors = reine API-Adapter (Auth + Lesen/Schreiben + Mapping auf kanonische Modelle), keine Geschäftsregeln, keine Kundennamen. Kundenlogik lebt als Solution (Daten). +- **Eine Workflow-Wahrheit.** Die Solution-Schicht ist eine **dünne Erweiterung von `AutoWorkflow`** + Settings-Record, keine Parallel-Welt → Scheduler/Runs/Versioning unverändert. +- **Source vs. Target** ist die wichtigste neue Connector-Achse (macht aus dem Push-Framework ein bidirektionales Integrations-Framework). +- **RBAC strikt feature-instance-scoped**, nicht mit Mandate-Rollen vermischen (`.cursor/rules/rbac-role-separation.mdc`). +- **Neutralisierung + Private LLM** zwingend für jeden LLM-Pfad mit Personendaten (Trustee, Lawyer/Berufsgeheimnis StGB 321). +- **YAGNI bei Connector-Abstraktion:** beim bestehenden `BaseAccountingConnector` bleiben und nur die **Source-Rolle** ergänzen; das generische «Capability-Mixin»-Framework erst ziehen, wenn die zweite Kategorie (Saläre) real wird. + +## Teil A — Plattform-Enabler (macht Solutions möglich) + +### A1 — Solution-Schicht (L3/L4) + +- **`AutoWorkflow` erweitern** um `settingsSchema`, `outputBinding`, `customerFacing`-Flag, **Instanz-Set** (Multi-Instanz-Fan-out). **DB-Migration: ja (Greenfield, additiv).** +- **Settings-Record-Modell** (`settingsValues` pro Solution/Instanz; Secrets verschlüsselt wie Connector-Configs). +- **`settingsSchema` automatisch ableiten** aus `trigger.form` + als «exposed» markierten Node-Params (kuratierte Overrides später). +- **Solution-Routes** (dünn über bestehende Editor-/Run-Routes): CRUD Settings, Test-Run, Activate/Deactivate. +- **`SolutionsView`** (ui-nyla): generische «Lösungen»-Seite pro Feature — Liste · Katalog/Neu · Detail mit Tabs (Einstellungen · Testlauf · Läufe · Ausgabe). Settings-Formular aus `settingsSchema` (FrontendType-getrieben). Registriert wie andere Views (`FeatureView.tsx` + UI-Areas in `main.py`). +- **Use-Case-Katalog** als System-Templates (`interfaces/interfaceBootstrap.py`). +- **AI: Use Case → Workflow** über bestehenden Workflow-Agent (Toolbox `workflow`), Draft + Review vor Aktivierung. +- **Output-Renderer** für `outputBinding.kind` = `file` (Datenraum/`TrusteeDocument`), `table` (FormGenerator/Data-Tables), `summary` (`AutoRun`/`AutoStepLog`). `dashboard` später (AI-Report/Canvas-Pipeline). + +### A2 — Generische Workflow-Bausteine (Nodes/Actions) + +| Baustein | Zweck | Status | +|---|---|---| +| `rbac.queryUsersByRole` | rollenbasierte Empfänger-Auflösung (Verteiler aus Feature-Rollen statt Listen) | **neu** | +| Trigger-`accessControl.requiredRoles` (in `triggerExecutor`) | nur erlaubte Rolle darf manuell auslösen | **neu** | +| run-level `testMode` | Testlauf real, Kommunikations-/Seiteneffekt-Nodes (Mail/Outlook/Teams/Webhook) unterdrücken Versand (loggen «würde senden …») | **neu** | +| `integration.fetchFromSource` / `integration.mapAccounts` / `integration.pushToTarget` | system-agnostischer Source→Target-Import (Quelle/Ziel = Config) | **neu** | +| `data.consolidate` (sumByKey) | Aggregation mehrerer Instanzen (Pling Holding-Konsolidierung) | prüfen/ggf. neu | +| `data.writeToTable` / Tabellen-Output | Ergebnistabellen (PWG-Übersicht) | prüfen/ggf. neu | +| `trigger.event` / DB-Change-Detection | ereignisgetriggerte Solutions (Notification) | **neu (Roadmap)** | + +Alle erscheinen über den Editor-Adapter (`graphicalEditor/nodeDefinitions/`) als Bausteine. + +### A3 — Connectors (L1, generische API-Adapter) + +- **SelectLine-Connector** (Quelle): `accountingConnectorSelectline.py`, implementiert `BaseAccountingConnector`, Auto-Discovery via `accountingRegistry.py`. Methoden: `testConnection`, `getChartOfAccounts`, `getCustomers`/`getVendors`, Lese-Seite für Belege (`getOutgoingInvoices`, Default `[]` in Base). Config: `baseUrl`, `username`, `password` (secret), optional `mandant`. +- **`TrusteeAccountingConfig.role`** (`source` | `target`) → mehrere Connector-Configs pro Instanz (eine Quelle + ein Ziel); `getActiveConfig`/`_resolveConnectorAndConfig` um `role` filtern. Optional `connectorCategory` (`accounting` | `payroll` | `invoicing`). **DB-Migration: ja.** +- **Kanonisches `Invoice`-Modell** prüfen/ergänzen (falls RMA als AR-Rechnung statt GL-Buchung). +- **Source-Pfad in `accountingBridge.py`** additiv (Push-Pfad unverändert). +- **Roadmap-Connectors** (generisch, je 1 Datei + Config): Xero (1.1.11), FileMaker (PWG 1.9.10), Kassensystem/Gastro (1.6, wartet auf Input), Lohn/Swissdec (4.2), Bank-Statement-Import (4.1.2). Je neuer Connector schaltet neue Solutions frei, ohne Architekturänderung. + +### A4 — «Datenquelle = Seite» (generische Connector-UI) + +- `TrusteeAccountingSettingsView` → generische **`IntegrationSettingsView`** (`category`-Prop): Verbindungen (Connector + Rolle Quelle/Ziel + Credentials + Test), Datenfluss/Import, Daten-Spiegel. +- Neue UI-Areas in `mainTrustee.py` (z. B. `ui.feature.trustee.payroll`) + Mapping in `FeatureView.tsx` → **gleiche** Komponente, andere `category`. +- «Buchhaltungssystem» existiert; «Saläre»/«Fakturierung» als Folge-Kategorien (Platzhalter, nicht erste Umsetzung). + +## Teil B — Vertikale Code-Features + +### B1 — `lawyer` (Mandatsvorbereitung + Dashboards) — NEU + +Echtes Feature (eigene Modelle + opinionated UI), das die Plattform-Bausteine bündelt; **konsumiert** die Solution-Schicht (Matter-Prep/Dashboard-Refresh als interne Solutions/Actions). + +- **Datenmodell** (`datamodelLawyer.py`): `LawyerMatter`, `LawyerPreparation`, `LawyerDashboardSnapshot`, `LawyerKpi`, `LawyerSourceMap`. **Migration: ja.** +- **Feature-Modul** `mainLawyer.py` + Template-Rollen `lawyer-admin` / `lawyer-user` / `lawyer-viewer` (feature-instance-scoped). +- **Actions** (`methodLawyer/`): `lawyer.prepareMatter`, `lawyer.refreshDashboard`, `lawyer.queryData`. +- **UI** (`ui-nyla/src/components/Lawyer/`): Dashboard-View (Tabs HR/Business/IT/Finance) + Matter-Preparation-View (opinionated, analog Workspace). +- **Connectors:** DMS (SharePoint vorhanden, iManage neu?), E-Mail (Outlook/Exchange), KYC/AML, Konflikt-Check — als generische L1-Bausteine (Teil A3-Muster). +- **Neutralisierung zwingend** (Berufsgeheimnis); Sprache UI primär Englisch (WW/Investor). +- **Demo-Asset:** synthetic Matter `M-DEMO-001` für WW-Präsentation (statisches Briefing-JSON, Backend-frei). + +> Begründung Feature statt Solution: eigene Datenmodelle (`LawyerMatter`…), tiefe opinionated UI (Matter-Preparation), Domänenlogik. Dashboards/Matter-Prep dürfen intern Solutions/Actions nutzen — das Feature ist der opinionated Rahmen. + +### B2 — `commcoach` (bestehend) + +- Feature komplett (10+ Personas inkl. 4 PWG-Immobilien-Personas, Gamification, Seeding). **Erweiterungen:** kundenspezifische Persona-Sets als Daten (z. B. PWG-Knowledge-Set). Kein Neubau. + +### B3 — `trustee` (Core, bestehend) — Erweiterungen + +- Engine + Accounting-Bridge + Pipeline (`extractFromFiles`/`processDocuments`/`syncToAccounting`) + Connectors (RMA/Bexio/Abacus) bestehen. +- **Erweiterungen als Bausteine** (nicht als Kundenlogik): Firmen-/Lieferanten-Mapping-UI (1.1.4), Buchungsregeln-Engine (1.1.6), Vorsteuer-Automatik (1.1.7), Bank-Statement-Matching (4.1). +- **Migration:** Analyse-Prompt-Templates (Budget/KPI/Cashflow/Prognose/Jahresabschluss) aus `mainTrustee.py` → kuratierte **Solution-Templates** (→ solutions-plan S5). Trustee bleibt Daten-/Connector-Heimat, die Analysen werden Solutions. + +### B4 — Plattform-Features (bestehend, Querschnitt) + +- `neutralization` (PII-Masking, Private-LLM, Compliance-Audit) — vorhanden; pro Solution/Feature nur konfigurieren. +- Knowledge/RAG, Billing, Multi-Tenancy, Workspace — vorhanden. +- **UI/UX-Härtung** (aus altem Kundenplan Teil 2, plattformweit, nicht Solution/Feature-spezifisch): Empty-State, DE-Placeholder/i18n, Zwischen-Breakpoint 1025–1280px, Trust-Strip, Billing-Discovery, Connector-Onboarding-Copy. → separate UX-Charge, hier nur referenziert. + +## Feature-vs-Solution — Recap (Entscheidungsmatrix) + +| Kriterium | → Solution (Daten) | → Feature (Code) | +|---|---|---| +| Eigenes Datenmodell? | nein | ja (`LawyerMatter`) | +| Tiefe opinionated UI? | nein | ja (Matter-Preparation) | +| Aus Bausteinen komponierbar? | ja | nein (Domänenlogik) | +| Beispiel | SelectLine→RMA, Pling, PWG, Analysen | `lawyer`, `commcoach`, `trustee`-Core | + +## Betroffene Module + +- **Gateway (platform-core):** + - `features/graphicalEditor/` — `AutoWorkflow`-Erweiterung + Settings-Record + Solution-Routes (A1). **Migration: ja.** + - `workflows/methods/` + `graphicalEditor/nodeDefinitions/` — generische Nodes (A2). + - `workflows/.../triggerExecutor` — `accessControl.requiredRoles` + `testMode` (A2). + - `features/trustee/accounting/connectors/accountingConnectorSelectline.py` (neu), `accountingConnectorBase.py` (Source-Methode), `accountingBridge.py` (Source-Pfad), `datamodelFeatureTrustee.py` (`role` [+ `connectorCategory`]) — **Migration: ja** (A3). + - `features/lawyer/` (neu, B1) — `mainLawyer.py`, `datamodelLawyer.py`, `methodLawyer/`, Routes. **Migration: ja.** + - `interfaces/interfaceBootstrap.py` — Use-Case-Katalog/System-Templates (A1). + - `serviceCenter/services/serviceAgent/` (Toolbox `workflow`) — Use-Case→Graph (A1). +- **Frontend (ui-nyla):** + - `SolutionsView` (A1), `IntegrationSettingsView` (A4), `Lawyer/`-Komponenten (B1), `FeatureView.tsx`-Registry + UI-Areas. +- **DB-Migration:** ja (Solution-Schicht, `TrusteeAccountingConfig.role`, Lawyer-Modelle). +- **Andere:** RBAC (neue UI-Areas, bestehende Feature-Rollen), Neutralisierung, Billing (Run-/Sync-Volumen). + +## Entscheidungen + +| Datum | Entscheidung | Begründung | +|-------|-------------|------------| +| 2026-06-04 | Plattform-Bausteine + Solution-Schicht als **generischer Code**, nie kundenspezifisch | macht alle Solutions möglich, hält «kein Kunden-Code» real | +| 2026-06-04 | Connectors = reine Adapter; `source`/`target`-Rolle als neue Achse | bidirektionales Integrations-Framework, additive Erweiterung | +| 2026-06-04 | `lawyer` bleibt **Feature** (eigene Modelle + opinionated UI), nutzt Solution-Schicht intern | Entscheidungsmatrix; Domänenlogik nicht als Graph abbildbar | +| 2026-06-04 | Trustee-Analyse-Prompt-Templates → **Solution-Templates** migrieren | kundentauglich machen; Trustee bleibt Daten-/Connector-Heimat | +| 2026-06-04 | Connector-Abstraktion erst bei zweiter Kategorie (Saläre) generalisieren | YAGNI | + +## Umsetzungs-Checkliste + +**Teil A (Enabler, zuerst):** +- [ ] `AutoWorkflow`-Erweiterung (`settingsSchema`/`outputBinding`/`customerFacing`/Instanz-Set) + Settings-Record + Migration +- [ ] Solution-Routes (CRUD/Test/Activate) + `SolutionsView` + Settings-Formular-Renderer +- [ ] Output-Renderer `file`/`table`/`summary` +- [ ] `rbac.queryUsersByRole`, Trigger-`accessControl`, run-level `testMode` +- [ ] Integration-Nodes `fetchFromSource`/`mapAccounts`/`pushToTarget` + Editor-Adapter +- [ ] `data.consolidate` / `data.writeToTable` prüfen/ergänzen +- [ ] SelectLine-Connector + `TrusteeAccountingConfig.role` (+ optional `connectorCategory`) + Migration +- [ ] kanonisches `Invoice`-Modell prüfen; Source-Pfad in `accountingBridge` (additiv) +- [ ] `IntegrationSettingsView` (`category`) generalisieren +- [ ] Use-Case-Katalog/System-Templates + Workflow-Agent-Pfad + +**Teil B (Features):** +- [ ] `lawyer`: Datenmodell (5 Modelle) + `mainLawyer.py` + 3 Actions + UI (Dashboard/Matter-Prep) + RBAC + Neutralisierung + Demo-Asset +- [ ] `trustee`: Analyse-Templates → Solution-Templates; optional Mapping-UI/Buchungsregeln/Vorsteuer/Bank-Matching +- [ ] `commcoach`: kundenspezifische Persona-/Knowledge-Sets als Daten +- [ ] Roadmap-Connectors nach Bedarf (Xero, FileMaker, Lohn, Kassensystem, Bank-Import) + +## Akzeptanzkriterien + +| # | Kriterium (Given-When-Then) | Prio | +|---|---|---| +| 1 | Given ein neues Umsystem, When ein Connector-File + Config ergänzt wird, Then ohne Änderung an Registry/Bridge/Editor verfügbar | must | +| 2 | Given `testMode`, When eine Solution testweise läuft, Then erzeugt sie Artefakte, sendet aber keine Kommunikation | must | +| 3 | Given `rbac.queryUsersByRole`, When mit Rollen-Set aufgerufen, Then dedupliziert die korrekten Empfänger (Pling-Verteiler) | must | +| 4 | Given Anwalt mit `lawyer-user`, When Matter-Preparation getriggert, Then strukturiertes Briefing in <90s, PII vor LLM neutralisiert | must | +| 5 | Given Mandate-Rolle ohne `lawyer-*`, When Lawyer-Feature geöffnet, Then Access Denied | must | +| 6 | Given Solution-Schicht, When ein Kunde Settings ändert, Then ohne Code-Deploy wirksam | must | + +## Offene Fragen + +1. **Solution-Daten-Heimat:** `AutoWorkflow`-Erweiterung (empfohlen) — Settings-Record als eigenes Modell oder JSON-Feld? +2. **`outputBinding`-Schema:** Artefakt-Referenz (Run-Output-Key vs. Document-Query); `table`-Spalten aus Node-Output ableiten? +3. **SelectLine:** on-prem-Erreichbarkeit (VPN/Tunnel/Agent); Zielart RMA (AR vs. GL). +4. **Lawyer-Connectors:** iManage/KYC/Konflikt-Check-APIs — welche mandantenspezifisch, welche generisch? +5. **Connector-Generalisierung:** wann Capability-Mixins (`AccountingCapable`/`PayrollCapable`) ziehen? + +## Links + +- Architektur: `c-work/0-ideas/2026-06-CustomerCases-step1-architecture.md` +- Solutions: `c-work/0-ideas/2026-06-CustomerCases-step3-solutions-plan.md` +- Bausteine: `b-reference/platform-core/workflow.md`, `b-reference/platform-core/automation.md`, `b-reference/platform-core/features/trustee.md` +- RBAC/Neutralisierung: `b-reference/platform/rbac.md`, `b-reference/platform/neutralization.md`, `.cursor/rules/rbac-role-separation.mdc` +- Lawyer-Kontext (WW): `pamocreate/projects/poweron/customer-walderwyss/` +- Code: `platform-core/modules/features/trustee/accounting/` (Bridge/Base/Registry/Connectors), `features/graphicalEditor/` + +## Abschluss + +- [ ] Bei Annahme → Build in `c-work/2-build/` (Teil A vor Teil B) +- [ ] `b-reference/` Kanon-Seiten: «Solutions / Customer Workflows», `features/lawyer.md`, Trustee «Source-Connectors» +- [ ] `TOPICS.md` + `_CHANGELOG.md` pro Phase diff --git a/c-work/0-ideas/2026-06-CustomerCases-step3-solutions-plan.md b/c-work/0-ideas/2026-06-CustomerCases-step3-solutions-plan.md new file mode 100644 index 0000000..843d7a4 --- /dev/null +++ b/c-work/0-ideas/2026-06-CustomerCases-step3-solutions-plan.md @@ -0,0 +1,199 @@ + + + + + +# Plan: Solutions — kundeneigene Workflows als Konfiguration (kein Code) + +> **Baut auf:** `2026-06-CustomerCases-step1-architecture.md` (Schichten L1–L4, Feature-vs-Solution-Grenze). +> **Schwester-Plan:** `2026-06-CustomerCases-step3-features-plan.md` (der Code dahinter: Solution-Schicht, generische Bausteine, Connectors, vertikale Features). +> **Konsolidiert/ersetzt:** Umsystem-Integration-Plan + die Solution-tauglichen Use Cases aus dem konsolidierten Kundenwünsche-Plan. + +## Beschreibung und Kontext + +Eine **Solution** ist ein **konfigurierter Workflow** (Daten = Graph + Settings + Trigger + Output-Bindung), der ein wiederkehrendes Kundenbedürfnis erfüllt — **ohne kundenspezifischen Code**. Sie konsumiert die vorhandenen Plattform-Bausteine (L1 Toolbox, L2 Graph) und wird über die neue Solution-Schicht (L3/L4) angelegt, eingestellt, getestet, ausgeführt und angesehen. + +Dieser Plan listet die **konkreten Kunden-Use-Cases, die als Solutions** umgesetzt werden. Der Code, den diese Solutions voraussetzen (Solution-Schicht selbst, generische Workflow-Bausteine, Connectors), steht im **features-plan** — eine Solution schreibt nie eigenen Code. + +Business-Treiber: jeder Use Case wird zu Konfiguration statt Engineering → Time-to-value in Tagen, Onboarding ohne Entwicklungs-Backlog, Grenzkosten pro Use Case nahe null. + +## Fokus und kritische Details + +- **Solution = Daten, nie Code.** Konten-Mappings, Empfänger, Perioden, Ordnerpfade, Cron-Zeiten, Instanz-Auswahl = **Settings**. Tauchen Kundennamen oder `if kunde == X` im Code auf, ist die Solution falsch geschnitten. +- **Multi-Instanz-Fan-out.** Eine Solution kann über ein **Set von Feature-Instanzen** laufen (Pling: 5 Stores). Das Settings-Modell trägt eine Instanz-Auswahl. +- **Voraussetzung sind generische Bausteine, keine kundenspezifischen.** Wo ein Baustein fehlt (z. B. `rbac.queryUsersByRole`, ein SelectLine-Connector), wird er **generisch** im features-plan gebaut und hier nur referenziert. +- **Neutralisierung** für jeden LLM-Pfad (Belege/Berichte mit Personendaten) — über das bestehende Gate, selektiv (Namen/Beschreibungen pseudonymisiert, Zahlen/Konten lesbar). +- **Testlauf real, ohne Versand:** Solutions laufen im Test echt, nur Kommunikation wird via run-level `testMode` unterdrückt. + +## Ziel und Nicht-Ziele + +- **Ziel:** Die häufigsten Kundenbedürfnisse als **kuratierte Solution-Templates** + pro Mandant/Instanz konfigurierte Solutions abbilden. +- **Ziel:** SelectLine→RMA und Pling-Reporting als erste produktive Solutions (Leit-Cases). +- **Ziel:** Nachweis, dass dasselbe Muster Beleg-Import, Dokumentenverarbeitung und Finanz-Analysen trägt. +- **Explizit NICHT:** kundenspezifischer Code pro Solution (→ features-plan baut nur Generisches). +- **Explizit NICHT:** den Graphical Editor ersetzen — Solutions kapseln ihn; «Im Editor öffnen» bleibt Escape-Hatch. +- **Explizit NICHT:** Use Cases, die ein eigenes Datenmodell / tiefe opinionated UI brauchen (→ das sind **Features**, siehe features-plan; z. B. `lawyer`). + +## Klassifikation: was wird Solution, was Feature + +| Use-Case-Quelle | Umsetzung | Begründung | +|---|---|---| +| SelectLine → RMA (Umsystem) | **Solution** «Systeme synchronisieren» | Komponierbar aus Connectors + Integration-Nodes; Kundenspezifika = Mapping/Settings | +| Pling Kaffee-Klatsch (Monatsreporting) | **Solution** «Periodisches Reporting» | Fan-out + Konsolidierung + AI-Report + rollenbasierte Verteilung, alles Bausteine | +| PWG Jahresmietzinsbestätigungen (1.9c) | **Solution** «Dokumente verarbeiten» | SharePoint→Extract→AI→Tabelle→Mail, 1 AI-Schritt | +| Beleg-/Spesen-Import periodisch (1.1, 1.10.5) | **Solution** «Beleg-Import» | SharePoint/Drive→Trustee-Pipeline, Zeitplan | +| Budget/Soll-Ist, KPI, Cashflow, Prognose, Jahresabschluss-Check, Liquidität (1.2–1.7, 4.x) | **Solution** «Finanz-Analyse & Reporting» | `queryData`→`ai.generate`→Output (Tabelle/Report); heute Prompt-Templates | +| KPI-/Notification-Verteilung (1.9.12, 4.5.8) | **Solution** «Benachrichtigung/Report» | Trigger→Daten→Report→rollenbasierte Verteilung | +| Lawyer (Mandatsvorbereitung + Dashboards) | **Feature** | Eigene Modelle (`LawyerMatter`…) + opinionated UI | +| CommCoach, Neutralisierung, Trustee-Core | **Feature** (bestehend) | Domänenlogik/eigene UI/Engine | +| Connectors (SelectLine, Xero, FileMaker, Lohn, Kassensystem) | **Feature/Plattform-Baustein** | Generischer Code (L1), kein Kunden-Code → features-plan | +| Solution-Schicht, generische Nodes, `testMode` | **Feature/Plattform-Enabler** | Code, der Solutions erst möglich macht → features-plan | + +## Solution-Katalog + +Jede Solution = Template (kuratiert) → pro Instanz konfiguriert. Bausteine sind **vorhanden**, sofern nicht als «(neu → features-plan)» markiert. + +### S1 — «Systeme synchronisieren» (Pilot: SelectLine → RMA) + +| | | +|---|---| +| **Bedürfnis** | Rechnungen aus externem System (SelectLine) periodisch ins RMA buchen | +| **Trigger** | `trigger.schedule` (z. B. täglich 06:00) oder `trigger.manual` | +| **Bausteine (Graph)** | `integration.fetchFromSource` (SelectLine) → `integration.mapAccounts` → `integration.pushToTarget` (RMA, inkl. Beleg-Upload) *(Nodes + SelectLine-Connector neu → features-plan)* | +| **Settings (L3)** | Quell-Connector + Credentials, Ziel-Connector, Konten-/Steuer-Mapping, Filter (nur Ausgangsrechnungen, «seit letztem Sync»), Zeitplan | +| **Output (L4)** | `summary` — Sync-Log/Status (gebucht/übersprungen/Duplikate) | +| **Dedup** | über bestehende AccountingBridge-Dedup-Logik | +| **Kunden** | konkreter SelectLine-Kunde; Muster für jedes weitere Umsystem | +| **Voraussetzungen (features-plan)** | SelectLine-Connector, `source`/`target`-Rolle auf Config, Integration-Nodes, ggf. kanonisches `Invoice`-Modell | + +Zwei Kunden mit unterschiedlichem Kontenplan-Mapping = **zwei Solutions/Configs, ein Code**. + +### S2 — «Periodisches Reporting» (Leit-Case: Pling Kaffee-Klatsch) + +| | | +|---|---| +| **Bedürfnis** | Am 15./Monat aus 5 RMA-Buchhaltungen konsolidieren, 6 PDFs erzeugen, rollenbasiert mailen | +| **Trigger** | `trigger.schedule` `0 6 15 * *` (Europe/Zurich) + `trigger.manual` (rollen-beschränkt) | +| **Bausteine (Graph)** | `flow.loop`(5 Instanzen) → `trustee.refreshAccountingData` → `trustee.queryData` (Salden akt.+Vorjahr) → `data.consolidate` (sumByKey) → `ai.generateDocument`×6 (1 Holding + 5 Store) → `rbac.queryUsersByRole` → `outlook.send` → `file.create` (Archiv) | +| **Settings (L3)** | **Instanz-Set** (5 Stores), Konten-Ranges (Umsatz 3000–3999, Warenkosten 6000–6299, Personal 5000–5099), Cron, Empfänger-**Rollen** (Holding→`trustee-accountant`/`trustee-viewer`, Store→`trustee-client`, Protokoll→`trustee-admin`), `stopOnIncomplete` | +| **Output (L4)** | `file` — 6 PDFs, archiviert als `TrusteeDocument`; + `summary` Lauf-Protokoll | +| **Sonderfall** | Buchhaltung am 15. nicht abgeschlossen → durchlaufen mit Markierung (Conditional nach refresh), steuerbar via `stopOnIncomplete` | +| **Neutralisierung** | selektiv (Namen/Beschreibungen ja; Zahlen/Konten nein) | +| **Voraussetzungen (features-plan)** | `rbac.queryUsersByRole`, Trigger-`accessControl.requiredRoles`, `data.consolidate` (prüfen), `testMode` | + +Vollständig spezifiziert (High-Level + Anhang); ~2 Wochen Build → bester End-to-End-Beleg der Solution-Schicht. + +### S3 — «Dokumente verarbeiten + Antwort» (PWG Jahresmietzinsbestätigungen, 1.9c) + +| | | +|---|---| +| **Bedürfnis** | Gescannte Rücklauf-Bestätigungen (≈3'200/Jahr) prüfen, Status klassifizieren, Antwortvorschläge | +| **Trigger** | `trigger.schedule` (täglich) oder `trigger.manual` | +| **Bausteine (Graph)** | `sharepoint.listFiles` → `flow.loop` → `sharepoint.downloadFile` + `trustee.extractFromFiles` (OCR) → `ai.prompt` (Scan vs. Abacus-Originaldaten, Status, Antwortvorschlag) → `data.writeToTable` → `email.send` | +| **Settings (L3)** | Scan-Ordner (SharePoint), Abacus-Mandant + Mietzins-Stammdaten-Abfrage, Empfänger (Sachbearbeiter), Prompt-Variante | +| **Output (L4)** | `table` — Übersicht verarbeiteter Bestätigungen (bestätigt / Abweichung / fehlende Unterschrift / unleserlich) + Mail-Zusammenfassung | +| **Kunden** | PWG (Pilot, Versand Sommer 2026, Deadline-gebunden) | +| **Voraussetzungen (features-plan)** | Prompt-Template «Mietzinsbestätigung prüfen», Abacus-Stammdaten-Abfrage konfigurieren, `data.writeToTable`-Output-Renderer | + +### S4 — «Beleg-Import» (periodische Spesen-/Belegverarbeitung; 1.1, 1.10.5) + +| | | +|---|---| +| **Bedürfnis** | Belege/Spesen aus SharePoint/Drive periodisch klassifizieren, kontieren, verbuchen | +| **Trigger** | `trigger.schedule` (z. B. täglich 22:00) | +| **Bausteine (Graph)** | `sharepoint.listFiles` → `flow.loop` → `trustee.extractFromFiles` → `trustee.processDocuments` (Klassifikation + Kontierung) → `trustee.syncToAccounting` | +| **Settings (L3)** | Quelle (Ordner), Ziel-Buchhaltung (RMA/Bexio/Abacus), Klassifikations-/Kontierungsoptionen, Zeitplan | +| **Output (L4)** | `table` verarbeitete Belege + `summary` | +| **Kunden** | Bling, PWG, Quid | +| **Voraussetzungen** | bestehende Pipeline + System-Template existiert bereits; als Solution kapseln | + +### S5 — «Finanz-Analyse & Reporting» (1.2–1.7, 4.x — heute Prompt-Templates) + +| | | +|---|---| +| **Bedürfnis** | Budget/Soll-Ist, KPI-Dashboard, Cashflow, Prognose, Jahresabschluss-Checks, Liquidität | +| **Trigger** | `trigger.manual` / `trigger.form` oder `trigger.schedule` (periodischer Report) | +| **Bausteine (Graph)** | `trustee.refreshAccountingData` → `trustee.queryData`/`aggregateTable` → `ai.generateDocument`/`ai.prompt` → Output | +| **Settings (L3)** | Periode(n), Vergleichsbasis (Vorjahr/Budget), optionaler Budget-Upload, KPI-Auswahl, Empfänger | +| **Output (L4)** | `table` (KPIs), `file` (Report-PDF) oder `summary` | +| **Kunden** | Bling, Quid, allgemein Treuhand | +| **Voraussetzungen** | bestehende Analyse-Prompt-Templates als Solution-Templates verfügbar machen (Migration aus `mainTrustee.py` → kuratierte Templates) | + +### S6 — «Benachrichtigung / Report-Verteilung» (1.9.12, 4.5.8) + +| | | +|---|---| +| **Bedürfnis** | Bei Ereignis/Zeitplan Bericht erzeugen und rollenbasiert verteilen; KPI-Alerts | +| **Trigger** | `trigger.schedule` / `trigger.event` (DB-Change → features-plan) | +| **Bausteine (Graph)** | Daten lesen → `ai.generateDocument` (optional) → `rbac.queryUsersByRole` → `email.send`/`outlook.send` | +| **Settings (L3)** | Auslöser/Schwellwerte, Empfänger-Rollen, Vorlage | +| **Output (L4)** | `summary` + Mail | +| **Voraussetzungen (features-plan)** | `rbac.queryUsersByRole`, optional `trigger.event`/DB-Change-Detection | + +## Gemeinsames Settings-Muster (alle Solutions) + +- **`settingsSchema`** automatisch aus `trigger.form` + exposed Node-Params abgeleitet (kuratierte Overrides später). +- **`settingsValues`** inkl. **Instanz-Set** (Multi-Instanz-Fan-out). +- **`triggerPolicy`** manuell/Zeitplan/Event/Form + `accessControl.requiredRoles` (bestehende Feature-Rollen). +- **`outputBinding.kind`** = `file | table | summary` (Dashboard später). +- **Lebenszyklus** in der «Lösungen»-Seite: Liste · Katalog/Neu (Vorlage oder AI) · Detail mit Tabs (Einstellungen · Testlauf · Läufe · Ausgabe). + +## Betroffene Module + +- **Daten/Config (kein Code pro Solution):** Solution-Definition + Settings-Record pro Feature-Instanz (Modell → features-plan), Workflow-Graph als Template/Version. +- **Kuratierte System-Templates:** `interfaces/interfaceBootstrap.py` — «Systeme synchronisieren», «Periodisches Reporting», «Dokumente verarbeiten», «Beleg-Import», «Finanz-Analyse». +- **Voraussetzungen (Code):** vollständig im **features-plan** (Solution-Schicht, generische Nodes, Connectors, `testMode`, `rbac.queryUsersByRole`). +- **Demo:** je Solution ein Demo-Setup (Pling-/PWG-/Bling-Mandant) — verweist auf Demo-Items aus dem alten Kundenplan. + +## Entscheidungen + +| Datum | Entscheidung | Begründung | +|-------|-------------|------------| +| 2026-06-04 | Kunden-Use-Cases primär als **Solutions** (Config) statt Code | step1-architecture Solution-first; skaliert ohne Engineering pro Kunde | +| 2026-06-04 | SelectLine→RMA und Pling als **erste produktive Solutions** | konkrete Geld-Cases, decken Sync- und Reporting-Muster ab | +| 2026-06-04 | Analyse-Prompt-Templates (Budget/KPI/Cashflow/…) werden **Solution-Templates** | bisher Trustee-interne Quick Actions → kundentauglich als Solutions | +| 2026-06-04 | Fehlende Bausteine werden **generisch** im features-plan gebaut, nie kundenspezifisch | «keine Kundenlogik im Code» | + +## Umsetzungs-Checkliste + +- [ ] Solution-Schicht + generische Bausteine verfügbar (→ features-plan: A1–A3) +- [ ] System-Template «Systeme synchronisieren» + Demo SelectLine→RMA (S1) +- [ ] System-Template «Periodisches Reporting» + Pling-Solution konfiguriert (S2) +- [ ] System-Template «Dokumente verarbeiten» + PWG-Mietzins-Solution (S3) — Deadline Sommer 2026 +- [ ] «Beleg-Import» als Solution kapseln (S4) +- [ ] Analyse-Templates → Solution-Templates migrieren (S5) +- [ ] «Benachrichtigung/Report» (S6) inkl. rollenbasierte Verteilung +- [ ] Pro Solution: Testlauf (`testMode`) grün, dann Aktivierung + +## Akzeptanzkriterien + +| # | Kriterium (Given-When-Then) | Prio | +|---|---|---| +| 1 | Given konfigurierte S1, When der Sync läuft, Then erscheinen SelectLine-Rechnungen als Buchungen in RMA (kein Kunden-Code; zweiter Kunde = nur andere Settings) | must | +| 2 | Given konfigurierte S2 (Pling), When der Monatslauf läuft, Then 6 PDFs erzeugt + rollenbasiert versendet + archiviert; manueller Start nur für `trustee-admin` | must | +| 3 | Given S2 im Testlauf, When ausgeführt, Then Reports werden erzeugt aber **keine** Mails versendet (`testMode`) | must | +| 4 | Given konfigurierte S3, When Scans eintreffen, Then Übersichtstabelle mit Status + Antwortvorschlägen + Mail | must | +| 5 | Given eine Solution, When der Kunde Settings ändert, Then ohne Code-Deploy wirksam (Settings = Daten) | must | +| 6 | Given ein neuer ähnlicher Use Case, When aus Template instanziiert, Then nur Settings nötig, kein Code | should | + +## Offene Fragen + +1. **S1 Erreichbarkeit:** SelectLine on-prem → Zugriffsweg (VPN/Tunnel/Agent)? Zielart RMA (AR-Rechnung vs. GL-Buchung)? +2. **S5 Migration:** Wie viele der Analyse-Prompt-Templates werden 1:1 Solution-Templates vs. konsolidiert? +3. **S2/S3 Output:** `outputBinding`-Detail (Artefakt-Referenz, `table`-Spalten aus Node-Output ableiten) — siehe step1-architecture «Output-Bindung». +4. **Demo-Daten:** welche Mandanten/Testdaten zuerst (Pling, PWG, Bling)? + +## Links + +- Architektur: `c-work/0-ideas/2026-06-CustomerCases-step1-architecture.md` +- Product Summary: `c-work/0-ideas/2026-06-CustomerCases-step2-communication-product-summary.md` (+ `.pdf`) +- Mockup: `c-work/0-ideas/2026-06-CustomerCases-step2-communication-mockup.html` +- Features/Code: `c-work/0-ideas/2026-06-CustomerCases-step3-features-plan.md` +- Pling-Spec: `pamocreate/projects/poweron/customer-pling/20-spezifikation/20260522-workflow-spec-kaffee-klatsch.md` (+ `-anhang.md`) +- Bausteine: `b-reference/platform-core/workflow.md`, `b-reference/platform-core/automation.md`, `b-reference/platform-core/features/trustee.md` + +## Abschluss + +- [ ] Bei Annahme → Solution-Templates + erste Konfigurationen in `c-work/2-build/` +- [ ] `b-reference/` Kanon-Seite «Solutions» nach Umsetzung +- [ ] `_CHANGELOG.md`-Eintrag pro Solution diff --git a/c-work/1-plan/2026-05-lawyer-feature.md b/c-work/1-plan/2026-05-lawyer-feature.md deleted file mode 100644 index c072431..0000000 --- a/c-work/1-plan/2026-05-lawyer-feature.md +++ /dev/null @@ -1,195 +0,0 @@ - - - - -# Lawyer Feature (Mandatsvorbereitung + Dashboards) - -## Beschreibung und Kontext - -Im Sales-Meeting mit David Vasella (WalderWyss) am 13.05.2026 hat sich ein klares Bild ergeben: Anwaltskanzleien arbeiten mit grossen Mengen **nicht human-readable Daten** (PDFs, E-Mails, frühere Mandate, Konflikt-Checks, KYC/AML, Buchungen). Zwischen internen Prozessen und der Mandantsbesprechung entsteht ein Overhead, den **Copilot nicht löst**. Existierende Branchen-Tools (Harvey.ai ~500 USD p/m/user, Legora, ClientFlex) sind teuer und decken die Anforderungen nicht voll ab. WW hat **kein CRM**. - -PORTA hat bereits alle Bausteine: Workspace, Knowledge/RAG, Konnektoren, Neutralisierung, Private LLM. Das `lawyer`-Feature bündelt diese Bausteine zu einem **opinionated UI für Anwälte**: ein Feature-Modul mit zwei Hauptseiten – **Dashboards** (HR / Business-Client / IT) und **Matter Preparation** (Mandatsvorbereitung in 5 Minuten). - -Business-Treiber: -- WW konkretes Sales-Asset (HTML-Präsentation und später Live-Demo). -- Eigene Use Cases für Homepage (`www.poweron.swiss`) – Sales-Story «echtes Produkt». -- Investor-Pitch (Founderful via Dominic + Philipp) braucht klare vertikale Geschichte. -- Wiederverwendbar für jede Anwaltskanzlei und mit Anpassung für Treuhand/Audit/Steuerberatung. - -## Fokus und kritische Details - -- **Berufsgeheimnis (StGB Art. 321)** – Mandantsdaten dürfen den Mandanten-Tenant nicht verlassen. Neutralisierung + Private LLM **zwingend** für jeden Pfad, der LLM nutzt (`wiki/b-reference/platform/neutralization.md`). -- RBAC korrekt: feature-instance roles, **NICHT** mit mandate roles vermischen (`.cursor/rules/rbac-role-separation.mdc`). -- Daten kommen aus heterogenen Quellen: Document Management System (DMS), E-Mail-Archiv, Zeiterfassung, Buchhaltung, KYC/AML, Konflikt-Check-DB. Konnektor-Pflege ist der **harte Teil**, nicht das UI. -- Mockup-Daten in der WW-Präsentation müssen klar als **synthetic** markiert sein. - -## Ziel und Nicht-Ziele - -- **Ziel:** Feature-Modul `lawyer` mit: - - Dashboard-Seite mit Tabs pro Funktion (HR, Business/Client, IT, optional Finance). - - Matter-Preparation-Seite: Anwalt definiert Kontext (Mandant, Matter, Meeting-Ziel, Datum), System aggregiert Quellen, AI-Agent generiert Briefing (Kerndaten, Risiken, Deadlines, offene Punkte, Agenda-Vorschlag). -- **Ziel:** Wiederverwendung der bestehenden PORTA-Bausteine (Workspace, Knowledge, Konnektoren, Neutralisierung, Private LLM). -- **Ziel:** Standard-Konnektoren für DMS (SharePoint, iManage), E-Mail (Outlook/Exchange), KYC-/Konflikt-Datenquellen, Buchhaltung (im ersten Schritt einer pro Kategorie). -- **Explizit NICHT:** vollständiges Practice-Management-System ersetzen (kein Time-Tracking-Replacement, kein Billing-System). -- **Explizit NICHT:** generische Vertragsanalyse / Drafting (das machen Harvey/Legora besser, wir sind komplementär). -- **Explizit NICHT:** eigene KYC/AML-Datenquelle aufbauen – wir konsumieren bestehende. - -## Betroffene Module - -- Gateway: - - Neues Feature-Modul `platform-core/modules/features/lawyer/` mit `mainLawyer.py`, `datamodelLawyer.py`, `interfaceLawyer.py`, `routeFeatureLawyer*.py`. - - Workflow-Method `platform-core/modules/workflows/methods/methodLawyer/` für `lawyer.prepareMatter`, `lawyer.queryData`. - - Konnektoren: prüfen, welche bestehen (`platform-core/modules/connectors/`), welche neu (DMS, KYC). -- Frontend: - - Neue Komponenten `ui-nyla/src/components/Lawyer/`. - - Dashboard-View mit Tabs. - - Matter-Preparation-View (analog Workspace, opinionated). -- DB-Migration: ja – neue Tabellen `LawyerMatter`, `LawyerPreparation`, `LawyerDashboardSnapshot`, `LawyerKpi`. -- Andere Komponenten: Knowledge/RAG (bestehend), Neutralisierung (bestehend), Private LLM (bestehend), Workspace-Agent-Tools (Erweiterung). - -## Entscheidungen - -| Datum | Entscheidung | Begründung | -|-------|-------------|------------| -| 2026-05-14 | Feature-Code `lawyer` (analog `trustee`, `realEstate`) | Konsistenz mit bestehenden Feature-Modulen | -| 2026-05-14 | Template-Rollen `lawyer-admin`, `lawyer-user`, `lawyer-viewer` | RBAC-Regel: feature-instance roles, mandate-getrennt | -| 2026-05-14 | Matter-Preparation nutzt bestehenden Workspace-Agent + neue opinionated Tool-Chain | Wiederverwendung statt Neubau | -| 2026-05-14 | Dashboards starten als read-only Aggregations-Views auf Konnektor-Daten | Schneller Time-to-Demo, Schreibpfad später | -| 2026-05-14 | Sprache UI primär Englisch | WW-Audience Management Board, Investor-tauglich; DE-Lokalisierung Phase 2 | - -## Use Cases (User Stories) - -### UC-1: Matter Preparation in 5 Minutes - -**Given** ein Anwalt hat morgen ein Klienten-Meeting für Matter `M-2024-0042` (M&A-Transaktion). -**When** er auf der Matter-Preparation-Seite den Matter und das Meeting-Ziel eingibt ("Statusbesprechung Due Diligence, offene Punkte"), -**Then** sammelt das System innerhalb von ~60 Sekunden aus DMS (alle Dokumente zu M-2024-0042), E-Mails (letzte 30 Tage), Zeiterfassung (WIP + Deadlines), KYC/AML (Aktueller Status), Konflikt-Check. -**And** generiert ein strukturiertes Briefing: - - Kerndaten Mandant + Matter - - Stand Due Diligence (Dokumente, offene Punkte) - - Risiken & Deadlines - - Offene Aktionen seit letzter Besprechung - - Vorschlag Agenda - - Quellenliste (jeder Punkt mit Link zur Quelle) -**And** alle Mandantsdaten werden neutralisiert, bevor sie das LLM erreichen. - -### UC-2: Partner-Dashboard - -**Given** ein Partner möchte vor der Wochensitzung den Stand seines Teams sehen. -**When** er die Dashboard-Seite öffnet, -**Then** sieht er HR-KPIs (Billable Hours, Utilization, Realization) für sein Team, Top-3-Risk-Matters, AR Aging. -**And** kann pro KPI in die Detailansicht drillen (Drilldown via Konnektor-Live-Query). - -### UC-3: IT/Compliance-Dashboard - -**Given** der IT-Leiter braucht für ein Audit-Meeting den Compliance-Status. -**When** er den IT-Tab öffnet, -**Then** sieht er Uptime, Security-Incidents (letzte 90 Tage), Patch-Status, KYC/AML-Backlog, Conflict-Check-SLAs. - -## Datenmodell-Skizze - -| Modell | Felder (Kern) | Kommentar | -|--------|---------------|-----------| -| `LawyerMatter` | id, featureInstanceId, mandateCode, clientName, matterType, openedAt, status, leadLawyerUserId | Mandate spiegeln, nicht zweimal halten | -| `LawyerPreparation` | id, matterId, requestedBy, meetingGoal, createdAt, briefingJson, sourceRefs | Persistiert das generierte Briefing für Audit + Wiederverwendung | -| `LawyerDashboardSnapshot` | id, featureInstanceId, dashboardType, periodStart, periodEnd, dataJson, generatedAt | Cache für Dashboard-Daten, Refresh periodisch | -| `LawyerKpi` | id, featureInstanceId, kpiCode, label, formula, lastValue, lastValueAt, dashboardType | Konfigurierbare KPI-Definitionen pro Tenant | -| `LawyerSourceMap` | id, featureInstanceId, sourceType, connectorRef, mappingJson | Welcher Konnektor liefert welche Daten in welche KPI | - -## Actions (Workflow-Method) - -| Action | Eingabe | Output | Zweck | -|--------|---------|--------|-------| -| `lawyer.prepareMatter` | featureInstanceId, matterId, meetingGoal, lookbackDays | LawyerPreparation (briefingJson + sourceRefs) | Sammelt aus Quellen, neutralisiert, generiert Briefing via Workspace-Agent | -| `lawyer.refreshDashboard` | featureInstanceId, dashboardType, periodStart, periodEnd | LawyerDashboardSnapshot | Re-aggregiert KPI-Werte aus Konnektoren | -| `lawyer.queryData` | featureInstanceId, freie Filter | ActionResult mit Query-Resultat | Read-only Zugriff für AI-Agent (analog `trustee.queryData`) | - -## UI-Skizze - -``` -/lawyer// - ├── dashboards/ - │ ├── hr (Tab) - │ ├── business (Tab) - │ ├── it (Tab) - │ └── finance (Tab, optional) - └── matter-preparation/ - ├── - └── / - ├── briefing (generated) - ├── sources (drilldown) - └── agenda-export (PDF/Markdown) -``` - -## RBAC-Mapping - -- Template-Rollen (Feature-Code `lawyer`, `mandateId=NULL`, `isSystemRole=False`): - - `lawyer-admin` – Feature-Instance-Admin, Konnektor-Konfig, KPI-Definition. - - `lawyer-user` – Anwalt, Matter-Preparation, Dashboard read. - - `lawyer-viewer` – Read-only, z. B. Management Board. -- Nutzung: `FeatureAccessRole` mit `featureCode=lawyer, featureInstanceId=, mandateId=, roleId=<>`. -- Strikt getrennt von Mandate-Rollen (`admin`, `user`, `viewer`). - -## Umsetzungs-Checkliste - -- [ ] Datenmodell (`datamodelLawyer.py`) – 5 Modelle + PowerOnModel-Basis -- [ ] Migration: Auto-Schema reicht? (analog `trustee`) -- [ ] Feature-Modul (`mainLawyer.py`) inkl. Template-Rollen-Definition -- [ ] Workflow-Method `methodLawyer/` mit 3 Actions -- [ ] Konnektoren-Inventur: was haben wir, was fehlt - - [ ] DMS-Konnektor (SharePoint vorhanden, iManage neu?) - - [ ] E-Mail-Konnektor (Outlook/Exchange vorhanden?) - - [ ] Zeiterfassung (mandantenabhängig, Anbindung über generisches Schema) - - [ ] KYC/AML (extern, API-Anbindung mandantenspezifisch) - - [ ] Konflikt-Check (intern WW-System – API klären) -- [ ] Routes (`routeFeatureLawyer.py`) -- [ ] Frontend-Komponenten (`Lawyer/Dashboard`, `Lawyer/MatterPreparation`) -- [ ] RBAC: Template-Rollen registrieren (siehe `.cursor/rules/rbac-role-separation.mdc`) -- [ ] Neutralisierung: `prepareMatter`-Action zwingend mit `PrivateLLM`-Pfad für sensitive Daten -- [ ] Navigation (Gateway → Frontend) – Feature-Eintrag -- [ ] Billing-Impact: prüfen (analog andere Features – pro Feature-Instance, Subscription-Capacity) -- [ ] Mockup-Daten-Set (synthetic) für WW-Präsentation + Demo -- [ ] Demo-Login-Mandant einrichten (für Live-Demo nach Präsentation) - -## Akzeptanzkriterien - -| # | Kriterium (Given-When-Then) | Prio | -|---|---------------------------|------| -| 1 | Given Anwalt mit `lawyer-user`-Rolle, When er Matter-Preparation für offenen Matter triggert, Then erhält er in <90s strukturiertes Briefing mit ≥3 Quellen | must | -| 2 | Given sensitive Mandantsdaten (Namen, Beträge), When `lawyer.prepareMatter` läuft, Then werden alle PII vor LLM-Call neutralisiert (Audit-Trail in Neutralization-Log) | must | -| 3 | Given User mit `lawyer-viewer`, When er Dashboard öffnet, Then sieht er KPIs read-only ohne Schreib-Buttons | must | -| 4 | Given User mit Mandate-Rolle `admin` aber ohne `lawyer-*`, When er Lawyer-Feature öffnet, Then Access Denied | must | -| 5 | Given Dashboard-Konnektor offline, When `refreshDashboard` läuft, Then Snapshot zeigt Fehlerstatus, Frontend zeigt klare Meldung statt leerer Werte | should | -| 6 | Given Briefing generiert, When Anwalt es exportiert, Then PDF/Markdown mit Quellenliste und «synthetic data» Wasserzeichen (im Demo-Mandanten) | should | - -## Testplan - -| ID | AC | Art | Automatisiert | Repo-Pfad | Status | -|----|----|-----|--------------|-----------|--------| -| T1 | 1 | api | ja | platform-core/tests/test_lawyer_prepare_matter.py | pending | -| T2 | 2 | integration | ja | platform-core/tests/test_lawyer_neutralization.py | pending | -| T3 | 3,4 | api | ja | platform-core/tests/test_lawyer_rbac.py | pending | -| T4 | 5 | integration | ja | platform-core/tests/test_lawyer_dashboard_refresh.py | pending | -| T5 | 1,6 | e2e | manuell | – | pending | - -## Demo-Asset Plan (für WW-Präsentation) - -- Synthetic Matter `M-DEMO-001` (M&A) mit fiktiven Dokumenten, E-Mails, Zeiteinträgen. -- Briefing-Output statisch generiert und in `30-presentation/src/data/matter-preparation.json` ablegen, damit die HTML-Präsentation **ohne Backend** funktioniert. -- Wenn David Live-Demo will: gleichen Demo-Mandanten im PORTA-Demo-Tenant live verfügbar machen. - -## Links - -- WW-Kontext: `pamocreate/projects/poweron/customer-walderwyss/20-objectives/20260514-zusammenfassung-meeting-dv.md` -- WW-Präsentation: `pamocreate/projects/poweron/customer-walderwyss/30-presentation/` -- Bestehende Feature-Doku als Vorbild: `wiki/b-reference/platform-core/features/trustee.md` -- Plattform-Bausteine: `wiki/b-reference/platform/neutralization.md`, `wiki/b-reference/platform/rbac.md` -- PR: – (noch nicht) -- Issue: – (noch nicht) - -## Abschluss - -- [ ] `b-reference/platform-core/features/lawyer.md` als neue Kanon-Seite anlegen -- [ ] `TOPICS.md` Eintrag für Lawyer-Feature -- [ ] Dieses Dokument → `2-build/` → `3-validate/` → `4-done/` -- [ ] Eintrag in `c-work/_CHANGELOG.md` pro Phase diff --git a/c-work/1-plan/2026-06-umsystem-integration-connectors-und-datenquellen-seiten.md b/c-work/1-plan/2026-06-umsystem-integration-connectors-und-datenquellen-seiten.md deleted file mode 100644 index aea6b23..0000000 --- a/c-work/1-plan/2026-06-umsystem-integration-connectors-und-datenquellen-seiten.md +++ /dev/null @@ -1,222 +0,0 @@ - - - - -# Umsystem-Integration: generische Connectors + kundenspezifische Workflows + Datenquellen-Seiten - -## Beschreibung und Kontext - -Ein Kunde schreibt seine Rechnungen in einem externen System (**SelectLine**, REST-API vorhanden) und möchte, dass diese Rechnungen **ins RMA (Run My Accounts)** geladen werden. Die Frage des Kunden: «Kann PowerOn dafür einfach eine Schnittstelle machen?» - -Der konkrete Fall ist ein Spezialfall eines generischen Musters: PowerOn soll **proprietäre Umsysteme** (ERP, Fakturierung, Lohn, …) anbinden. Wir haben die Logik dafür im Prinzip schon – im Feature **Trustee** sind Buchhaltungssysteme (ABACUS, Bexio, Banana, **RMA**) über das **AccountingBridge-Connector-Framework** angebunden (`platform-core/modules/features/trustee/accounting/`). RMA ist bereits ein vollwertiger Ziel-Connector (inkl. `pushBooking`, `pushInvoice`, Beleg-Upload). - -**Kern-Architekturvorgabe (Auftrag):** Es soll **keine kundenspezifische Logik im Code** entstehen. Wir trennen sauber in: - -1. **Generische Bausteine** (Code, wiederverwendbar, ohne Kundennamen): Connectors, kanonische Datenmodelle, generische Workflow-Nodes. -2. **Kundenspezifische Logik** (als **Daten** = Workflow-Graph + Config, nicht als Code): die konkrete Verdrahtung «SelectLine → Mapping → RMA» pro Mandant/Instanz im Graphical Editor. - -Business-Treiber: -- Konkreter Kundenwunsch (Termin nächste Woche). -- Wiederverwendbares Muster für jedes weitere Umsystem → Sales-Asset und skalierbare Onboarding-Story. -- Vermeidung von Wartungs-Hölle durch `if kunde == X`-Code. - -**Abgrenzung — NICHT als Personal Source einbinden.** Personal Sources (UDB-`DataSource`-Familie: SharePoint, Drive, Infomaniak) sind **user-privat** und für **unstrukturierte RAG-Daten** gedacht (`wiki/b-reference/platform/unified-data-bar.md`). Eine Debitorenrechnung von SelectLine nach RMA ist ein **transaktionaler Buchungs-Vorgang auf Mandant-/Feature-Ebene** mit Dedup, Sync-Audit und verschlüsselten Credentials pro Mandant. Das gehört in das **Trustee-Connector-Framework** (`featureInstanceId`-scoped), nicht in Personal Sources. - -## Fokus und kritische Details - -- **Trennung Baustein ↔ Kundenlogik ist das eigentliche Ziel.** Jede Versuchung, Kunden-/Systemspezifika fest zu verdrahten (Konten-Mappings, Filter, Belegart-Auswahl), muss in **Config/Workflow-Graph** wandern, nicht in den Connector. -- **Connector = reiner API-Adapter.** Auth, Lesen/Schreiben von Ressourcen, Mapping zwischen nativem API-Format und kanonischem Modell. Keine Geschäftsregeln, keine Kundennamen, keine Konto-Zuordnungen. -- **Richtung.** Bestehende AccountingBridge ist heute **push-orientiert** (lokale `TrusteePosition` → extern). SelectLine ist eine **Quelle** (lesen). Wir brauchen einen sauberen **Import-/Source-Pfad** und eine **Rolle** (`source` / `target`) auf der Config, weil eine Instanz künftig *eine Quelle* **und** *ein Ziel* hat. -- **On-Prem-Erreichbarkeit (grösstes Risiko, extern abhängig).** Die SelectLine-API läuft typischerweise beim Kunden (Doku zeigt `http://localhost/...`). Unsere Cloud muss sie erreichen → VPN / Reverse-Tunnel / fester Endpoint / On-Site-Agent. Klärt Aufwand und Sicherheit. -- **Datenschutz/Neutralisierung.** Rechnungen enthalten Personendaten. Pfade, die durch das LLM laufen (z. B. KI-gestütztes Konten-Mapping), müssen über das Neutralisierungs-Gate (`wiki/b-reference/platform/neutralization.md`). -- **Fragile Stellen:** `accountingBridge.py` (Orchestrierung, Dedup, Sync-Records) ist heute auf Position→Push zugeschnitten; der Source-Pfad muss additiv ergänzt werden, ohne den bestehenden Push-Pfad zu brechen. `TrusteeAccountingConfig` erlaubt heute nur **eine aktive** Config pro Instanz (siehe `getActiveConfig`). - -## Ziel und Nicht-Ziele - -- **Ziel:** Generisches, plugin-basiertes **Umsystem-Connector-Framework** (Erweiterung des bestehenden AccountingBridge-Musters), mit dem ein neues System = **eine Connector-Datei + Config**, ohne Architekturänderung. -- **Ziel:** **SelectLine-Connector** (Quelle): Login, Lesen von Ausgangsrechnungen (`Document`/`DocumentKind`), Kunden, Konten, Steuerschlüssel. -- **Ziel:** **Source→Target-Import** als **generische Workflow-Nodes**, sodass «SelectLine → RMA» ein **Workflow-Graph** ist (kundenspezifisch als Daten), kein Code. -- **Ziel:** **UI-Muster «Datenquelle = Seite»** im Feature Trustee: die Seite «Buchhaltungssystem» existiert; das Muster wird generisch, sodass weitere Kategorien (z. B. «Saläre», «Fakturierung») als eigene Seiten dazukommen können. -- **Explizit NICHT:** kundenspezifische Logik im Code (`if kunde == …`). -- **Explizit NICHT:** SelectLine als Personal Source. -- **Explizit NICHT:** Aufbau eines eigenen ERP/Faktura-Systems – wir konsumieren/transferieren nur. -- **Explizit NICHT (vorerst):** voll generisches «Integrations-Framework für alles». Wir bleiben im Trustee-Kontext und verallgemeinern erst, wenn die zweite Kategorie (Saläre) real wird (YAGNI – siehe «Meine Gedanken»). - -## Architektur: generische Bausteine vs. kundenspezifische Logik - -Vier Schichten. Schicht 1–3 sind **Code (generisch)**, Schicht 4 ist **Daten (kundenspezifisch)**. - -``` -┌─ Schicht 4: WORKFLOW-GRAPH + CONFIG (Daten, pro Instanz, im Graphical Editor) ─┐ -│ "SelectLine → mappe Konto 1100→1100, Belegart=AR, seit lastSync → RMA (GL)" │ -│ Konto-Mappings · Filter · Zeitplan · Quelle/Ziel-Auswahl → KUNDENSPEZIFISCH │ -└─────────────────────────────────────────────────────────────────────────────────┘ - ▲ konsumiert generische Nodes, enthält KEINEN Code -┌─ Schicht 3: WORKFLOW-NODES (generische Typed Actions) ─────────────────────────┐ -│ source.fetchInvoices · transform.mapAccounts · target.pushBooking · attachDoc │ -└─────────────────────────────────────────────────────────────────────────────────┘ - ▲ arbeiten ausschliesslich auf kanonischen Modellen -┌─ Schicht 2: KANONISCHE MODELLE ─────────────────────────────────────────────────┐ -│ AccountingBooking / AccountingBookingLine / Invoice / Contact / Chart … │ -│ (bereits vorhanden in accountingConnectorBase.py) │ -└─────────────────────────────────────────────────────────────────────────────────┘ - ▲ Connectors übersetzen natives API-Format ⇄ kanonisch -┌─ Schicht 1: CONNECTORS (generische API-Adapter, plugin-discovery) ─────────────┐ -│ accountingConnectorRma.py · accountingConnectorSelectline.py · …bexio/abacus │ -│ nur Auth + Lesen/Schreiben + Mapping. KEINE Kundenlogik. │ -└─────────────────────────────────────────────────────────────────────────────────┘ -``` - -### Schicht 1 — Connectors (neu: SelectLine) - -- Neue Datei `platform-core/modules/features/trustee/accounting/connectors/accountingConnectorSelectline.py`, implementiert `BaseAccountingConnector` (`accountingConnectorBase.py`). Auto-Discovery über `accountingRegistry.py` (Pattern `accountingConnector*.py`) → **keine Registrierungs-Änderung nötig**. -- Methoden: `testConnection` (Login + GET), `getChartOfAccounts` (Konten), `getCustomers`/`getVendors`, und die Lese-Seite für Belege (siehe «Source-Capability» unten). -- Config-Felder (`getRequiredConfigFields`): `baseUrl`, `username`, `password` (secret), optional `mandant`. Verschlüsselt wie alle Configs (`_decryptConfig`). -- **Source-Capability:** Da die Base heute primär Push/Read-Journal kennt, ergänzen wir eine schlanke, optionale Lesemethode für Belege, z. B. `getOutgoingInvoices(config, dateFrom, sinceCursor) -> List[Invoice]` (Default `[]` in der Base; nur Source-Connectors überschreiben). Alternativ Wiederverwendung von `getJournalEntries` – Entscheidung siehe «Offene Fragen». - -### Schicht 2 — kanonische Modelle (vorhanden) - -`AccountingBooking`, `AccountingBookingLine`, `AccountingChart`, `SyncResult` etc. in `accountingConnectorBase.py`. Für reine Debitoren-Fakturen ggf. ein kanonisches `Invoice`-Modell ergänzen (Header + Lines + Kunde + Steuer), falls RMA als **AR-Rechnung** (offener Posten) statt GL-Buchung beschrieben werden soll. - -### Schicht 3 — Workflow-Nodes (generisch, Typed Actions) - -Analog zu den bestehenden Trustee-Actions (`trustee.extractFromFiles` → `processDocuments` → `syncToAccounting`). Neue, **system-agnostische** Nodes: - -- `integration.fetchFromSource` — zieht Belege/Buchungen aus dem **konfigurierten Quell-Connector** (Quelle = Config, nicht hartcodiert) → kanonische Liste. -- `integration.mapAccounts` — wendet eine **Mapping-Tabelle** (Config/Daten) auf Konten/Steuercodes an. -- `integration.pushToTarget` — schreibt über den **konfigurierten Ziel-Connector** (`pushBooking`/`pushInvoice` + Beleg-Upload, bereits in RMA vorhanden). - -Diese Nodes erscheinen über den Editor-Adapter (`graphicalEditor/nodeDefinitions/`) als Bausteine im Graphical Editor. Die Pipeline `trigger → fetchFromSource(SelectLine) → mapAccounts → pushToTarget(RMA)` ersetzt damit für strukturierte Quellen den KI-Extraktionsschritt (günstiger + zuverlässiger). - -### Schicht 4 — Workflow-Graph + Config (kundenspezifisch, als Daten) - -- Der konkrete Kundenfluss ist ein **Workflow-Template/Graph** pro Feature-Instanz (persistiert), gebaut im Graphical Editor. Konten-Mappings, Filter (nur Ausgangsrechnungen, nur «seit letztem Sync»), Buchungsart, Zeitplan = **Config-Datensätze**. -- Ergebnis: zwei Kunden mit SelectLine→RMA, aber unterschiedlichem Kontenplan-Mapping = **zwei Graphen/Configs, ein Code**. - -### Datenmodell-Änderung - -`TrusteeAccountingConfig` um **`role`** (`source` | `target`) erweitern, sodass pro Instanz mehrere Connector-Configs koexistieren (eine Quelle + ein Ziel). `getActiveConfig` / `_resolveConnectorAndConfig` entsprechend um `role` filtern. Optional: `connectorCategory` (`accounting` | `payroll` | `invoicing`) für die UI-Seitenzuordnung. - -## SelectLine-API – Befund (Kurz) - -Geprüft anhand hilfe.selectline.ch und der Demo-API (demo.slmobile.de): - -- REST, JSON/XML. Auth: `POST /Login` mit `{username,password}` → `AccessToken`/`LoginId`; danach Header `Authorization: LoginId ` (Session-Token, Re-Login bei Ablauf). -- Relevante Ressourcen: **`Document` / `DocumentKind`** (Belegkette inkl. Ausgangsrechnungen), `Customers`/`Vendors` (Geschäftspartner), `Konten` + `Kontensalden`, `Journale`, `Offene Posten`, `Steuerschlüssel`, `Kostenrechnung`, `Bankassistent` (camt.053-Import). -- Betriebsmodell: i. d. R. **on-premise** beim Kunden → Erreichbarkeit klären (Risiko oben). -- Swagger-/OpenAPI-Beschreibung pro Installation herunterladbar → exaktes Beleg-Schema beim Kunden verifizieren. - -## UI-Konzept: «Datenquelle = Seite» - -Heute ist «Buchhaltungs-Einstellungen» eine eigene Seite im Trustee-Feature: -- Registriert als UI-Object `ui.feature.trustee.settings` (`meta.area="settings"`, `admin_only`) in `mainTrustee.py`. -- Gemappt auf `TrusteeAccountingSettingsView` in `ui-nyla/src/pages/FeatureView.tsx` (`VIEW_COMPONENTS.trustee.settings`). -- Innen bereits Tabs: «Verbindungseinstellungen» + «Buchhaltungsdaten importieren» (Connector wählen → Credentials → Test → Import). - -**Vorschlag:** dieses Muster zu einem **generischen «Datenquellen-Seiten»-Pattern** verallgemeinern – eine Seite pro **Kategorie** von Umsystem: - -| Seite (UI-Area) | Kategorie | Connectors (Beispiele) | Kanonisches Modell | -|---|---|---|---| -| Buchhaltungssystem (existiert) | `accounting` | RMA, Bexio, Abacus, **SelectLine (Quelle)** | AccountingBooking | -| **Saläre** (Idee) | `payroll` | SwissSalary, Abacus Lohn, Swissdec-konform | PayrollEntry (neu) | -| Fakturierung (Idee) | `invoicing` | SelectLine, Bexio | Invoice | - -Pro Seite identischer Aufbau (**eine generische React-Komponente, parametrisiert über `category`**): -1. **Verbindungen** — Connectors der Kategorie listen, Rolle (Quelle/Ziel) wählen, Credentials, Test (wiederverwendet die bestehende `TrusteeAccountingSettingsView`-Mechanik, generalisiert). -2. **Datenfluss/Import** — Workflow-Template wählen/starten (= Schicht-4-Graph), Zeitplan, Status/Audit. -3. **Daten** — eingelesene Datensätze (read-only Spiegel). - -Konkret: -- Generische `IntegrationSettingsView` (aus `TrusteeAccountingSettingsView` extrahiert), die `category` als Prop bekommt. -- Neue UI-Areas in `mainTrustee.py` (z. B. `ui.feature.trustee.payroll`) + Mapping in `FeatureView.tsx` → **gleiche** Komponente, andere `category`. -- «Saläre» ist bewusst **nur ein Platzhalter-Beispiel**, um zu zeigen, dass das Muster skaliert; nicht Teil der ersten Umsetzung. - -## Betroffene Module - -- **Gateway (platform-core):** - - `features/trustee/accounting/connectors/accountingConnectorSelectline.py` (neu). - - `accounting/accountingConnectorBase.py` (optionale Source-Lesemethode, Default `[]`). - - `accounting/accountingBridge.py` (additiver Import-/Source-Pfad; `role`-Auflösung). - - `datamodelFeatureTrustee.py` (`TrusteeAccountingConfig.role` [+ optional `connectorCategory`]) → **DB-Migration: ja**. - - `workflows/methods/methodTrustee/actions/` + `graphicalEditor/nodeDefinitions/` (generische Nodes `integration.fetchFromSource` / `mapAccounts` / `pushToTarget`). - - `mainTrustee.py` (UI-Areas, RBAC-Objekte, Workflow-Templates). -- **Frontend (ui-nyla):** - - `TrusteeAccountingSettingsView` → generische `IntegrationSettingsView` (`category`-Prop). - - `FeatureView.tsx` Registry + `mainTrustee` UI-Areas für weitere Seiten. - - `trusteeApi.ts` (Connector-Listing nach Kategorie, Rolle source/target). -- **DB-Migration:** ja (`role`, optional `connectorCategory`). -- **Andere:** Neutralisierung (falls KI-Mapping), Audit/Billing (Sync-Volumen). - -## Entscheidungen - -| Datum | Entscheidung | Begründung | -|-------|-------------|------------| -| 2026-06-04 | Umsystem als Trustee-Connector, **nicht** als Personal Source | Transaktional, mandant-scoped, Dedup/Audit/verschlüsselte Credentials bereits in AccountingBridge | -| 2026-06-04 | Kundenlogik als Workflow-Graph + Config, nicht im Code | Auftrag: keine kundenspezifische Logik im Code; nutzt bestehende Typed-Action-/Editor-Architektur | -| 2026-06-04 | UI-Muster «Datenquelle = Seite» pro Kategorie, eine generische Komponente | Skaliert auf Saläre/Fakturierung ohne Copy-Paste | - -## Umsetzungs-Checkliste - -- [ ] DB: `TrusteeAccountingConfig.role` (+ optional `connectorCategory`) + Migration -- [ ] Bridge: Source-Auflösung nach `role`, Import-Pfad (additiv, Push-Pfad unverändert) -- [ ] Connector: `accountingConnectorSelectline.py` (Login/Test/Konten/Kunden/Belege lesen) -- [ ] Kanonisch: `Invoice`-Modell prüfen/ergänzen (falls AR-Rechnung in RMA) -- [ ] Workflow-Nodes: `integration.fetchFromSource` / `mapAccounts` / `pushToTarget` + Editor-Adapter -- [ ] Workflow-Template «Source→Target Import» (parametrisierbar) -- [ ] UI: `IntegrationSettingsView` generalisieren (`category`), Quelle/Ziel-Auswahl -- [ ] RBAC / Permissions (neue UI-Areas, admin_only) -- [ ] Neutralisierung betroffen? (nur falls KI-Mapping) -- [ ] Navigation / Routing (UI-Areas + FeatureView-Registry) -- [ ] Billing-Impact? (Sync-Läufe/Volumen) - -## Akzeptanzkriterien - -| # | Kriterium (Given-When-Then) | Prio | -|---|---------------------------|------| -| 1 | Given konfigurierter SelectLine-Source + RMA-Target, When der Import-Workflow läuft, Then erscheinen die SelectLine-Ausgangsrechnungen als Buchungen in RMA (inkl. Beleg-Verlinkung) | must | -| 2 | Given zwei Mandanten mit unterschiedlichem Konten-Mapping, When beide SelectLine→RMA nutzen, Then unterscheiden sie sich nur in Workflow-Graph/Config – **kein** kundenspezifischer Code | must | -| 3 | Given ein neues Umsystem, When ein Connector-File + Config ergänzt wird, Then ist es ohne Änderung an Registry/Bridge/Editor verfügbar | must | -| 4 | Given erneuter Import, When Belege bereits gebucht sind, Then werden sie über die bestehende Dedup-Logik nicht doppelt gebucht | must | -| 5 | Given das UI-Muster, When eine neue Kategorie-Seite («Saläre») registriert wird, Then nutzt sie dieselbe generische Komponente | should | - -## Testplan - -| ID | AC | Art | Automatisiert | Repo-Pfad | Status | -|----|----|-----|--------------|-----------|--------| -| T1 | 1 | unit | ja | platform-core/tests/unit/features/trustee/test_accountingConnectorSelectline.py | pending | -| T2 | 1,4 | integration | ja | platform-core/tests/integration/trustee/test_source_target_import_e2e.py | pending | -| T3 | 3 | unit | ja | platform-core/tests/unit/.../test_adapter_validator.py (Editor-Node-Drift) | pending | -| T4 | 2 | unit | ja | platform-core/tests/unit/.../test_integration_nodes.py (Mapping aus Config) | pending | - -## Offene Fragen (für den Kundentermin) - -1. **Erreichbarkeit:** Wo läuft die SelectLine-API (on-prem/Cloud)? Welcher Zugriffsweg (VPN/Tunnel/Agent)? -2. **Zielart in RMA:** Debitoren-Rechnung (AR, offener Posten) **oder** GL-Buchung? → bestimmt `pushInvoice`-Ausbau vs. `pushBooking`. -3. **Mapping:** Liefert SelectLine pro Rechnung Konto + Steuerschlüssel, oder Kontenplan-Mapping SelectLine→RMA nötig? -4. **Beleg-PDF:** Rechnungs-PDF mit nach RMA (Beleg-Upload vorhanden)? -5. **Delta/Frequenz:** On-demand, Zeitplan oder Event? Cursor = Belegnummer/Datum? -6. **Alternative:** SelectLine `Bankassistent` (camt.053) – relevant oder nur Ausgangsrechnungen? - -## Meine Gedanken / Empfehlungen - -- **Saubere Trennung ist erreichbar, weil die Plattform sie schon vorlebt.** Trustee nutzt bereits Typed Actions + Graphical Editor + Templates. «Kundenlogik als Graph» ist kein neues Paradigma, sondern Anwendung des Bestehenden. Das ist der grösste Hebel gegen kundenspezifischen Code. -- **Nicht zu früh über-generalisieren.** Ein einziges «BaseConnector für alles» mit Capability-Mixins (`AccountingCapable`, `PayrollCapable`) ist elegant, aber bevor «Saläre» real ist, würde ich beim bestehenden `BaseAccountingConnector` bleiben und nur die **Source-Rolle** ergänzen. Die Abstraktion ziehen wir, wenn die zweite Kategorie konkret wird – sonst bauen wir ein Framework für hypothetische Fälle (YAGNI). -- **Namensgebung zur Abgrenzung:** «Personal Sources» = user-privat/RAG. Diese hier sind **«Umsystem-Anbindungen» / «Integrationen»** auf Mandant-Ebene. Klare Begriffe verhindern, dass die zwei Welten wieder vermischt werden. -- **Source vs. Target ist die wichtigste neue Achse.** Sie macht aus dem heutigen Push-Framework ein bidirektionales Integrations-Framework und ist die Voraussetzung für «System A → PowerOn → System B» generell. -- **«Saläre»-Seite** ist ein gutes nächstes Beispiel: Lohnsystem (Swissdec-konform) → Lohnbuchungen → Buchhaltung. Gleicher Mechanismus, neues kanonisches Modell `PayrollEntry`. Bestätigt, dass das Seiten-Muster trägt. -- **Risiko bleibt extern:** On-Prem-Erreichbarkeit von SelectLine ist der kritische Pfad – das ist eher Infrastruktur/Netzwerk als Code. Im Kundentermin zuerst klären. - -## Links - -- Vorgelagerte Analyse (dieser Chat): SelectLine-API-Prüfung + erste Empfehlung -- Referenz Trustee: `wiki/b-reference/platform-core/features/trustee.md` -- Referenz UDB/Personal Sources: `wiki/b-reference/platform/unified-data-bar.md` -- Code: `platform-core/modules/features/trustee/accounting/` (Bridge, Base, Registry, Connectors) -- PR: — -- Issue: — - -## Abschluss - -- [ ] b-reference/ aktualisiert (`features/trustee.md` Abschnitt «Source-Connectors / Integrationen»; ggf. neue `platform/integrations.md`) -- [ ] TOPICS.md aktualisiert (neues Thema «Umsystem-Integrationen») -- [ ] Dieses Dokument → c-work/2-build/ (bei Umsetzungsbeginn), am Ende → z-archive/ diff --git a/c-work/_CHANGELOG.md b/c-work/_CHANGELOG.md index 55e4679..43e1475 100644 --- a/c-work/_CHANGELOG.md +++ b/c-work/_CHANGELOG.md @@ -14,6 +14,9 @@ Skip: reine Refactors, Formatting, Lint, Dep-Bumps, Test-only, Wiki-Tippfehler. ## 2026-06-04 +- 2026-06-04 | docs | wiki | **CustomerCases-Doks auf einheitliche Naming-Convention umbenannt**: `2026-06-STEP*`-Dateien → `2026-06-CustomerCases-stepN-*` (step1=architecture, step2=communication [product-summary md/pdf + mockup html], step3=solutions-plan/features-plan). Alle Cross-Referenzen in den Dokumenten + Changelog-Pfade angepasst. (c-work: c-work/0-ideas/2026-06-CustomerCases-step1-architecture.md u. a.) +- 2026-06-04 | docs | wiki | **STEP2-Pläne neu strukturiert: Solutions vs. Features**: Die drei bisherigen STEP2-Docs (lawyer-feature, pm-consolidated-customer-requirements, umsystem-integration) durch zwei architektur-konforme Pläne ersetzt. `step3-solutions-plan.md` = alle konfigurierten Use Cases als Solutions (S1 SelectLine→RMA, S2 Pling-Reporting, S3 PWG-Mietzins, S4 Beleg-Import, S5 Finanz-Analysen, S6 Notification) mit Trigger/Bausteine/Settings/Output je Solution + Klassifikationstabelle. `step3-features-plan.md` = der Code dahinter (Teil A Plattform-Enabler: Solution-Schicht L3/L4, generische Nodes rbac.queryUsersByRole/testMode/integration.*, Connectors; Teil B vertikale Features: lawyer, commcoach, trustee-core). (c-work: c-work/0-ideas/2026-06-CustomerCases-step3-solutions-plan.md, 2026-06-CustomerCases-step3-features-plan.md) +- 2026-06-04 | docs | wiki | **Konzept: Solution-Schicht (Customer Workflows) + Pling-Use-Case**: Architektur-Idee fuer generische L3/L4-Solution-Schicht ueber dem Workflow-Stack (Use Case → konfigurierter Workflow, kein Kunden-Code). Pling «Kaffee-Klatsch» Monatsreporting als staerkstes Validierungsbeispiel eingearbeitet (Multi-Instanz-Fan-out, rollenbasierte Verteilung). Plus generische Product-Summary und klickbares HTML-Mockup im ui-nyla-Look. (c-work: c-work/0-ideas/2026-06-CustomerCases-step1-architecture.md, 2026-06-CustomerCases-step2-communication-product-summary.md, 2026-06-CustomerCases-step2-communication-mockup.html) - 2026-06-04 | docs | wiki | **Plan: Umsystem-Integration (Connectors + Workflows + Datenquellen-Seiten)**: Arbeitsdokument fuer generische Umsystem-Anbindung (SelectLine→RMA als Pilot). Trennung generische Bausteine (Connectors/kanonische Modelle/Workflow-Nodes) vs. kundenspezifische Logik (Workflow-Graph + Config). UI-Muster «Datenquelle = Seite» pro Kategorie (Buchhaltung existiert, Saläre als Idee). (c-work: c-work/1-plan/2026-06-umsystem-integration-connectors-und-datenquellen-seiten.md) ## 2026-06-03