Refactor analysis file names

The versioning of analysis input and document files
(`analysis_input_v{N}.json`, `document_v{N}.md`) has been removed. All
analysis inputs will now use `analysis_input.json` and generated
documents will use `document.md`.

This simplifies file management, as there's no longer a need to track
and manage multiple versions of these files within a case directory. The
analysis worker will now overwrite the existing `document.md` if it
exists, ensuring that the latest analysis result is always present. The
`version` field has also been removed from `AnalyzeJob` and
`AnalysisInput`.
This commit is contained in:
2026-04-16 01:56:55 +02:00
parent 928c0659c1
commit 8c6b2eeaa4
9 changed files with 111 additions and 281 deletions
+10 -30
View File
@@ -9,7 +9,7 @@ use tracing::{info, warn};
use time::{format_description::well_known::Rfc3339, Date, OffsetDateTime, UtcOffset};
use crate::analyze::{recovery as analyze_recovery, AnalyzeSender};
use crate::analyze::{recovery as analyze_recovery, AnalyzeSender, ANALYSIS_INPUT_FILE, DOCUMENT_FILE};
use crate::auth::AuthenticatedWebUser;
use crate::config::Config;
use crate::error::AppError;
@@ -173,39 +173,19 @@ async fn compute_flags(
}
}
/// True iff the case directory contains at least one `analysis_input_v*.json`.
/// The worker removes the input after successful document write, so existence
/// implies a pending or in-flight analyze job.
/// True iff `analysis_input.json` exists. The worker removes it after a
/// successful document write, so existence implies a pending or in-flight job.
pub(crate) async fn any_analysis_input_exists(case_dir: &Path) -> bool {
let mut entries = match tokio::fs::read_dir(case_dir).await {
Ok(r) => r,
Err(_) => return false,
};
while let Ok(Some(entry)) = entries.next_entry().await {
let name = entry.file_name();
let Some(name_str) = name.to_str() else { continue };
if name_str.starts_with("analysis_input_v") && name_str.ends_with(".json") {
return true;
}
}
false
tokio::fs::try_exists(case_dir.join(ANALYSIS_INPUT_FILE))
.await
.unwrap_or(false)
}
/// True iff the case directory contains at least one `document_v{N}.md`.
/// We don't care about N here — any version means "Ausgewertet" for the UI.
/// True iff `document.md` exists.
pub(crate) async fn any_document_exists(case_dir: &Path) -> bool {
let mut entries = match tokio::fs::read_dir(case_dir).await {
Ok(r) => r,
Err(_) => return false,
};
while let Ok(Some(entry)) = entries.next_entry().await {
let name = entry.file_name();
let Some(name_str) = name.to_str() else { continue };
if name_str.starts_with("document_v") && name_str.ends_with(".md") {
return true;
}
}
false
tokio::fs::try_exists(case_dir.join(DOCUMENT_FILE))
.await
.unwrap_or(false)
}
/// Self-heal: if a worker is idle but orphans exist on disk for this user,