feat: Show LLM failure banner and retry button

When an LLM analysis fails, a `.analysis_failed.json` marker is created.
If no document exists yet and the auto-trigger is blocked by this
marker,
the case page must display a banner. This banner provides the failure
reason and a button to retry the analysis, ensuring users are not left
in a dead-end state.

The `read_failure_marker` function is made public to allow the web layer
to access this failure information. The `CasePageTemplate` is updated to
include `analysis_failed` data, which conditionally renders the new
`.failure-banner` HTML.

This change prevents cases from becoming unrecoverable due to transient
LLM errors.
This commit is contained in:
2026-05-03 13:53:55 +02:00
parent bf6464d7e1
commit cbb072d0cc
5 changed files with 473 additions and 2 deletions
+7 -1
View File
@@ -269,7 +269,13 @@ async fn scan_m4as(case_dir: &Path) -> M4aScan {
scan
}
async fn read_failure_marker(case_dir: &Path) -> Option<FailureMarker> {
/// Read and parse the per-case failure marker. `pub(crate)` so the web
/// layer can surface the failure state in the case page (otherwise a
/// transport-level LLM error leaves the user with no UI affordance to
/// retry — the auto-trigger sees the marker and skips, but no document
/// exists yet either, so the existing `Neu analysieren` button is not
/// rendered).
pub(crate) async fn read_failure_marker(case_dir: &Path) -> Option<FailureMarker> {
let bytes = tokio::fs::read(case_dir.join(FAILURE_MARKER_FILE))
.await
.ok()?;