1
0

Umsetzung von Meilenstein M7

This commit is contained in:
2026-04-07 17:26:02 +02:00
parent ffd91c766d
commit e9e9b2d17a
30 changed files with 2328 additions and 206 deletions

View File

@@ -17,10 +17,14 @@ package de.gecheckt.pdf.umbenenner.domain.model;
* processed further in the next stage (target copy, final filename generation).
* This is a non-terminal intermediate state.</li>
* <li>{@link #SUCCESS} — document was fully processed end-to-end and written to the
* target location. Status is final and irreversible; skip in all future runs.</li>
* target location. Status is final and irreversible; skip in all future runs with
* {@link #SKIPPED_ALREADY_PROCESSED}.</li>
* <li>{@link #FAILED_RETRYABLE} — last attempt failed but is retryable; process again
* in the next run according to the applicable retry rule.</li>
* <li>{@link #FAILED_FINAL} — all allowed retries exhausted; skip in all future runs.</li>
* in the next run according to the applicable retry rule. This status is only
* valid as long as at least one further scheduler run is fachlich zulässig.</li>
* <li>{@link #FAILED_FINAL} — all allowed retries are exhausted; skip in all future
* runs with {@link #SKIPPED_FINAL_FAILURE}. This status is terminal and
* irreversible.</li>
* <li>{@link #PROCESSING} — document is currently being processed (transient, within a
* run); if found persisted after a crash, treat as {@link #FAILED_RETRYABLE}.</li>
* </ul>
@@ -38,6 +42,32 @@ package de.gecheckt.pdf.umbenenner.domain.model;
* overall status was already {@link #FAILED_FINAL}.</li>
* </ul>
* <p>
* <strong>Terminal status rule:</strong>
* {@link #SUCCESS} and {@link #FAILED_FINAL} are the only truly terminal statuses.
* Documents with either of these statuses as their overall status are never reprocessed;
* they receive a historised skip attempt instead. Documents with
* {@link #FAILED_RETRYABLE}, {@link #READY_FOR_AI}, or {@link #PROPOSAL_READY} remain
* verarbeitbar in future runs, subject to their applicable retry rule.
* <p>
* <strong>Transition to {@link #FAILED_FINAL} — retry exhaustion rules:</strong>
* <ul>
* <li><em>Deterministic content errors</em>: The first historised deterministic content
* error leads to {@link #FAILED_RETRYABLE}. The second historised deterministic
* content error for the same fingerprint leads to {@link #FAILED_FINAL}. No further
* retry is possible after the second content error.</li>
* <li><em>Transient technical errors</em>: Each transient error increments the transient-error
* counter. When the counter reaches the configured {@code max.retries.transient} value
* (Integer &ge; 1), the attempt that reaches the limit transitions the document to
* {@link #FAILED_FINAL}. The value {@code 0} for {@code max.retries.transient} is
* invalid start configuration.</li>
* </ul>
* <p>
* <strong>Immediate within-run target copy retry:</strong>
* A single technical retry of the physical target-file copy step is permitted within the
* same run. This mechanism is not a cross-run retry and does not increment the
* transient-error counter. It does not change the document's overall status until the
* outcome of the retry is known.
* <p>
* <strong>Counter rules:</strong>
* <ul>
* <li>Only {@link #FAILED_RETRYABLE} and {@link #FAILED_FINAL} outcomes may increase
@@ -46,11 +76,17 @@ package de.gecheckt.pdf.umbenenner.domain.model;
* never change any failure counter.</li>
* <li>A deterministic content error at first occurrence → {@link #FAILED_RETRYABLE},
* content-error counter +1. At second occurrence → {@link #FAILED_FINAL},
* content-error counter +2 (cumulative).</li>
* <li>A transient technical error after a successful fingerprint → {@link #FAILED_RETRYABLE},
* transient-error counter +1.</li>
* content-error counter +1 (cumulative total = 2).</li>
* <li>A transient technical error after a successful fingerprint → counter +1; status
* is {@link #FAILED_RETRYABLE} while counter &lt; {@code max.retries.transient},
* or {@link #FAILED_FINAL} when counter reaches {@code max.retries.transient}.</li>
* </ul>
*
* <p>
* <strong>Document-level errors and batch exit code:</strong>
* Document-level errors (content errors, transient errors, target copy failures) do not
* escalate to exit-code&nbsp;1. The batch run continues with remaining documents and
* exits with code&nbsp;0 as long as the run itself started cleanly. Exit-code&nbsp;1 is
* reserved for hard start or bootstrap failures only.
*/
public enum ProcessingStatus {

View File

@@ -57,5 +57,23 @@
* <li>Immutable value objects or enumerations</li>
* <li>Reusable across all layers via the Application and Adapter contracts</li>
* </ul>
* <p>
* <strong>Retry and status semantics summary (see {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus}
* for full detail):</strong>
* <ul>
* <li>{@code SUCCESS} and {@code FAILED_FINAL} are terminal; documents with these statuses
* receive a historised skip attempt in future runs and are never reprocessed.</li>
* <li>{@code FAILED_RETRYABLE} is only valid while at least one further scheduler run
* is fachlich zulässig for the document.</li>
* <li>Deterministic content errors follow the 1-retry rule: first occurrence →
* {@code FAILED_RETRYABLE}; second occurrence → {@code FAILED_FINAL}.</li>
* <li>Transient technical errors follow the configurable {@code max.retries.transient}
* rule (Integer &ge; 1): the attempt reaching the limit transitions to
* {@code FAILED_FINAL}.</li>
* <li>The within-run target copy immediate retry does not increment the transient-error
* counter and is not a cross-run retry.</li>
* <li>Document-level errors never produce exit-code&nbsp;1; they are contained within
* the batch run.</li>
* </ul>
*/
package de.gecheckt.pdf.umbenenner.domain.model;