diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiConfigurationEditorWorkspace.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiConfigurationEditorWorkspace.java
index e79c2a5..d979435 100644
--- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiConfigurationEditorWorkspace.java
+++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiConfigurationEditorWorkspace.java
@@ -43,6 +43,8 @@ import de.gecheckt.pdf.umbenenner.application.validation.editor.EditorValidation
import de.gecheckt.pdf.umbenenner.application.validation.editor.EditorValidationSeverity;
import de.gecheckt.pdf.umbenenner.application.validation.technicaltest.CorrectionExecutionService;
import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
@@ -51,8 +53,6 @@ import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
@@ -70,7 +70,6 @@ import javafx.scene.input.ClipboardContent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
-
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunCoordinator.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunCoordinator.java
index a0bfd4e..9639fcc 100644
--- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunCoordinator.java
+++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunCoordinator.java
@@ -268,6 +268,48 @@ public final class GuiBatchRunCoordinator {
return startWorker(task);
}
+ /**
+ * Starts a reprocessing operation: resets the database status of the specified
+ * fingerprints and immediately launches a targeted mini-run for them.
+ *
+ * This method is the preferred entry point for "Erneut verarbeiten" (reprocess)
+ * actions in the GUI. It ensures that documents marked as FAILED_FINAL or otherwise
+ * ineligible for processing are reset before the mini-run begins, so they are
+ * reprocessed rather than skipped.
+ *
+ * The reset executes synchronously on the caller's thread before the worker thread
+ * is started. This guarantees that the mini-run sees the documents in a
+ * reprocessable state.
+ *
+ * @param configFilePath the configuration file; must not be {@code null}
+ * @param fingerprintFilter the set of document fingerprints to reset and process;
+ * must not be {@code null}
+ * @return {@code true} when a new worker thread was started, {@code false} when a run
+ * was already in progress or when the reset failed for all fingerprints
+ * @throws NullPointerException if any argument is {@code null}
+ */
+ public boolean startReprocessing(Path configFilePath,
+ Set fingerprintFilter) {
+ Objects.requireNonNull(configFilePath, "configFilePath must not be null");
+ Objects.requireNonNull(fingerprintFilter, "fingerprintFilter must not be null");
+ if (isRunning()) {
+ return false;
+ }
+ // Reset the database status synchronously before starting the mini-run.
+ // This ensures that documents are not skipped due to FAILED_FINAL or other
+ // terminal states.
+ ResetDocumentStatusResult resetResult = resetPort.reset(configFilePath, fingerprintFilter);
+ if (resetResult.successCount() == 0) {
+ LOG.warn("GUI-Reprocessing: Reset für alle {} Dokumente fehlgeschlagen; "
+ + "Mini-Lauf wird nicht gestartet.", fingerprintFilter.size());
+ return false;
+ }
+ LOG.info("GUI-Reprocessing: {} von {} Dokumenten erfolgreich zurückgesetzt.",
+ resetResult.successCount(), resetResult.requestedCount());
+ // Now start the mini-run with the reset fingerprints.
+ return startMiniRun(configFilePath, fingerprintFilter);
+ }
+
/**
* Starts a reset-only operation for the supplied fingerprint set.
*
diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTab.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTab.java
index 3438cb3..ff1997c 100644
--- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTab.java
+++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTab.java
@@ -4,7 +4,6 @@ import java.nio.file.Path;
import java.time.Duration;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -707,7 +706,10 @@ public final class GuiBatchRunTab {
// Mark selected rows as reset-pending immediately for visual feedback.
markSelectedRowsAsResetPending();
- boolean started = coordinator.startMiniRun(configPath, snapshot);
+ // Reset database status and start mini-run. The reset executes synchronously
+ // before the mini-run worker thread is started, ensuring documents are not
+ // skipped due to FAILED_FINAL status.
+ boolean started = coordinator.startReprocessing(configPath, snapshot);
if (!started) {
showMessage(ALREADY_RUNNING_HINT);
return;
diff --git a/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunCoordinatorMiniRunTest.java b/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunCoordinatorMiniRunTest.java
index 7e5d73b..b3f0c9a 100644
--- a/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunCoordinatorMiniRunTest.java
+++ b/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunCoordinatorMiniRunTest.java
@@ -18,8 +18,6 @@ import java.util.function.Function;
import org.junit.jupiter.api.Test;
-import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunCancellationToken;
-import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunProgressObserver;
import de.gecheckt.pdf.umbenenner.application.port.in.DocumentCompletionEvent;
import de.gecheckt.pdf.umbenenner.application.port.in.DocumentCompletionStatus;
import de.gecheckt.pdf.umbenenner.application.port.in.ResetDocumentStatusResult;
diff --git a/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTabSelectionSmokeTest.java b/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTabSelectionSmokeTest.java
index 1971302..a9b9789 100644
--- a/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTabSelectionSmokeTest.java
+++ b/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTabSelectionSmokeTest.java
@@ -196,7 +196,10 @@ class GuiBatchRunTabSelectionSmokeTest {
GuiBatchRunLauncher noOpLauncher = (p, o, t) ->
GuiBatchRunLaunchOutcome.rejected("not used");
GuiResetDocumentStatusPort noOpReset = (p, fps) ->
- new ResetDocumentStatusResult(fps.size(), Set.of(), Map.of());
+ // Return a successful reset for all fingerprints. The reset doesn't actually
+ // change anything in this test, but successCount() returns successfullyReset.size(),
+ // so we must return the fingerprints in the successfully reset set.
+ new ResetDocumentStatusResult(fps.size(), fps, Map.of());
CountDownLatch tabReady = new CountDownLatch(1);
AtomicReferenceCapture tabRef = new AtomicReferenceCapture<>();
diff --git a/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTabSmokeTest.java b/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTabSmokeTest.java
index f9d746c..6003a10 100644
--- a/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTabSmokeTest.java
+++ b/pdf-umbenenner-adapter-in-gui/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/GuiBatchRunTabSmokeTest.java
@@ -2,7 +2,6 @@ package de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.nio.file.Path;
diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/AiResponseValidator.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/AiResponseValidator.java
index 901263c..95c850b 100644
--- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/AiResponseValidator.java
+++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/AiResponseValidator.java
@@ -6,6 +6,7 @@ import java.util.Objects;
import java.util.Set;
import de.gecheckt.pdf.umbenenner.application.port.out.ClockPort;
+import de.gecheckt.pdf.umbenenner.application.service.AiResponseValidator.AiValidationResult;
import de.gecheckt.pdf.umbenenner.domain.model.AiErrorClassification;
import de.gecheckt.pdf.umbenenner.domain.model.DateSource;
import de.gecheckt.pdf.umbenenner.domain.model.NamingProposal;
diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/DocumentProcessingCoordinator.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/DocumentProcessingCoordinator.java
index 9b88475..aeb2e8f 100644
--- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/DocumentProcessingCoordinator.java
+++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/service/DocumentProcessingCoordinator.java
@@ -7,6 +7,7 @@ import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
+import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunProgressObserver;
import de.gecheckt.pdf.umbenenner.application.port.in.DocumentCompletionEvent;
import de.gecheckt.pdf.umbenenner.application.port.in.DocumentCompletionStatus;
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentKnownProcessable;
diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultBatchRunProcessingUseCase.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultBatchRunProcessingUseCase.java
index e315572..b757318 100644
--- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultBatchRunProcessingUseCase.java
+++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultBatchRunProcessingUseCase.java
@@ -12,14 +12,10 @@ import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunCancellationToken;
import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunOutcome;
import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunProcessingUseCase;
import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunProgressObserver;
-import de.gecheckt.pdf.umbenenner.application.port.in.DocumentCompletionEvent;
-import de.gecheckt.pdf.umbenenner.application.port.in.DocumentCompletionStatus;
-import de.gecheckt.pdf.umbenenner.application.port.in.RunSummary;
import de.gecheckt.pdf.umbenenner.application.port.out.FingerprintPort;
import de.gecheckt.pdf.umbenenner.application.port.out.FingerprintResult;
import de.gecheckt.pdf.umbenenner.application.port.out.FingerprintSuccess;
import de.gecheckt.pdf.umbenenner.application.port.out.FingerprintTechnicalError;
-import de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint;
import de.gecheckt.pdf.umbenenner.application.port.out.PdfTextExtractionPort;
import de.gecheckt.pdf.umbenenner.application.port.out.ProcessingLogger;
import de.gecheckt.pdf.umbenenner.application.port.out.RunLockPort;
diff --git a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/BatchRunProgressObservationTest.java b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/BatchRunProgressObservationTest.java
index 4541bdb..9640758 100644
--- a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/BatchRunProgressObservationTest.java
+++ b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/BatchRunProgressObservationTest.java
@@ -2,14 +2,11 @@ package de.gecheckt.pdf.umbenenner.application.usecase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.io.IOException;
-import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant;
@@ -17,7 +14,6 @@ import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
diff --git a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultResetDocumentStatusUseCaseTest.java b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultResetDocumentStatusUseCaseTest.java
index ebc4bab..a523702 100644
--- a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultResetDocumentStatusUseCaseTest.java
+++ b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultResetDocumentStatusUseCaseTest.java
@@ -6,7 +6,6 @@ import static org.assertj.core.api.Assertions.assertThatNullPointerException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
diff --git a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/BootstrapRunner.java b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/BootstrapRunner.java
index d5c3d02..7a67763 100644
--- a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/BootstrapRunner.java
+++ b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/BootstrapRunner.java
@@ -24,8 +24,6 @@ import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiConfigurationLoadException;
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiStartupContext;
import de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun.GuiBatchRunLaunchOutcome;
import de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun.GuiBatchRunLauncher;
-import de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun.GuiMiniRunLauncher;
-import de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun.GuiResetDocumentStatusPort;
import de.gecheckt.pdf.umbenenner.adapter.in.gui.editor.GuiConfigurationEditorState;
import de.gecheckt.pdf.umbenenner.adapter.in.gui.editor.GuiConfigurationEditorStateFactory;
import de.gecheckt.pdf.umbenenner.adapter.in.gui.editor.GuiConfigurationFileSnapshot;
@@ -56,7 +54,6 @@ import de.gecheckt.pdf.umbenenner.application.config.startup.StartConfiguration;
import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunOutcome;
import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunProcessingUseCase;
import de.gecheckt.pdf.umbenenner.application.port.in.ResetDocumentStatusResult;
-import de.gecheckt.pdf.umbenenner.application.usecase.DefaultResetDocumentStatusUseCase;
import de.gecheckt.pdf.umbenenner.application.port.out.AiContentSensitivity;
import de.gecheckt.pdf.umbenenner.application.port.out.AiInvocationPort;
import de.gecheckt.pdf.umbenenner.application.port.out.ClockPort;
@@ -77,6 +74,7 @@ import de.gecheckt.pdf.umbenenner.application.service.AiNamingService;
import de.gecheckt.pdf.umbenenner.application.service.AiResponseValidator;
import de.gecheckt.pdf.umbenenner.application.service.DocumentProcessingCoordinator;
import de.gecheckt.pdf.umbenenner.application.usecase.DefaultBatchRunProcessingUseCase;
+import de.gecheckt.pdf.umbenenner.application.usecase.DefaultResetDocumentStatusUseCase;
import de.gecheckt.pdf.umbenenner.application.validation.editor.EditorConfigurationValidator;
import de.gecheckt.pdf.umbenenner.application.validation.technicaltest.ProviderTechnicalTestService;
import de.gecheckt.pdf.umbenenner.application.validation.technicaltest.TechnicalTestOrchestrator;