Files
gala-ki-spielwiese/workflow_dateieingang.md

157 lines
8.5 KiB
Markdown
Raw Normal View History

# Workflow: Automatischer Dateieingang — SFTP → OCI Object Storage → DB
**Stand:** 2026-04-08
---
## Beteiligte Systeme
| System | Rolle |
|---|---|
| **SFTP-Server** | Quelle — externer Lieferant legt ZIP-Dateien ab |
| **Dateieingang Service** | Middleware (Quarkus) — holt ZIP, entpackt, lädt Dateien + Marker in OCI hoch |
| **OCI Object Storage** | Zwischenspeicher — Eingangsordner, Zielordner nach Verarbeitung |
| **Oracle DB / APEX** | Verarbeitung — liest Dateien aus OCI, importiert Daten |
Details zum Dateieingang Service: `quarkus-automaton/docs/Architecture.md`
Details zur DB-Verarbeitung: `database/docs/plan_pck_net_storage.md`
---
## Ablauf
```
┌─────────────────────────────────────────────────────────────────┐
│ APEX Automation (stündlich) │
│ → pck_auto_import.p_run_ba_korrespondenz_dateieingang_automation │
│ │
│ 1. p_process_incoming_ba_data aufrufen │
│ → OCI-Batches mit Marker verarbeiten (Fallback: ORDS-Aufruf │
│ im letzten Quarkus-Lauf fehlgeschlagen) │
│ │
│ 2. Dateieingang Service aufrufen (fire & forget) │
│ HTTP POST /api/process-incoming (Header: X-Api-Key) │
└────────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Dateieingang Service (Quarkus, läuft im Hintergrund) │
│ │
│ 3a. Neue *.zip-Dateien vom SFTP-Server auflisten │
│ 3b. ZIP herunterladen und entpacken │
│ 3c. Alle Dateien in OCI eingang/<zip-name>/ hochladen │
│ (Unterordner aus der ZIP werden beibehalten) │
│ → Fehler stoppt Verarbeitung dieser ZIP │
│ 3d. Marker eingang/<zip-name>/_READY_FOR_DB_PROCESSING_ │
│ hochladen │
│ 3e. ZIP auf SFTP umbenennen (.processed oder .error) │
│ → erst NACH erfolgreichem Marker-Upload │
│ 3f. ORDS-Endpunkt aufrufen (pck_auto_import.p_process_incoming_ba_data)│
│ 3g. Lokale Arbeitsdateien löschen │
└────────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Oracle DB (via ORDS-Endpunkt) │
│ │
│ 4. Unterordner in eingang/ auflisten │
│ 5. Für jeden Unterordner mit Marker: │
│ Für jede Datei (außer Marker) einzeln: │
│ a. Daten importieren (noch kein Commit) │
│ → log_object_ref = eingang/<zip-name>/datei.csv │
│ b. Datei in Zielordner verschieben │
│ c. Commit │
│ d. Fehler → Rollback, ERROR in lg_app_log, nächste Datei │
│ 6. Keine Dateien mehr im Unterordner (außer Marker)? │
│ → Marker löschen (Batch abgeschlossen) │
└─────────────────────────────────────────────────────────────────┘
```
---
## OCI Ordnerstruktur
```
bucket/
eingang/
export_2026-04-07/ ← Unterordner = ZIP-Name
datei1.csv
datei2.csv
unterordner/
datei3.csv
_READY_FOR_DB_PROCESSING_ ← Marker: Batch vollständig
<zielordner>/
export_2026-04-07/ ← gleiche Struktur nach Verarbeitung
datei1.csv
...
```
Der Marker bleibt solange erhalten bis **alle** Dateien des Unterordners
verarbeitet wurden. Fehlgeschlagene Dateien bleiben im Ordner.
Wenn ein Import-Lauf alle Dateien im Ordner einmal versucht hat zu importieren, und min. eine Datei übrig geblieben ist, für die der automatische Import also nicht funktioniert hat, dann wird für jede dieser Dateien eine Wiedervorlage für die Sachbearbeiter erstellt und eine Marker Datei für die Sachbearbeiter wird im Ordner abgelegt.
Daran können die Sachbearbeiter erkennen, dass der Ordner nicht mehr automatisch importiert wird, sondern sie manuell tätig werden müssen.
---
## Fehlerfall-Verhalten
**Service: Upload einer Datei schlägt fehl**
- Verarbeitung dieser ZIP stoppt sofort
- Kein Marker wird geschrieben, ZIP auf SFTP wird zu `.error` umbenannt
- ORDS wird nicht aufgerufen
- Bereits hochgeladene Dateien werden beim nächsten Trigger überschrieben (OCI PUT idempotent)
**Service: ORDS-Aufruf schlägt fehl**
- Marker liegt in `eingang/<zip-name>/`, Dateien sind vollständig hochgeladen
- Beim nächsten Stundenlauf findet APEX Automation den Marker und verarbeitet
**DB: Verarbeitung einer einzelnen Datei schlägt fehl**
- Rollback — Datei bleibt in `eingang/<zip-name>/`
- ERROR in `lg_app_log` mit `log_object_ref = eingang/<zip-name>/datei.csv`
- Nächste Dateien im Batch werden weiterverarbeitet
**DB: Batch-Abschluss (nach dem Datei-Loop)**
- DB-Marker (`_READY_FOR_DB_PROCESSING_`) wird **immer gelöscht** — kein automatischer Retry
- Liegen noch Dateien im Unterordner: SB-Marker (`_BITTE_PRÜFEN_`) wird angelegt → Sachbearbeiter müssen manuell eingreifen
- Alle Dateien erfolgreich: INFO in `lg_app_log`, Unterordner ist leer
**DB: p_move_object schlägt nach erfolgreichem Import fehl**
- Rollback des Imports → sauberer Ausgangszustand
- Datei bleibt in `eingang/<zip-name>/`
- DB-Marker wird trotzdem am Ende des Loops gelöscht; falls noch Dateien übrig → SB-Marker
---
## Warum ruft die APEX Automation p_process_incoming_ba_data auf, obwohl Quarkus das auch tut?
`p_process_incoming_ba_data` wird in jedem Stundenlauf **zweimal** aufgerufen:
1. Direkt durch `p_run_ba_korrespondenz_dateieingang_automation` (Schritt 1)
2. Indirekt — von Quarkus via ORDS, nachdem der Upload abgeschlossen ist (Schritt 3f)
Der direkte Aufruf in Schritt 1 ist ein **Fallback**: Wenn der ORDS-Aufruf in einem vorherigen Quarkus-Lauf fehlgeschlagen ist, liegt der Marker bereits in OCI, aber `p_process_incoming_ba_data` wurde nie aufgerufen. Ohne Schritt 1 würde dieser Batch erst beim nächsten Quarkus-Lauf verarbeitet — und nur dann, wenn Quarkus beim nächsten Mal auch wieder erfolgreich bis zum ORDS-Aufruf kommt. Mit Schritt 1 ist die DB-Verarbeitung unabhängig davon, ob Quarkus den ORDS-Aufruf erfolgreich abgeschlossen hat.
Das heißt: Quarkus ist der **schnelle Pfad** (Upload + sofortiger DB-Trigger), die APEX Automation ist die **Absicherung** (findet Marker, die noch nicht verarbeitet wurden).
---
## Warum kein Fehlerordner, keine Status-Tabelle?
Der Zustand steckt im Dateisystem:
- Unterordner mit Marker = Batch bereit oder teilweise verarbeitet
- Unterordner ohne Marker = unvollständiger Upload, wird ignoriert
- Datei im Zielordner = erfolgreich verarbeitet
- Datei noch in `eingang/<zip-name>/` = noch ausstehend oder fehlgeschlagen
- ZIP auf SFTP mit `.error` = persistenter Fehler, manuelle Prüfung nötig
Fehlerdetails stehen in `lg_app_log`. Über `log_object_ref` ist jede Datei
eindeutig einer ZIP zugeordnet. Kein Verhalten wird aus dem Log abgeleitet —
es dient ausschließlich dem Audit-Trail.
---
## Zeitplan
APEX Automation läuft **1x pro Stunde**. Der Dateieingang Service wird dabei per
HTTP POST aufgerufen und läuft zeitlich versetzt nach dem Automation-Start.