13 KiB
Gateway -- Architektur
Überblick
Das Gateway ist das Python-Backend der PowerOn-Plattform (FastAPI, PostgreSQL). Es kapselt Mandanten- und Feature-Logik hinter einer REST-API und folgt einer klaren Schichtenfolge: Connectors sprechen externe Systeme und Datenbanken an, Interfaces normalisieren Zugriffe und DTOs, Services bündeln fachliche Operationen darauf, und das ServiceCenter löst diese Services pro Request mit einheitlichem Kontext auf. Routen in modules/routes/ sind der HTTP-Einstieg; Security-Middleware und gemeinsame Utilities liegen in modules/security/ bzw. modules/shared/. Feature-spezifische Domänen leben in modules/features/ als weitgehend autonome Module.
Modulstruktur
Unter gateway/modules/ (Kontext-Audit):
| Modul | Zweck |
|---|---|
aicore/ |
Model-Registry, Model-Selector, Provider-Plugins (Anthropic, OpenAI, Mistral, Perplexity, Tavily, PrivateLLM) |
auth/ |
Authentifizierung, CSRF, Token-Refresh-Middleware, JWT |
connectors/ |
DB-Connector (PostgreSQL), Provider-Subpakete (Microsoft, Google, ClickUp, FTP), Ticket/Messaging/Geo-Konnektoren |
datamodels/ |
Pydantic-Datenmodelle (u. a. Ai, Billing, Chat, Content, Files, Knowledge, Rbac, Subscription, UiLanguage, Workflow) |
features/ |
Feature-Module (autonome Domänen): workspace, graphicalEditor, chatbot, commcoach, neutralization, realEstate, trustee, teamsbot |
interfaces/ |
DB-Interfaces (App, Billing, Chat, Knowledge, Management, Subscription), AI-Objects, RBAC, Features, Messaging |
migration/ |
Daten-Migrationen |
routes/ |
REST-API-Routen (u. a. Admin, Billing, DataFiles, DataSources, i18n, Security, Store, System) |
security/ |
RBAC (rbac.py, rbacCatalog.py), Root-Access |
serviceCenter/ |
Zentrale Service-Orchestrierung (Registry, Resolver, Kontext, Haupt-Services) |
serviceHub/ |
Service-Registry und Dependency Injection (u. a. PublicService-Wrapper) |
shared/ |
Gemeinsame Utilities (attributeUtils, i18nRegistry, Konfiguration, Logging, …) |
system/ |
System-Konfiguration, Feature-Discovery (registry.py: loadFeatureMainModules, loadFeatureRouters) |
workflows/ |
Workflow-Engine mit Methoden, Aktionen, Execution Engine und konsolidiertem Scheduler |
ServiceCenter (Kern-Orchestrierung)
Das ServiceCenter ist die zentrale Schicht, die Kern- und importierbare Services verbindet. Pro Request/Session wird ein ServiceCenterContext (serviceCenter/context.py) mitgeführt und propagiert u. a.:
user: User(gesamtes User-Objekt),mandateId,featureInstanceIdworkflow_id,workflow,feature_coderequireNeutralization(optional) — Neutralisierungsflag auf Chat-Ebene
Die öffentliche API umfasst u. a. getService(key, context) zur Auflösung einer Service-Instanz; registrierte Services sind in registry.py als CORE_SERVICES und IMPORTABLE_SERVICES hinterlegt, mit feature-spezifischer Auflösung und optionaler Vorabladung (preWarm).
Services (serviceCenter/services/)
| Service | Hauptmodul (Auszug) | Zweck |
|---|---|---|
serviceAgent |
mainServiceAgent.py |
AI-Agent mit vielen Tools (u. a. Dateien, Suche, Container, Web, Mail) |
serviceAi |
mainServiceAi.py |
AI-Call-Gateway: Neutralisierung, Billing-Preflight, Provider-Auswahl, Streaming, Extraktion, Generierung |
serviceKnowledge |
mainServiceKnowledge.py |
Knowledge Store: Indexierung, semantische Suche, RAG-Kontext (buildAgentContext) |
serviceBilling |
mainServiceBilling.py |
Billing-Checks, Transaktionen |
serviceChat |
mainServiceChat.py |
Chat-Persistenz |
serviceExtraction |
mainServiceExtraction.py |
Dokument-Extraktion (PDF, DOCX, XLSX, …) |
serviceGeneration |
mainServiceGeneration.py |
Dokument-Generierung |
serviceMessaging |
mainServiceMessaging.py |
E-Mail, Notifications |
serviceSubscription |
mainServiceSubscription.py |
Subscription-Verwaltung |
serviceWeb |
mainServiceWeb.py |
Web-Scraping |
Hinweis (Agent): Agent-Tools liefern Rohdaten; Neutralisierung vor dem Versand an ein Sprachmodell erfolgt zentral im serviceAi (mainServiceAi.py), nicht in den Tools selbst.
Einordnung (Framework)
Daten- und Steuerfluss: Client oder Workflow → Service Center → Service → Interface → Connector → externes System. Das Service Center bündelt dabei Erkennbarkeit (Registry), Konfiguration und querschnittliche Aspekte wie Logging, RBAC-Objekt-Registrierung (registerServiceObjects) und konsistente Service-Lebenszyklen; serviceHub ergänzt dies mit PublicService, sodass nur bewusst exponierte Methoden nach außen sichtbar sind.
Interfaces (DB-Schicht)
Die genannten Module kapseln die Datenbankzugriffe bzw. die zugehörigen Fachverträge (Audit-Liste):
| 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), UiLanguageSet-Seeding |
interfaceDbSubscription.py |
Subscription-Verwaltung |
interfaceAiObjects.py |
AI-Call-Abstraktion (Text, Embedding, Vision, Streaming) |
interfaceFeatures.py |
Feature-Instanz-Lifecycle, Template-Rollen-Kopie |
interfaceRbac.py |
RBAC-Regelauswertung |
Weitere Interface-Dateien im Ordner (z. B. Voice, Tickets, Messaging, Bootstrap) erfüllen dieselbe Normalisierungsrolle gegenüber Connectors bzw. externen APIs; die Tabelle oben entspricht der expliziten DB-/Kern-Zuordnung aus dem Kontext-Audit.
Schlüssel-Dateien
| Datei / Pfad | Rolle |
|---|---|
gateway/app.py |
FastAPI-Anwendung (generischer Entry-Point), Routen, Middleware, EventManager, Scheduler-MainLoop |
gateway/modules/serviceCenter/__init__.py |
Service Center: getService, preWarm, RBAC-Registrierung für Service-Objekte |
gateway/modules/serviceCenter/context.py |
ServiceCenterContext pro Request |
gateway/modules/serviceCenter/registry.py |
Service-Registry (CORE / IMPORTABLE) |
gateway/modules/serviceCenter/resolver.py |
Auflösung von Service-Instanzen inkl. Cache |
gateway/modules/serviceHub/__init__.py |
Hub / DI, PublicService-Wrapper für kontrollierte Oberflächen |
gateway/modules/routes/*.py |
HTTP-Endpunkte, Aufruf in Richtung Service Center / Features (inkl. routeI18n.py für DB-backed i18n mit AI-Übersetzung) |
gateway/modules/interfaces/*.py |
Stabile Verträge und DB-Zugriffe (keine direkte Vendor-Logik in Services) |
gateway/modules/connectors/*.py |
Vendor-spezifische Adapter (Auth, Transport, Mapping) |
gateway/modules/security/* |
RBAC-Auswertung, RBAC-Katalog, Root-Access |
gateway/modules/auth/* |
CSRF, Token-Refresh-Middleware, JWT, OAuth |
gateway/modules/shared/* |
Querschnitt: Konfiguration, Audit-Logging, Events, Utilities |
gateway/modules/system/registry.py |
Feature-Discovery, Router-Laden, Katalog-Registrierung beim App-Start |
gateway/modules/workflows/workflowManager.py |
Zentrale Workflow-Steuerung (Workspace/Chat Workflows) |
gateway/modules/workflows/automation2/executionEngine.py |
Graph-Execution-Engine: topoSort, Transit-Routing, _normalizeToSchema nach Execute, flow.merge-Wait, Resume-Schema-Validierung |
gateway/modules/workflows/scheduler/mainScheduler.py |
Konsolidierter Workflow-Scheduler |
gateway/modules/interfaces/interfaceBootstrap.py |
System-Bootstrap (Templates, Billing, Stripe) |
i18n (Mehrsprachigkeit)
Das Gateway nutzt ein DB-basiertes Sprachsystem (UiLanguageSet). Alle UI-sichtbaren Texte (HTTPException-Details, Model-Labels, API-Messages) werden ueber t() getaggt und per AI uebersetzt.
| Komponente | Datei | Zweck |
|---|---|---|
i18nRegistry.py |
modules/shared/ |
t(), resolveText(), @i18nModel Decorator, _REGISTRY, _CACHE, _setLanguage, Boot-Sync |
attributeUtils.py |
modules/shared/ |
getModelLabels() / getModelLabel() lesen aus i18nRegistry.MODEL_LABELS, nutzen resolveText() |
routeI18n.py |
modules/routes/ |
Admin-API: Sprachset-CRUD, AI-Uebersetzung, xx-Sync, TextMultilingual-Batch-Uebersetzung |
app.py |
gateway/ |
Boot-Hooks (_syncRegistryToDb, _loadCache), Request-Middleware (_setLanguage) |
Architektur-Regeln
t()NUR mit String-Literalen:t("Speichern")ist korrekt,t(variable)ist verboten. Jeder i18n-Key muss als Literal im Code stehen, damit er beim Import registriert wird.- Backend uebersetzt, Frontend rendert: Das Backend liefert uebersetzte Strings via API. Das Frontend ruft
t()nur fuer eigene statische UI-Texte auf, nie fuer Werte die vom Backend kommen. - Fallback
[key]: Wenn eine Uebersetzung fehlt, gibtt()[key]zurueck (z.B.[Speichern]), damit fehlende Uebersetzungen im UI sofort sichtbar sind. - Keine lokalen Resolve-Helfer: Alle Label-Aufloesung laeuft ueber
resolveText()(zentral ini18nRegistry.py). Keine_resolveLabel(),_resolveTextMultilingual(),_storeLabelText()etc. in Route-Dateien.
Zentrale Funktionen
t(key: str) -> str — Tag + Translate:
- Bei Import: registriert Key in
_REGISTRY - Bei Runtime: liefert
_CACHE[lang][key], Fallback[key] - Sprache kommt aus
_CURRENT_LANGUAGEContextVar (gesetzt durch Middleware)
resolveText(value: Any, lang: Optional[str] = None) -> str — Universelle Label-Aufloesung:
str→t(value)(behandelt als i18n-Key)dict→ Nutzersprache aus Kontext (oderlangwenn gesetzt), dannxx, dann erster nicht-leerer Wert (keine eckigen Klammern — das ist Inhalt, kein fehlender UI-Key)TextMultilingual→model_dump()dann dict-LogikNone→""
Boot-Reihenfolge
- Module laden →
@i18nModelDecorators +t()-Aufrufe registrieren Keys in_REGISTRY _syncRegistryToDb():- Scannt Route-Dateien nach
routeApiMsg("…")(api.* Keys) _registerNavLabels(): Navigation-Labels ausNAVIGATION_SECTIONS(nav.* Keys)_registerFeatureUiLabels():FEATURE_LABELundUI_OBJECTSLabels (nav.* Keys)_registerRbacLabels():DATA_OBJECTS,RESOURCE_OBJECTS,TEMPLATE_ROLES,QUICK_ACTIONSLabels (rbac.data, rbac.resource, rbac.role, rbac.quickaction Keys)- Merged Gateway-Keys ins xx-Basisset (UI-Keys bleiben erhalten)
- Scannt Route-Dateien nach
_loadCache(): Laedt alleUiLanguageSetsin den In-Memory-Cache (_CACHE)
Request-Flow
Middleware setzt _setLanguage(lang) aus Accept-Language Header → t("Key") liefert Uebersetzung aus _CACHE[lang] (O(1) Dict-Lookup, kein DB-Call). resolveText() nutzt denselben Mechanismus.
TextMultilingual
Felder vom Typ TextMultilingual speichern Benutzertexte mehrsprachig. xx ist das Pflichtfeld (Quelltext/Deutsch), weitere Sprachen werden dynamisch als Extra-Felder gespeichert. Bei neuer Sprache werden alle TextMultilingual-Felder per Batch-Job automatisch uebersetzt (routeI18n._translateTextMultilingualFields). On-Demand: POST /api/i18n/translate-field.
Context-Namensraeume
ui (Frontend), api.<routeModuleName> (HTTPExceptions), table.<ClassName> (Model-Labels), table.<ClassName>.<fieldName> (Feld-Labels), nav (Navigation/Feature-Labels), rbac.data / rbac.resource / rbac.role / rbac.quickaction (RBAC-Katalog)
Entries-Identitaet: Ein Entry wird durch (key, context) eindeutig identifiziert — derselbe Text kann mit verschiedenen Contexts existieren.
Regeln / Invarianten
- Schichten: Connectors sind anbieterspezifisch und ersetzbar; Services hängen von Interfaces ab, nicht direkt von Connectors. Geschäftslogik und Guardrails liegen in den Services.
- Datenbank: Persistenz und die genannten Domänen-Reads/Writes laufen über die Interface-Schicht, nicht ad hoc aus Routen heraus.
- Service Center: Aufrufe laufen über die zentrale Auflösung (
getService+ Kontext); Workflows und Routen konsumieren dieselbe Landschaft. - Sicherheit & Governance: RBAC und Geheimnisse werden zentral geführt; Service-Aufrufe und Workflow-Schritte sollen nachvollziehbar sein (Audit); Kontingente und Limits pro Mandant/Service sind vorgesehen.
- HTTP-Einstieg: Globale Middleware (CSRF, Token-Refresh unter
modules/auth/); RBAC-Auswertung und Katalog untermodules/security/. - Code-Konventionen (Projekt): Interne Hilfsfunktionen mit Präfix
_; Bezeichner in camelCase für Variablen und Funktionen.