Files
gala-ki-spielwiese/agent-backend/CLAUDE.md

4.9 KiB

CLAUDE.md — Dateieingang Service

Projektbeschreibung

Quarkus-Backend-Service, der einen n8n-Workflow bei Galabau ersetzt. Empfängt einen HTTP-Trigger von der APEX Automation, holt ZIP-Dateien von einem SFTP-Server, entpackt sie, lädt die Dateien in OCI Object Storage hoch und benachrichtigt die Oracle-Datenbank via ORDS.

Dokumentation

Nur bei Bedarf lesen — nicht automatisch in den Kontext laden:

Dokument Inhalt
SETUP.md Installation (WSL, Java 25, Quarkus CLI), Build, Dev-Server, Umgebungsvariablen
docs/Architecture.md Pipeline-Steps, Service-Mapping, Konfigurationsstruktur
docs/Logging.md Logging-Stack (LGTM), MDC-Felder, Log-Events pro Step
docs/Plan.md Vollständiger Architektur- und Migrationsplan
docs/SFTP-Integration.md SSHJ-Architektur, Host-Key-Verification, Fehlerbehandlung

Datenbankspezifische Dokumente: ../database/

Tech-Stack

Komponente Technologie
Framework Quarkus (Java 25)
Build Maven (Maven Wrapper ./mvnw)
SFTP SSHJ (com.hierynomus:sshj)
ZIP-Verarbeitung Apache Commons Compress
OCI Object Storage OCI Java SDK (oci-java-sdk-objectstorage)
ORDS-Client MicroProfile REST Client
Fehlertoleranz SmallRye Fault Tolerance (@Retry, @Timeout)
Async Quarkus Managed Executor (quarkus-smallrye-context-propagation)
Logging Quarkus + OTLP → Loki/Grafana (Dev: quarkus-observability-devservices-lgtm)
JSON Jackson

Paketstruktur

src/main/java/de/galabau/dateieingang/
├── api/        # REST Endpoint (eingehend von APEX Automation)
├── sftp/       # SSHJ: list, download, rename
├── zip/        # ZIP-Entpacken (Apache Commons Compress)
├── oci/        # OCI Object Storage Upload + Marker
├── ords/       # Oracle ORDS REST-Client (process_incoming)
├── pipeline/   # Orchestrierung des Gesamtworkflows
├── model/      # ProcessingContext, FileEntry, DTOs
├── config/     # @ConfigMapping Interfaces
└── exception/  # Domain-Exceptions

Externe Abhängigkeiten

Service Konfiguration Zweck
SFTP-Server galabau.sftp.* ZIP-Dateien abholen
OCI Object Storage galabau.oci.* Dateien + Marker ablegen
Oracle ORDS galabau.ords.* DB-Verarbeitung auslösen
APEX Automation ruft /api/process-incoming auf Trigger (stündlich)

Konventionen

  • Sprache: Dokumentation auf Deutsch, Code auf Englisch
  • Konfiguration: Alle URLs, Ports, Benutzernamen in application.properties; Passwörter und Keys via ${ENV_VAR} aus Umgebungsvariablen
  • Kein eigenes Scheduling: Trigger kommt von APEX Automation via HTTP POST
  • Async: Pipeline läuft im Hintergrund, APEX bekommt sofort 202 Accepted
  • Cleanup: Lokale Arbeitsdateien immer im finally-Block löschen
  • Einzelinstanz: Kein Clustering — AtomicBoolean-Guard verhindert gleichzeitige Läufe

Java Code Guidelines

Sprache

Dokumentation und Kommentare auf Deutsch, Code (Klassen-, Methoden-, Variablennamen) auf Englisch.

Javadoc

Javadoc für alle öffentlichen Methoden der Service-Klassen und alle Klassen in model/. Nicht nötig für triviale Getter, Test-Methoden oder selbsterklärende Signaturen.

// ✅ Javadoc sinnvoll
/**
 * Lädt alle Dateien aus dem ProcessingContext in OCI Object Storage hoch
 * und schreibt danach den Marker für die DB-Verarbeitung.
 *
 * @param context enthält die Liste der hochzuladenden Dateien und den Ziel-Prefix
 * @throws OciException bei persistenten OCI-Fehlern (4xx)
 */
public void upload(ProcessingContext context) throws OciException { ... }

Exceptions

Eigene Domain-Exceptions pro Integrationsbereich. Möglichst nicht Exception oder RuntimeException fangen.

// ✅
throw new SftpException("SFTP rename failed for: " + filename, cause);

// ❌
throw new RuntimeException("something went wrong");

Logging

io.quarkus.logging.Log — statische API, kein Field-Boilerplate.

import io.quarkus.logging.Log;

@ApplicationScoped
public class SftpService {
    public List<String> listZipFiles() throws SftpException {
        Log.infof("Listing ZIP files on SFTP: %s", config.remotePath());
        Log.errorf(e, "SFTP list failed on %s", config.host());
    }
}

Immer mit MDC-Kontext loggen (wird automatisch angehängt, siehe docs/Logging.md). Nie sensible Daten loggen (Passwörter, Keys, Key-Dateipfade).

Konfiguration

Keine hardcodierten Werte — alles via @ConfigMapping.

// ✅
@ConfigMapping(prefix = "galabau.sftp")
public interface SftpConfig { ... }

// ❌
private static final String HOST = "sftp.lieferant.de";

CDI / Services

Services als @ApplicationScoped. Keine manuelle Instanziierung mit new.

Paketgrenzen

Kein direkter Zugriff auf interne Klassen fremder Pakete — nur über die öffentliche Service-API.