Plugin-System
Plugin-System
Section titled “Plugin-System”FinAnalyzer verwendet ein modulares Plugin-System, das Built-in Plugins (im Lieferumfang enthalten) und externe Plugins (als JAR-Dateien nachinstallierbar) unterstützt.
Übersicht
Section titled “Übersicht”┌──────────────────────────────────────────────────┐│ FinAnalyzer Backend ││ ││ ┌─────────────┐ ┌──────────────────────────┐ ││ │ Plugin │ │ Built-in Plugins │ ││ │ Registry │◄──│ • CSV Import │ ││ │ Service │ │ • Google Sheets │ ││ │ │ │ • HBCI / FinTS │ ││ │ (DB sync, │ │ • Tink Open Banking │ ││ │ lifecycle)│ └──────────────────────────┘ ││ │ │ ││ │ │ ┌──────────────────────────┐ ││ │ │◄──│ External Plugins (PF4J) │ ││ │ │ │ • /data/plugins/*.jar │ ││ └─────────────┘ └──────────────────────────┘ ││ ││ ┌─────────────┐ ┌──────────────────────────┐ ││ │ Plugin │ │ Plugin Config │ ││ │ Admin API │ │ Service │ ││ │ (Admins) │ │ (pro User, JSON Schema) │ ││ └─────────────┘ └──────────────────────────┘ │└──────────────────────────────────────────────────┘Plugin-Typen
Section titled “Plugin-Typen”Built-in Plugins
Section titled “Built-in Plugins”Diese Plugins sind fest im Backend eingebaut und sofort verfügbar:
| Plugin | Kategorie | Beschreibung |
|---|---|---|
| CSV Import | Import | Banktransaktionen aus CSV-Dateien importieren |
| Google Sheets | Import | Transaktionen aus Google Sheets synchronisieren |
| HBCI / FinTS | Import | Direkter Bankzugang über das FinTS-Protokoll (deutsche Banken) |
| Tink Open Banking | Import | PSD2-konformer Bankzugang über die Tink-API (europaweit) |
Built-in Plugins werden beim Serverstart automatisch erkannt und registriert. Sie können von Admins aktiviert/deaktiviert werden.
Externe Plugins (PF4J)
Section titled “Externe Plugins (PF4J)”Externe Plugins werden als JAR-Dateien bereitgestellt und in das Plugin-Verzeichnis gelegt. Das Backend erkennt neue JARs automatisch zur Laufzeit (Hot-Reload) — kein Neustart nötig.
Plugin-Verzeichnis:
- All-in-One Image:
/data/plugins/ - Docker Compose (Prod/Dev): gemountet via
plugins-dataVolume - Lokale Entwicklung (IDE):
./plugins/relativ zum Backend-Arbeitsverzeichnis - Konfigurierbar via: Umgebungsvariable
FINANALYZER_PLUGINS_DIR
Plugin-Lebenszyklus
Section titled “Plugin-Lebenszyklus”Jedes Plugin durchläuft einen definierten Lebenszyklus — sowohl beim Serverstart als auch bei Hot-Reload (neue JARs zur Laufzeit):
Neu entdeckt: onInstall() → onLoad() → onEnable()Bereits bekannt: onLoad() → onEnable() (wenn ENABLED)Deaktiviert: onLoad() (kein onEnable)| Callback | Wann | Zweck |
|---|---|---|
onInstall() | Einmalig beim ersten Entdecken | Ersteinrichtung (z.B. Default-Konfiguration) |
onLoad() | Bei jedem Serverstart oder Hot-Reload | Ressourcen laden, Caches initialisieren |
onEnable() | Bei Start/Hot-Reload, wenn Plugin aktiv | Funktionalität aktivieren |
onDisable() | Wenn Admin das Plugin deaktiviert | Funktionalität deaktivieren, Ressourcen freigeben |
Fehlertoleranz: Wenn ein Plugin beim Start einen Fehler wirft, wird es übersprungen — alle anderen Plugins starten normal weiter.
Plugin-Status
Section titled “Plugin-Status”| Status | Bedeutung |
|---|---|
| INSTALLED | Entdeckt, aber noch nicht synchronisiert |
| ENABLED | Aktiv — Plugin-Funktionen stehen zur Verfügung |
| DISABLED | Deaktiviert durch Admin — Plugin wird geladen aber nicht aktiviert |
| ACTIVE | Wie ENABLED (Legacy-Kompatibilität) |
Konfiguration
Section titled “Konfiguration”Admin-Konfiguration (global)
Section titled “Admin-Konfiguration (global)”Admins können über die Admin-API Plugins aktivieren/deaktivieren:
GET /api/v1/admin/plugins → Alle Plugins mit StatusGET /api/v1/admin/plugins/{pluginId} → Plugin-DetailsPUT /api/v1/admin/plugins/{id}/status → {"enabled": true/false}Benutzer-Konfiguration (pro User)
Section titled “Benutzer-Konfiguration (pro User)”Jeder Benutzer kann Plugins individuell konfigurieren (z.B. API-Keys, Zugangsdaten):
GET /api/v1/plugins → Alle Plugins mit Config-StatusGET /api/v1/plugins/{pluginId}/config-schema → JSON Schema für Config-FormularGET /api/v1/plugins/{pluginId}/config → Aktuelle KonfigurationPUT /api/v1/plugins/{pluginId}/config → Konfiguration speichernDELETE /api/v1/plugins/{pluginId}/config → Konfiguration löschenGET /api/v1/plugins/configs → Alle eigenen KonfigurationenDie Konfiguration wird als JSON-Objekt gespeichert und gegen das Config-Schema des Plugins validiert. Sensible Felder (wie API-Keys) werden serverseitig verschlüsselt gespeichert.
Externe Plugins installieren
Section titled “Externe Plugins installieren”1. Plugin-JAR beschaffen
Section titled “1. Plugin-JAR beschaffen”Externe Plugins werden als .jar-Dateien verteilt. Achte auf:
- Kompatibilität: Das Plugin muss zur installierten FinAnalyzer-Version passen (Major-Version muss übereinstimmen)
- Vertrauenswürdigkeit: Plugins haben vollen Zugriff auf die Backend-Funktionalität — installiere nur Plugins aus vertrauenswürdigen Quellen
- Dateiformat: Die Datei muss eine
.jar-Endung haben und ein gültiges PF4J-Plugin sein
2. JAR in das Plugin-Verzeichnis kopieren
Section titled “2. JAR in das Plugin-Verzeichnis kopieren”Das Backend erkennt neue JARs automatisch per Hot-Reload — ein Neustart ist nicht nötig.
All-in-One Image:
# Plugin in den laufenden Container kopieren — wird automatisch erkanntdocker cp mein-plugin-1.0.0.jar finanalyzer:/data/plugins/Docker Compose (Prod/Dev):
# Plugin in das gemountete Volume kopieren — wird automatisch erkanntdocker cp mein-plugin-1.0.0.jar backend-prod:/app/plugins/Lokale Entwicklung (IDE — Backend läuft direkt):
# JAR in das plugins/-Verzeichnis im Backend-Root legen — wird automatisch erkanntcp mein-plugin-1.0.0.jar fin-analyzer-backend/plugins/Tipp: Falls du das Plugin in einen gestoppten Container/Volume platzierst, wird es beim nächsten Start geladen. Bei einem laufenden Container wird es per Hot-Reload innerhalb des nächsten Scan-Intervalls erkannt.
3. Plugin aktivieren
Section titled “3. Plugin aktivieren”Nach dem Platzieren der JAR-Datei wird das Plugin automatisch erkannt und als ENABLED registriert — kein Server-Neustart nötig. Das Backend scannt das Plugin-Verzeichnis regelmäßig auf neue JARs (Hot-Reload).
- Erster Scan nach Serverstart: nach 30 Sekunden (konfigurierbar via
FINANALYZER_PLUGINS_SCAN_INITIAL_DELAY_MS) - Danach: alle 10 Sekunden (konfigurierbar via
FINANALYZER_PLUGINS_SCAN_INTERVAL_MS)
Im Admin-Bereich der App ist das Plugin nach dem nächsten Scan sichtbar.
4. Plugin konfigurieren
Section titled “4. Plugin konfigurieren”Falls das Plugin eine Konfiguration benötigt (z.B. API-Schlüssel), öffne die Plugin-Einstellungen in der App und fülle das Konfigurationsformular aus.
Plugin entfernen
Section titled “Plugin entfernen”- Plugin über die Admin-API deaktivieren
- Container stoppen
- JAR-Datei aus dem Plugin-Verzeichnis löschen
- Container neu starten
Hinweis: Das Entfernen von Plugins erfordert derzeit einen Neustart. Das Hinzufügen neuer Plugins funktioniert ohne Neustart (Hot-Reload).
Fehlerbehebung
Section titled “Fehlerbehebung”| Problem | Ursache | Lösung |
|---|---|---|
| Plugin erscheint nicht nach Platzierung | JAR nicht im richtigen Verzeichnis | Prüfe docker exec <container> ls /app/plugins/ bzw. /data/plugins/ |
| Plugin erscheint nicht nach 30 Sekunden | JAR ist kein gültiges PF4J-Plugin | Prüfe Container-Logs: docker logs <container> | grep PF4J |
| Plugin erscheint, aber Status INSTALLED | Startup-Fehler im Plugin | Prüfe Container-Logs auf failed during startup lifecycle |
| Plugin-Konfiguration schlägt fehl | JSON entspricht nicht dem Schema | Prüfe das Config-Schema via /api/v1/plugins/{id}/config-schema |
| Plugins verschwinden nach Container-Update | Volume nicht gemountet | Stelle sicher, dass das plugins-data Volume korrekt gemountet ist |
Umgebungsvariablen
Section titled “Umgebungsvariablen”| Variable | Default | Beschreibung |
|---|---|---|
FINANALYZER_PLUGINS_DIR | plugins | Pfad zum Plugin-Verzeichnis (relativ oder absolut) |
FINANALYZER_PLUGINS_SCAN_INTERVAL_MS | 10000 | Hot-Reload Scan-Intervall in Millisekunden |
FINANALYZER_PLUGINS_SCAN_INITIAL_DELAY_MS | 30000 | Verzögerung vor dem ersten Scan (Startup abwarten) |
⚠ Hinweis: Wenn du
FINANALYZER_PLUGINS_DIRänderst, muss auch der Volume-Mount angepasst werden, damit die JARs im Container am richtigen Pfad liegen. Im All-in-One Image ist/data/plugins/Teil des/data-Volumes — eine Änderung erfordert einen zusätzlichen Volume-Mount.
Für Plugin-Entwickler
Section titled “Für Plugin-Entwickler”Externe Plugins implementieren das FinAnalyzerPlugin-Interface aus dem FinAnalyzer Plugin SDK (fin-analyzer-be-sdk). Plugins werden als PF4J-Plugins verpackt.
Voraussetzungen
Section titled “Voraussetzungen”- Java/Kotlin 21
- Zugang zum
fin-analyzer-be-sdkMaven-Artefakt (Gitea Registry oder lokal viamvn install)
Plugin-Aufbau
Section titled “Plugin-Aufbau”- Dependency:
fin-analyzer-be-sdkalsprovided-Dependency (wird zur Laufzeit vom Backend bereitgestellt) - Interface:
FinAnalyzerPluginimplementieren — definiert:pluginId— Eindeutige ID (z.B.my-custom-import)pluginName,pluginDescription,pluginVersion,pluginAuthorpluginCategory—IMPORT,EXPORT, oderUTILITYconfigSchema—ConnectorConfigSchemamitConfigField-Liste (definiert das Konfigurationsformular)- Lifecycle-Hooks:
onInstall(),onLoad(),onEnable(),onDisable()
- Extension Point:
@ExtensionAnnotation (PF4J) auf der Plugin-Klasse für automatische Erkennung - Packaging: Fat JAR mit PF4J Plugin-Manifest (
plugin.propertiesoderMETA-INF/extensions.idx)
Lokales Testen
Section titled “Lokales Testen”# 1. SDK lokal installieren (falls nicht aus Registry verfügbar)cd fin-analyzer-be-sdk./mvnw install -DskipTests
# 2. Plugin bauencd mein-plugin/./mvnw package -DskipTests
# 3a. IDE-Modus: JAR ins plugins/-Verzeichnis des Backends legencp target/mein-plugin-1.0.0.jar ../fin-analyzer-backend/plugins/# Hot-Reload erkennt das Plugin automatisch — kein Neustart nötig
# 3b. Docker-Modus: JAR ins Volume kopierendocker cp target/mein-plugin-1.0.0.jar finanalyzer-local:/app/plugins/# Hot-Reload erkennt das Plugin automatisch — kein Neustart nötigWichtige Regeln
Section titled “Wichtige Regeln”- Plugin-IDs müssen global eindeutig sein — Duplikate verursachen einen Startup-Fehler
- Lifecycle-Hooks dürfen nicht blockieren — lang laufende Initialisierung asynchron auslagern
- Fehler in Hooks werden isoliert — ein fehlerhaftes Plugin blockiert nicht den Rest
- Config-Schema-Validierung ist automatisch — ungültige User-Konfigurationen werden vom Backend abgelehnt
- SECRET-Felder werden verschlüsselt gespeichert — verwende
ConfigFieldType.SECRETfür API-Keys und Passwörter
Detaillierte SDK-Dokumentation: siehe fin-analyzer-be-sdk/README.md.