diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/M4DocumentProcessor.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/M4DocumentProcessor.java index e0546a4..0e0fab5 100644 --- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/M4DocumentProcessor.java +++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/M4DocumentProcessor.java @@ -192,6 +192,100 @@ public class M4DocumentProcessor { } } + /** + * Applies the full M4 processing logic for one identified document candidate. + *
+ * The caller must have already computed a valid {@link DocumentFingerprint} for the + * candidate. This method handles the complete M4 processing flow: + *
+ * This method never throws. All persistence failures are caught, logged, and
+ * treated as controlled per-document failures so the batch run can continue.
+ *
+ * @param candidate the source document candidate being processed; must not be null
+ * @param fingerprint the successfully computed fingerprint for this candidate;
+ * must not be null
+ * @param context the current batch run context (for run ID and timing);
+ * must not be null
+ * @param attemptStart the instant at which processing of this candidate began;
+ * must not be null
+ * @param m3Executor functional interface to execute the M3 pipeline when needed;
+ * must not be null
+ */
+ public void processWithM3Execution(
+ SourceDocumentCandidate candidate,
+ DocumentFingerprint fingerprint,
+ BatchRunContext context,
+ Instant attemptStart,
+ java.util.function.Function
* Per-document errors do not abort the overall batch run. Each candidate ends
@@ -227,15 +233,15 @@ public class DefaultBatchRunProcessingUseCase implements BatchRunProcessingUseCa
LOG.debug("Fingerprint computed for '{}': {}",
candidate.uniqueIdentifier(), fingerprint.sha256Hex());
- // Step M4-2..M4-8: Execute M3 pipeline and delegate M4 logic to the processor
- // The M3 pipeline runs only if the document is not in a terminal state;
- // M4DocumentProcessor handles the terminal check internally.
- // We run M3 eagerly here and pass the result; M4DocumentProcessor will
- // ignore it for terminal documents.
- DocumentProcessingOutcome m3Outcome = runM3Pipeline(candidate);
-
- // Delegate idempotency check, status mapping, and persistence to M4DocumentProcessor
- m4DocumentProcessor.process(candidate, fingerprint, m3Outcome, context, attemptStart);
+ // Delegate the complete M4 processing logic to the processor
+ // The processor handles loading document master record, checking terminal status,
+ // executing M3 pipeline only when needed, and persisting results consistently
+ m4DocumentProcessor.processWithM3Execution(
+ candidate,
+ fingerprint,
+ context,
+ attemptStart,
+ this::runM3Pipeline); // Pass the M3 executor as a function
}
}
}
@@ -287,4 +293,4 @@ public class DefaultBatchRunProcessingUseCase implements BatchRunProcessingUseCa
return outcome;
}
-}
+}
\ No newline at end of file
diff --git a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/BatchRunProcessingUseCaseTest.java b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/BatchRunProcessingUseCaseTest.java
index f13411f..5fbc692 100644
--- a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/BatchRunProcessingUseCaseTest.java
+++ b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/BatchRunProcessingUseCaseTest.java
@@ -641,6 +641,18 @@ class BatchRunProcessingUseCaseTest {
super.process(candidate, fingerprint, m3Outcome, context, attemptStart);
}
+ @Override
+ public void processWithM3Execution(
+ de.gecheckt.pdf.umbenenner.domain.model.SourceDocumentCandidate candidate,
+ de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint fingerprint,
+ de.gecheckt.pdf.umbenenner.domain.model.BatchRunContext context,
+ java.time.Instant attemptStart,
+ java.util.function.Function