14 KiB
PowerOn Applikations-Kontext (Stand 2026-03-29)
Multi-Tenant SaaS-Applikation mit Feature-Store-Modell, AI-Agent-Workspace und mandantenweiter Datenneutralisierung.
1. Technologie-Stack
| Layer | Technologie | Pfad |
|---|---|---|
| Backend (Gateway) | FastAPI (Python), PostgreSQL | @poweron/gateway |
| Frontend | React/TypeScript (Vite) | @poweron/frontend_nyla |
| AI Core | Multi-Provider (Anthropic, OpenAI, Mistral, Perplexity, Tavily, PrivateLLM) | @poweron/gateway/modules/aicore |
| DB-Connector | PostgreSQL mit pgvector (Embeddings) | @poweron/gateway/modules/connectors/connectorDbPostgre.py |
2. Gateway-Architektur (Backend)
Modulstruktur (gateway/modules/)
| Modul | Zweck |
|---|---|
aicore/ |
Model-Registry, Model-Selector, Provider-Plugins (Anthropic, OpenAI, Mistral, Perplexity, Tavily, PrivateLLM) |
auth/ |
Authentifizierung |
connectors/ |
DB-Connector (PostgreSQL), externe Konnektoren |
datamodels/ |
Pydantic-Datenmodelle (30+ Dateien: Ai, Billing, Chat, Content, Files, Knowledge, Rbac, Subscription, Workflow...) |
features/ |
Feature-Module (autonome Domänen): workspace, automation, automation2, chatbot, commcoach, neutralization, realEstate, trustee, teamsbot |
interfaces/ |
DB-Interfaces (App, Billing, Chat, Knowledge, Management, Subscription), AI-Objects, RBAC, Features, Messaging |
migration/ |
Daten-Migrationen |
routes/ |
REST-API-Routen (30+ Dateien: Admin, Billing, DataFiles, DataSources, Security, Store, System...) |
security/ |
Sicherheits-Middleware |
serviceCenter/ |
Zentrale Service-Orchestrierung (siehe Abschnitt 3) |
serviceHub/ |
Service-Registry und Dependency Injection |
shared/ |
Gemeinsame Utilities (attributeUtils, etc.) |
system/ |
System-Konfiguration |
workflows/ |
Workflow-Engine mit Methoden und Aktionen (siehe Abschnitt 4) |
Interfaces (DB-Schicht)
Die Interfaces kapseln alle Datenbankzugriffe:
| Interface | Verantwortlich für |
|---|---|
interfaceDbApp.py |
User, Mandate, FeatureAccess, UserConnections, Preferences |
interfaceDbBilling.py |
BillingAccount, BillingTransaction, Subscriptions |
interfaceDbChat.py |
ChatWorkflow, ChatMessage, ChatDocument |
interfaceDbKnowledge.py |
FileContentIndex, ContentChunk, RoundMemory (RAG/Knowledge Store) |
interfaceDbManagement.py |
FileItem, Folder, Prompt, DataSource (mandantenweite Stammdaten) |
interfaceDbSubscription.py |
Subscription-Verwaltung |
interfaceAiObjects.py |
AI-Call-Abstraction (Text, Embedding, Vision, Streaming) |
interfaceFeatures.py |
Feature-Instanz-Lifecycle, Template-Rollen-Kopie |
interfaceRbac.py |
RBAC-Regelauswertung |
3. ServiceCenter (Kern-Orchestrierung)
Das ServiceCenter ist die zentrale Schicht, die alle Services verbindet. Es wird pro Request/Session erstellt und propagiert einen ServiceCenterContext (context.py).
Services (serviceCenter/services/)
| Service | Pfad | Zweck |
|---|---|---|
serviceAgent |
mainServiceAgent.py (3400+ Zeilen) |
AI-Agent mit 30+ Tools (readFile, writeFile, searchInFileContent, browseContainer, summarizeContent, readContentObjects, webSearch, sendMail, etc.) |
serviceAi |
mainServiceAi.py (1700+ Zeilen) |
AI-Call-Gateway: Neutralisierung, Billing-Preflight, Provider-Selection, Streaming, Extraction, Generation |
serviceKnowledge |
mainServiceKnowledge.py |
Knowledge Store: Indexierung, Semantic Search, RAG-Kontext-Aufbau (buildAgentContext) |
serviceBilling |
Billing-Checks, Transaktionen | |
serviceChat |
Chat-Persistence | |
serviceExtraction |
Dokument-Extraktion (PDF, DOCX, XLSX...) | |
serviceGeneration |
Dokument-Generierung | |
serviceMessaging |
E-Mail, Notifications | |
serviceSubscription |
Subscription-Verwaltung | |
serviceWeb |
Web-Scraping |
ServiceCenterContext (context.py)
Propagiert pro Request:
userId,mandateId,featureInstanceIdrequireNeutralization: Optional[bool]— Chat-Level Neutralisierungsflag- Provider-Restrictions, Billing-Context
Agent-Tools (in mainServiceAgent.py)
Der Agent hat 30+ registrierte Tools. Tools liefern direkt Rohdaten — Neutralisierung erfolgt zentral im AI-Service (mainServiceAi.py) bevor Daten an ein AI-Modell gesendet werden.
Datenschutz-relevante DataSource-Tools:
_resolveDataSource()— liestneutralize-Flag der DataSource als 4. Tuple-Element_downloadFromDataSource()— vererbtneutralize-Flag auf erstellte FileItems_queryFeatureInstance()— setztrequireNeutralization=Trueauf Sub-Agent AI-Calls wenn FeatureDataSourceneutralize=True
4. Workflow-Engine
WorkflowManager (workflows/workflowManager.py, 1400+ Zeilen)
Zentrale Workflow-Steuerung für Automation und dynamische Workflows.
Methoden (workflows/methods/)
| Methode | Aktionen |
|---|---|
methodContext |
extractContent, neutralizeData, saveContent, transformContent |
methodAi |
AI-Analyse, Summarization, Prompt-Processing |
methodChatbot |
Chatbot-spezifische Aktionen |
methodSharepoint |
SharePoint-Integration |
methodOutlook |
Outlook/E-Mail-Integration |
methodJira |
Jira-Integration |
methodTrustee |
Trustee-Feature-Aktionen |
5. Neutralisierungs-System (KRITISCH)
Architektur, Prozess und Code-Karte (ein Dokument): wiki/compliance/Neutralisierung.md
Prinzip: Zentrales Gate — ALLE Daten, die an ein AI-Modell gehen, werden AUSSCHLIESSLICH in mainServiceAi.py neutralisiert.
Architektur: Einzige zentrale Stelle
Neutralisierung findet nur an einer einzigen Stelle statt: _shouldNeutralize() und _neutralizeRequest() in mainServiceAi.py. Kein anderer Service, kein Tool und kein Workflow prüft oder neutralisiert eigenständig. Failsafe: Wenn Neutralisierung erforderlich ist (requireNeutralization=True) und fehlschlägt, wird der AI-Call blockiert (RuntimeError).
Neutralisierungs-Trigger (Prioritätsreihenfolge)
- Per-Request:
AiCallRequest.requireNeutralization = True/False— expliziter Override - Chat-Level:
ServiceCenterContext.requireNeutralization = True— Session-Level-Flag - Mandate-Config:
NeutralizationConfig.enabled— mandantenweite Konfiguration
Was neutralisiert wird (in _neutralizeRequest)
request.prompt— Benutzer-Promptrequest.context— RAG-Kontext (externe Dokumente)request.messages— Chat-Nachrichten (OpenAI-Style)
Schlüssel-Dateien
| Datei | Rolle |
|---|---|
features/neutralization/serviceNeutralization/mainServiceNeutralization.py |
processText(text) → {neutralized_text, mappings}, resolveText(text) → Rehydrierung |
routes/routeDataFiles.py |
PATCH /{fileId}/neutralize — Toggle löscht Index synchron, re-indexiert im Background |
serviceAi/mainServiceAi.py |
Zentrales Gate: _shouldNeutralize() prüft Request → Context → Config; _neutralizeRequest() neutralisiert prompt, context, messages. Hard-Mode bei requireNeutralization=True |
serviceKnowledge/mainServiceKnowledge.py |
indexFile() neutralisiert bei FileItem.neutralize=True (Data-at-rest-Schutz). RAG-Chunks werden neutral gespeichert |
serviceAgent/mainServiceAgent.py |
_resolveDataSource() liest neutralize-Flag der DataSource. _downloadFromDataSource() vererbt Flag auf erstellte FileItems. _queryFeatureInstance() setzt requireNeutralization=True wenn FeatureDataSource neutralize-Flag gesetzt |
workflows/methods/methodContext/actions/neutralizeData.py |
Explizite Neutralisierungs-Aktion in Workflows (prüft nur Config, nicht Context-Flag) |
Failsafe-Kette
- Toggle ON: Index + Chunks werden synchron gelöscht → kein Leak bei Background-Re-Index-Fehler
- Indexierung:
indexFile()neutralisiert Chunks beiFileItem.neutralize=True→ Data-at-rest ist sicher - DataSource-Download: neutralize-Flag wird auf erstellte FileItems vererbt
- FeatureDataSource:
_queryFeatureInstance()setztrequireNeutralization=Trueauf Sub-Agent AI-Calls - AI-Calls (Zentrales Gate): Hard-Mode (
requireNeutralization=True) → Prompt-/Context-Fehler =RuntimeError(AI-Call blockiert), Message-Fehler = Message entfernt _rehydrateResponse()bleibt als Utility-Methode verfügbar, wird aber nicht mehr automatisch aufgerufen
NeutralizationPanel (Frontend)
frontend_nyla/src/pages/views/workspace/NeutralizationPanel.tsx — zeigt alle Files mit neutralize-Flag, deren Status und Platzhalter-Mappings. API: GET /api/workspace/{instanceId}/files → {files: [...]}.
6. Frontend-Architektur
Struktur (frontend_nyla/src/)
| Ordner | Inhalt |
|---|---|
pages/ |
Seiten: admin/, basedata/, billing/, settings/, views/ (workspace, commcoach, chatbot, trustee, automation) |
components/ |
Wiederverwendbar: FormGenerator, FolderTree, Navigation, UnifiedDataBar, Automation2FlowEditor, OnboardingAssistant |
hooks/ |
useApi, useFiles, useNavigation, useConfirm, usePrompt, useResizablePanels, etc. |
contexts/ |
FileContext, PekContext, ToastContext, WorkflowSelectionContext |
api/ |
API-Client (api.ts) und Feature-spezifische API-Module |
core/ |
PageManager |
layouts/ |
Layout-Komponenten |
locales/ |
i18n |
types/ |
TypeScript-Typen |
utils/ |
Utility-Funktionen |
Wichtige UI-Komponenten
| Komponente | Zweck |
|---|---|
UnifiedDataBar (UDB) |
Multi-Tab-Panel: Chats, Files, Sources — wird in Workspace und CommCoach genutzt |
FormGenerator |
Dynamische Formulare/Tabellen aus Backend-Attribut-Definitionen |
FolderTree |
Rekursiver Ordnerbaum mit Drag&Drop, Multi-Selection, Inline-Editing |
MandateNavigation |
Feature-Baum-Navigation mit Mandanten-Kontext |
Automation2FlowEditor |
n8n-style Flow-Builder für Automation2 |
WorkspacePage |
AI-Workspace mit Chat, UDB, Agent-Streaming |
UI-Regeln
- Keine Browser-Dialoge (alert/confirm/prompt) — stattdessen
useConfirm()undusePrompt()Hooks - Alle internen Funktionen mit
_Prefix - camelCase für Variablen und Funktionen
7. RBAC-System (Zwei getrennte Rollensysteme!)
Mandantenrollen
- Labels:
admin,user,viewer - Scope:
mandateId, keinfeatureCode/featureInstanceId - Junction:
UserMandateRole
Feature-Instanz-Rollen
- Labels:
workspace-admin,workspace-user,workspace-viewer, etc. - Scope:
mandateId+featureCode+featureInstanceId - Junction:
FeatureAccessRole
Strikte Regel: NIE eine Mandantenrolle einer FeatureAccessRole zuweisen oder umgekehrt.
8. Billing & Subscriptions
- Modell: PREPAY_MANDATE (kein PREPAY_USER)
- Billing-Check: Vor jedem AI-Call via
_preflightBillingCheckund_checkBillingBeforeAiCall - Datenvolumen:
assertCapacity("dataVolumeMB")prüft RAG-Index-Grösse - Trial: 5 CHF, Standard: 10 CHF/Monat
9. AI-Core (Provider-Abstraction)
Model-Registry (aicoreModelRegistry.py)
Registriert alle Provider-Plugins und deren Modelle dynamisch.
Model-Selector (aicoreModelSelector.py)
Wählt optimal basierend auf: Operation Type, Prompt-Grösse, Provider-Restrictions, Score-Ranking.
Provider-Plugins
aicorePluginAnthropic.py— Claude Sonnet/Haiku/OpusaicorePluginOpenai.py— GPT-4o, Embeddings (text-embedding-3-small/large), DALL-EaicorePluginMistral.py— Mistral Large/Small, Mistral EmbedaicorePluginPerplexity.py— Sonar/Sonar-ProaicorePluginTavily.py— Web-SearchaicorePluginPrivateLlm.py— Private LLMaicorePluginInternal.py— Interne Extraktoren/Generatoren/Renderer
Operation Types
dataExtract, dataAnalyse, agent, embedding, imageGeneration, vision, webSearch
10. Knowledge Store (RAG)
Datenmodelle (datamodelKnowledge.py)
FileContentIndex— Pro File: Struktur, Metadaten,isNeutralized,neutralizationStatus,totalObjects,totalSizeContentChunk— Semantische Chunks mit Embedding-Vektor,fileId,data,metadataRoundMemory— Kontext aus früheren Runden (file_ref, etc.)
Indexierung (serviceKnowledge.indexFile())
- Extraktion via
serviceExtraction - Optional: Neutralisierung via
serviceNeutralization.processText() - Chunking + Embedding
- Speicherung in
FileContentIndex+ContentChunk
RAG-Kontext (serviceKnowledge.buildAgentContext())
- Semantic Search via pgvector
- Context-Budget: Priorisierte Layer (File-Refs, Instance Docs, Mandate Docs)
- Neutralisierung erfolgt zentral im AI-Service wenn der RAG-Kontext als
request.contextan ein AI-Modell geht
11. Feature-Module
| Feature | Beschreibung |
|---|---|
workspace |
AI-Agent-Workspace mit Chat, Tools, RAG, Streaming |
automation |
Workflow-Automatisierung (v1) |
automation2 |
Flow-Editor n8n-Style (v2) |
chatbot |
Chatbot-Feature |
commcoach |
Kommunikations-Coach mit Voice, Dossier, UDB |
neutralization |
Datenneutralisierungs-Service und Config |
trustee |
Trustee/Treuhand-Feature (Buchhaltung, Positionen) |
realEstate |
Immobilien-Feature |
teamsbot |
MS Teams Bot |
12. Coding-Konventionen
- Alle internen Funktionen beginnen mit
_Prefix - camelCase für Variablen und Funktionsnamen (kein snake_case)
- Keine Browser-Dialoge —
useConfirm()/usePrompt()Hooks - Fehler propagieren — keine stillen Fallbacks bei kritischen Pfaden
- Pydantic-Models als einzige Quelle für UI-Feld-Definitionen
PowerOnModelals Basis mitsysCreatedAt,sysCreatedBy,sysModifiedAt,sysModifiedBy