Add OnelinerState::Manual variant
This commit introduces a new `Manual` variant to the `OnelinerState` enum, allowing for manual overrides of the oneliner text. This change affects the client and server components to handle and display this new state. A `OnelinerOverrideRequest` struct is also added for API requests to set manual oneliners. New tests are included to ensure the `Manual` variant serializes and deserializes correctly. The `compute_oneliner_display` function in `server/src/routes/user_web.rs` is updated to treat `Manual` states the same as `Ready` states for display purposes. The `cases_needing_oneliner_in` function in `server/src/transcribe/recovery.rs` is updated to not retry cases that are in a `Manual` state.
This commit is contained in:
@@ -143,7 +143,11 @@ pub(crate) async fn cases_needing_oneliner_in(user_root: &Path) -> Vec<PathBuf>
|
||||
let (state, _) = paths::read_oneliner_state(&case_dir).await;
|
||||
let needs_retry = match state {
|
||||
None | Some(OnelinerState::Error { .. }) => true,
|
||||
Some(OnelinerState::Ready { .. } | OnelinerState::Empty { .. }) => false,
|
||||
Some(
|
||||
OnelinerState::Ready { .. }
|
||||
| OnelinerState::Empty { .. }
|
||||
| OnelinerState::Manual { .. },
|
||||
) => false,
|
||||
};
|
||||
if !needs_retry {
|
||||
continue;
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use doctate_common::TranscriptState;
|
||||
use doctate_common::oneliners::{ONELINER_FILENAME, OnelinerState};
|
||||
use doctate_common::oneliners::OnelinerState;
|
||||
use time::OffsetDateTime;
|
||||
use time::format_description::well_known::Rfc3339;
|
||||
use tracing::{error, info, warn};
|
||||
@@ -237,7 +237,7 @@ pub(crate) async fn update_oneliner(
|
||||
.format(&Rfc3339)
|
||||
.unwrap_or_default();
|
||||
let state = OnelinerState::Empty { generated_at };
|
||||
if let Err(e) = write_oneliner_state(case_dir, &state).await {
|
||||
if let Err(e) = paths::write_oneliner_state(case_dir, &state).await {
|
||||
error!(
|
||||
case = %case_dir.display(),
|
||||
error = %e,
|
||||
@@ -298,7 +298,7 @@ pub(crate) async fn update_oneliner(
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = write_oneliner_state(case_dir, &state).await {
|
||||
if let Err(e) = paths::write_oneliner_state(case_dir, &state).await {
|
||||
error!(case = %case_dir.display(), error = %e, "writing oneliner.json failed");
|
||||
return;
|
||||
}
|
||||
@@ -310,18 +310,6 @@ pub(crate) async fn update_oneliner(
|
||||
);
|
||||
}
|
||||
|
||||
/// Write `state` atomically to `case_dir/oneliner.json` via
|
||||
/// `write(tmp) + rename(tmp, final)`. Rename is atomic within a single
|
||||
/// filesystem, so concurrent readers never see a half-serialized JSON
|
||||
/// document.
|
||||
async fn write_oneliner_state(case_dir: &Path, state: &OnelinerState) -> std::io::Result<()> {
|
||||
let final_path = case_dir.join(ONELINER_FILENAME);
|
||||
let tmp_path = case_dir.join(format!("{ONELINER_FILENAME}.tmp"));
|
||||
let payload = serde_json::to_vec(state).expect("OnelinerState is infallibly serializable");
|
||||
tokio::fs::write(&tmp_path, &payload).await?;
|
||||
tokio::fs::rename(&tmp_path, &final_path).await
|
||||
}
|
||||
|
||||
/// Return true if `case_dir` contains at least one `.m4a` recording
|
||||
/// whose transcript is still `Pending` (no sidecar file yet). Used to
|
||||
/// gate the oneliner-regenerate call: we only run it after the *last*
|
||||
|
||||
Reference in New Issue
Block a user