Files
gala-ki-spielwiese/workflow_dateieingang.md

8.5 KiB

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.