use std::collections::HashMap; use std::path::Path; use std::sync::Arc; use std::sync::atomic::Ordering; use askama::Template; use axum::extract::{Query, State}; use axum::response::Html; use doctate_common::TranscriptState; use doctate_common::oneliners::OnelinerState; use serde::Deserialize; use tracing::{info, warn}; use time::{Date, OffsetDateTime, format_description::well_known::Rfc3339}; use crate::analyze::{ ANALYSIS_INPUT_FILE, DOCUMENT_FILE, auto_trigger, recovery as analyze_recovery, }; use crate::auth::AuthenticatedWebUser; use crate::case_id::{CaseId, CaseIdPath}; use crate::config::Config; use crate::error::AppError; use crate::events::EventSender; use crate::gazetteer::Gazetteer; use crate::paths; use crate::routes::case_actions::read_document; use crate::routes::web::{RecordingView, scan_recordings}; use crate::settings::Settings; use crate::transcribe::recovery as transcribe_recovery; use crate::{BusyGuard, PipelineState}; /// UI-layer oneliner status for the case list. Combines the persisted /// [`OnelinerState`] with derived transit states that only make sense /// in the list context (transcription still pending, or no state file /// despite completed transcription). /// /// Kept local to the server — not part of the public API DTO, which /// exposes the raw [`OnelinerState`] and lets each client decide how /// to render transit states. enum OnelinerDisplay { /// LLM produced a usable title. Ready(String), /// Stable "no title to expect" — either the LLM returned nothing /// (no medical content in transcript) or every recording failed so /// nothing can ever generate a title. UI treats both identically; /// the reason is uninteresting to the doctor in the list view. Empty, /// LLM call failed with transcripts available. Error, /// Transcription still running — a title cannot exist yet. Pending, /// Transcripts are done (or about to land) but the LLM hasn't /// written a state yet, OR a previous state is obsolete because new /// recordings arrived. The worker is generating right now or will /// generate as soon as the last transcript is in. Covers the /// reset-just-clicked case and the post-restart recovery window. Generating, } struct UserCaseView { case_id: String, most_recent: String, /// HH:MM of the most recent recording in UTC — no-JS fallback. /// Browser script replaces the displayed text with the browser-local /// equivalent via the parallel `recorded_at_iso` field. time_hms_utc: String, /// Full RFC3339 UTC timestamp of the most recent recording. Fed into /// the HTML `