# Firefly Import Preprocessor — Dokumentation **Version:** 1.0.0 **Datum:** 03. Mai 2026 **Status:** Production Ready 🌐 [English](README.md) --- ## 📋 Inhaltsverzeichnis 1. [Überblick](#überblick) 2. [Installation & Setup](#installation--setup) 3. [Schnellstart](#schnellstart) 4. [Konfiguration](#konfiguration) 5. [Transformationstypen](#transformationstypen) 6. [CLI-Referenz](#cli-referenz) 7. [Debug-Modus](#debug-modus) 8. [Firefly III Integration](#firefly-iii-integration) 9. [Architektur](#architektur) 10. [Fehlerbehandlung](#fehlerbehandlung) --- ## Überblick Der **Firefly Import Preprocessor** ist ein produktionsreifer PHP-Preprocessor für Banken-CSV-Exportdateien. Er transformiert Bankdaten in ein standardisiertes Format und kann sie optional in Firefly III importieren. ### Kernfeatures ✅ **Vollständige CSV-Transformation** mit komplexen Pipelines ✅ **Metadaten-Extraktion** mit Regex (IBAN, Währung, Kontoname) ✅ **13 Transformationstypen** für flexible Datenverarbeitung ✅ **Firefly III Integration** — CLI, Docker und HTTP-Upload ✅ **Debug-Modus** für Transparenz bei Verarbeitung ✅ **Production Ready** mit vollständiger Fehlerbehandlung ✅ **Zero Dependencies** für Core-Funktionalität ### Workflow ```text Input CSV ↓ Metadaten extrahieren (Regex) ↓ Datenzeilen transformieren (Pipeline) ↓ Output CSV schreiben ↓ [Optional] In Firefly III importieren ``` --- ## Installation & Setup ### Voraussetzungen - PHP 8.1+ - Composer (empfohlen) - [Optional] Docker für Firefly III Integration ### Installation ```bash # 1. Repository clonen/kopieren cd ff-imp-preprocessor # 2. Abhängigkeiten installieren (optional) composer install # 3. Konfiguration erstellen cp config/config.example.json config/config.json # Bearbeite config/config.json mit deinen Einstellungen # 4. Directories erstellen mkdir -p config/import/{source,output,archive,error} chmod 755 config/import/{source,output,archive,error} # 5. Test durchführen php bin/transformer.php validate config/config.json input.csv ``` --- ## Schnellstart ### 1. Konfiguration anpassen Bearbeite `config/config.json` und stelle sicher, dass die Extraction-Rules zu deinem CSV-Format passen: ```json { "metadata": { "extractionRules": [ { "name": "account_iban", "lineNumber": 2, "regex": "IBAN:\\s*([A-Z0-9 ]+)", "captureGroup": 1 } ] }, "csvStructure": { "headerLine": 5, "delimiter": ";", "encoding": "UTF-8" } } ``` ### 2. CSV validieren ```bash php bin/transformer.php validate config/config.json input.csv ``` ### 3. Transformation durchführen ```bash php bin/transformer.php transform input.csv config/config.json # Mit Debug-Modus für Fehlersuche php bin/transformer.php transform input.csv config/config.json --debug ``` ### 4. Output prüfen ```bash php bin/transformer.php test input.csv config/config.json --debug # Zeigt max. 10 transformierte Zeilen und Debug-Logs ``` --- ## Konfiguration ### config.json Struktur #### `metadata` - Metadaten-Extraktion ```json { "metadata": { "extractionRules": [ { "name": "account_iban", "lineNumber": 2, "regex": "IBAN:\\s*([A-Z0-9 ]+)", "captureGroup": 1 }, { "name": "currency_code", "lineNumber": 3, "regex": "Währung:\\s*([A-Z]{3})", "captureGroup": 1 } ] } } ``` | Feld | Typ | Beschreibung | | ------ | ----- | ------------- | | `name` | string | Name der Metadaten-Variable (verwendet in constantvalue) | | `lineNumber` | int | Zeilennummer in CSV (1-basiert, menschenlesbar) | | `regex` | string | Regex-Pattern zur Extraktion (ohne Delimiter) | | `captureGroup` | int | Nummer der Klammer-Gruppe (0=komplett, 1=erste Klammer, etc.) | **Beispiel Regex:** - Pattern: `IBAN:\s*([A-Z0-9 ]+)` - Input: `IBAN: CH93 0077 2020 6262 5252 7` - Capture Group 1: `CH93 0077 2020 6262 5252 7` #### `csvStructure` - CSV-Format ```json { "csvStructure": { "headerLine": 5, "delimiter": ";", "encoding": "UTF-8", "hasBom": false } } ``` | Feld | Typ | Default | Beschreibung | | ------ | ----- | --------- | ------------- | | `headerLine` | int | 5 | Zeilennummer der Header (1-basiert) | | `delimiter` | string | `;` | CSV-Delimiter | | `encoding` | string | `UTF-8` | Zeichenkodierung (UTF-8, ISO-8859-1, CP1252) | | `hasBom` | bool | false | Hat die Datei BOM (Byte Order Mark)? | #### `columnTransformations` - Spalten-Transformationen ```json { "columnTransformations": [ { "sourceColumn": "Buchungsdatum", "transformations": [ { "type": "dateformat", "fromFormat": "d.m.Y", "toFormat": "Y-m-d" } ], "outputColumn": "date", "outputAction": "overwrite" } ] } ``` **outputAction:** - `overwrite` — Überschreibe sourceColumn - `create` — Erstelle neue Spalte (für Regex-Extract, Split, etc.) #### `directories` - Dateisystem ```json { "directories": { "source": "/opt/ff-imp-preprocessor/import/source", "output": "/opt/ff-imp-preprocessor/import/output", "archive": "/opt/ff-imp-preprocessor/import/archive", "error": "/opt/ff-imp-preprocessor/import/error" } } ``` | Feld | Beschreibung | | ------ | ------------- | | `source` | Eingabe-Verzeichnis | | `output` | Ausgabe-Verzeichnis | | `archive` | Archiv für verarbeitete Dateien | | `error` | Error-Verzeichnis für ungültige Dateien | #### `fireflyImport` - Firefly III Integration Der Betriebsmodus wird über das Feld `mode` gesteuert. Mögliche Werte: `cli`, `docker`, `http`. Details und vollständige Konfigurationsbeispiele: [Firefly III Integration](#firefly-iii-integration). ```json { "fireflyImport": { "mode": "docker", "jsonConfig": "/import/configs/ubs-import.json", "importerCommand": "docker exec firefly-importer php artisan importer:import", "autoImport": false, "deleteAfterImport": false, "timeout": 300 } } ``` | Feld | Typ | Beschreibung | | --- | --- | --- | | `mode` | String | Betriebsmodus: `cli` \| `docker` \| `http` (Standard: `cli`) | | `jsonConfig` | String | Pfad zur Firefly III Data Importer JSON-Konfigurationsdatei (Format v3) | | `importerCommand` | String | Vollständiges CLI-Kommando *(Modi: cli, docker)* | | `importerUrl` | String | URL des Data Importers *(Modus: http)* | | `importerSecret` | String | `AUTO_IMPORT_SECRET` des Importers (mind. 16 Zeichen) *(Modus: http)* | | `autoImport` | Boolean | Import direkt nach Transformation ausführen | | `deleteAfterImport` | Boolean | Transformierte CSV nach erfolgreichem Import löschen | | `timeout` | Integer | Timeout in Sekunden (Standard: 300) | | `environment` | Object | Zusätzliche Umgebungsvariablen *(Modi: cli, docker)* | --- ## Transformationstypen Es gibt **13 unterstützte Transformationstypen**, die als Pipeline kombiniert werden können: ### 1. **trim** - Leerzeichen entfernen ```json { "type": "trim" } ``` - Input: ` Coop Pronto ` → Output: `Coop Pronto` --- ### 2. **lowercase** - Zu Kleinbuchstaben ```json { "type": "lowercase" } ``` - Input: `COOP PRONTO CHUR` → Output: `coop pronto chur` --- ### 3. **uppercase** - Zu Grossbuchstaben ```json { "type": "uppercase" } ``` - Input: `Coop Pronto Chur` → Output: `COOP PRONTO CHUR` --- ### 4. **ucwordsfirst** - Grossschreibung nach Trennzeichen ```json { "type": "ucwordsfirst" } ``` - `COOP PRONTO CHUR` → `Coop Pronto Chur` - `migros-rail city` → `Migros-Rail City` - `O'NEILL STORE` → `O'Neill Store` Trennzeichen: Leerzeichen, Bindestrich, Apostroph, Slash, Punkt, Komma, Semikolon, Doppelpunkt, Klammern. --- ### 5. **replace** - String-Replacement ```json { "type": "replace", "search": " ", "replace": " " } ``` - Input: `Coop Pronto` → Output: `Coop Pronto` --- ### 6. **split** - Spalte teilen ```json { "type": "split", "delimiter": ";", "part": 0 } ``` - Input: `Coop Pronto Chur;7007 Chur` → Output: `Coop Pronto Chur` --- ### 7. **regex** - Regex-Ersetzung ```json { "type": "regex", "pattern": "^(.*?);.*$", "replace": "$1" } ``` - Kein Match → Originalwert bleibt **unverändert** (pipeline-sicher) --- ### 8. **regexextract** - Regex-Extraktion ```json { "type": "regexextract", "pattern": "(\\d{4,} [^;]+)" } ``` - Kein Match → leerer String (**nicht** pipeline-sicher) --- ### 9. **dateformat** - Datum-Umformat ```json { "type": "dateformat", "fromFormat": "d.m.Y", "toFormat": "Y-m-d" } ``` - Input: `10.12.2025` → Output: `2025-12-10` --- ### 10. **truncate** - String kürzen ```json { "type": "truncate", "maxLength": 100 } ``` --- ### 11. **constantvalue** - Konstanten-Wert aus Metadaten ```json { "sourceColumn": "_constant_", "transformations": [{ "type": "constantvalue", "metadataKey": "account_iban" }], "outputColumn": "account_iban", "outputAction": "create" } ``` --- ### 12. **map** - Spalte kopieren ```json { "type": "map" } ``` --- ### 13. **pipeline** - Verschachtelte Pipeline ```json { "type": "pipeline", "steps": [ { "type": "trim" }, { "type": "lowercase" }, { "type": "ucwordsfirst" } ] } ``` --- ### Pipeline-Beispiel ```json { "sourceColumn": "Buchungstext", "transformations": [ { "type": "trim" }, { "type": "replace", "search": " ", "replace": " " }, { "type": "lowercase" }, { "type": "ucwordsfirst" } ], "outputColumn": "description", "outputAction": "overwrite" } ``` **Verarbeitung:** 1. `" COOP PRONTO "` → trim → `"COOP PRONTO"` 2. `"COOP PRONTO"` → replace → `"COOP PRONTO"` 3. `"COOP PRONTO"` → lowercase → `"coop pronto"` 4. `"coop pronto"` → ucwordsfirst → `"Coop Pronto"` --- ## CLI-Referenz ```bash php bin/transformer.php [input] [config] [options] ``` ### Kommandos | Kommando | Beschreibung | | -------- | ------------- | | `test` | Test-Run (max. 10 Zeilen) | | `transform` | Vollständige Transformation | | `validate` | Konfiguration validieren | | `auto-import` | Verzeichnis-Überwachung | | `help` | Hilfe anzeigen | ### Optionen | Option | Beschreibung | | -------- | ------------- | | `--debug`, `-d` | Debug-Modus aktivieren | | `--rows=N` | Max. N Zeilen (test-Kommando) | | `--output=FILE`, `-o` | Output-Pfad | | `--strict` | Strikte Validierung | | `--watch` | Kontinuierliche Überwachung | | `--interval=SEC` | Prüfintervall in Sekunden | | `--dry-run` | Simulationsmodus | --- ## Debug-Modus ```bash php bin/transformer.php test input.csv config/config.json --debug ``` Der Debug-Modus protokolliert Ereignisse in folgenden Kategorien: | Kategorie | Wann | | ----------- | ------ | | `transformer` | Anfang/Ende Transformation | | `csv_reader` | Beim CSV lesen | | `metadata` | Bei Metadaten-Extraktion | | `metadata_warning` | Bei Problemen | | `transformation` | Bei jeder Transformation | | `csv_writer` | Beim CSV schreiben | --- ## Firefly III Integration Drei Betriebsmodi decken alle typischen Deployment-Szenarien ab. ### Modus `cli` Transformer und Importer auf demselben Server. ```json "fireflyImport": { "mode": "cli", "jsonConfig": "/opt/firefly-data-importer/storage/configurations/ubs-import.json", "importerCommand": "php /opt/firefly-data-importer/artisan importer:import", "autoImport": true, "timeout": 300, "environment": { "FIREFLY_III_URL": "https://localhost", "FIREFLY_III_ACCESS_TOKEN": "your-token-here" } } ``` ### Modus `docker` Transformer lokal, Importer in Docker. Das Ausgabeverzeichnis muss als Volume eingebunden sein. `jsonConfig` ist der Pfad **innerhalb des Containers**. ```json "fireflyImport": { "mode": "docker", "jsonConfig": "/import/configs/ubs-import.json", "importerCommand": "docker exec firefly-importer php artisan importer:import", "autoImport": true, "timeout": 300 } ``` ### Modus `http` Transformer lokal, Importer über HTTP(S) erreichbar. Benötigt `ext-curl`. **Voraussetzungen auf dem Importer-Server:** ```text CAN_POST_FILES=true AUTO_IMPORT_SECRET= # mindestens 16 Zeichen ``` ```json "fireflyImport": { "mode": "http", "importerUrl": "https://importer.your-server.com", "importerSecret": "your-auto-import-secret-min-16-chars", "jsonConfig": "/local/path/to/ubs-import.json", "autoImport": true, "timeout": 300 } ``` --- ## Architektur ```text bin/transformer.php (CLI Entry Point) ↓ TransformerEngine (Orchestrierung) ├─ ConfigurationLoader (Config laden/validieren) ├─ CsvReader (CSV einlesen) ├─ MetadataExtractor (Metadaten mit Regex) ├─ ColumnTransformer (Transformationen anwenden) ├─ CsvWriter (CSV schreiben) ├─ FireflyImporter (Firefly III Integration) └─ DebugLogger (Debug-Protokolle) ``` | Klasse | Verantwortung | | -------- | --------------- | | `TransformerEngine` | Orchestriert gesamten Workflow | | `ConfigurationLoader` | Lädt und validiert JSON-Konfiguration | | `CsvReader` | Liest CSV mit Metadaten | | `MetadataExtractor` | Extrahiert Metadaten mit Regex | | `ColumnTransformer` | Transformiert Spalten (Pipeline) | | `CsvWriter` | Schreibt CSV | | `FireflyImporter` | Importiert in Firefly III | | `DebugLogger` | Statischer Logger für Debug | --- ## Fehlerbehandlung ### Häufige Fehler #### "Input file not found" ```bash # Prüfe Dateipfad ls -la input.csv # Nutze absoluten Pfad wenn relativ nicht funktioniert php bin/transformer.php transform /absolute/path/input.csv config.json ``` #### "Missing metadata: account_iban" ```bash # Prüfe erste Zeilen des CSV head -5 input.csv # Überprüfe lineNumber und regex in config.json php bin/transformer.php validate config.json input.csv --debug ``` #### "Invalid JSON" ```bash php -r "json_decode(file_get_contents('config/config.json'), true) or die('JSON invalid');" ``` #### "Configuration: 'csvStructure.headerLine' required" ```bash diff config/config.json config/config.example.json ``` --- ## Version & Änderungen **v1.0.0 (03. Mai 2026)** - ✅ Initial Release - ✅ 13 Transformationstypen - ✅ Metadaten-Extraktion mit Regex - ✅ Debug-Modus - ✅ Firefly III Integration (cli / docker / http) - ✅ Vollständige Dokumentation --- **Lizenz:** GPL-3.0 **Author:** PHP CSV Transformer Project **Repository:** [git.andare.ch/david.reindl/ff-imp-preprocessor](https://git.andare.ch/david.reindl/ff-imp-preprocessor)