fix: settle silent-only cases to Empty oneliner state
Introduce `TranscriptState { Pending, Silent, Content }` in
doctate-common as the canonical three-way state of a recording's
`.transcript.txt` sidecar. Previously each call-site projected the
raw `Option<String>` / `.exists()` onto its own 2-state view and the
projections disagreed: the UI treated a 0-byte silent transcript like
`Content` while the oneliner worker treated it like `Pending`,
leaving silent-only cases stuck on "generiere Titel …" forever with
no persisted oneliner.json.
`update_oneliner` now settles a silent-only case to
`OnelinerState::Empty` when no `Content` transcript exists and no
recording is still `Pending`, so the UI resolves to "unbenannt" and
recovery treats it as terminal.
Single reader: `paths::read_transcript_state`. All call-sites
(scan_recordings, compute_oneliner_display, has_pending_recordings,
all_transcripts_joined, read_recordings, enqueue_pending_for_user,
scan_m4as, cases_needing_oneliner_in, case_recordings.html) go
through the same typed abstraction and must handle `Silent` via
exhaustive match.
Regression tests:
- silent_case_empty_test: heal path settles silent-only case to
Empty without calling Ollama
- case_page_silent_only_shows_empty_not_generating: UI renders
"unbenannt", not "generiere Titel …"
This commit is contained in:
@@ -21,6 +21,7 @@ use tracing::warn;
|
||||
use super::{ANALYSIS_INPUT_FILE, AnalysisInput, AnalyzeJob, AnalyzeSender, DOCUMENT_FILE};
|
||||
use crate::config::Config;
|
||||
use crate::events::{self, CaseEventKind, EventSender};
|
||||
use crate::paths;
|
||||
use crate::routes::case_actions::build_analysis_input;
|
||||
|
||||
/// Filename of the per-case failure marker. Written by the worker on
|
||||
@@ -253,8 +254,14 @@ async fn scan_m4as(case_dir: &Path) -> M4aScan {
|
||||
});
|
||||
}
|
||||
|
||||
let transcript = entry.path().with_extension("transcript.txt");
|
||||
if !tokio::fs::try_exists(&transcript).await.unwrap_or(false) {
|
||||
// Analyze gate: "all transcribed" means every m4a has passed
|
||||
// through the transcriber, regardless of whether that produced
|
||||
// `Content` or `Silent` output. Only `Pending` (no sidecar)
|
||||
// holds the trigger back.
|
||||
if paths::read_transcript_state(&entry.path())
|
||||
.await
|
||||
.is_pending()
|
||||
{
|
||||
scan.all_transcribed = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user