Refactor oneliner storage to use enum
The oneliner is now stored as `OnelinerState` enum which can represent three states: `Ready`, `Empty` or `Error`. This allows the client to differentiate between a case with no medical content and a case where the oneliner generation failed. The `OnelinerState` enum is serialized to JSON and stored in `oneliner.json` file. The `OnelinerEntry` struct has been updated to reflect this change. The client-desktop application has been updated to handle the new `OnelinerState` enum and display appropriate UI elements for each state. The server-side code has also been updated to read and write the `OnelinerState` enum, and to handle the new file format. The `reset_case_artefacts` function in `server/src/routes/case_actions.rs` has been updated to remove `oneliner.txt` and create `oneliner.json` instead. The tests have been updated to reflect these changes.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use doctate_common::oneliners::{ONELINER_FILENAME, OnelinerState};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Absolute on-disk location of a case directory.
|
||||
@@ -46,3 +48,36 @@ pub async fn write_delete_marker(case_dir: &Path, marker: &DeleteMarker) -> std:
|
||||
.map_err(|e| std::io::Error::other(format!("serialize delete marker: {e}")))?;
|
||||
tokio::fs::write(case_dir.join(DELETE_MARKER), bytes).await
|
||||
}
|
||||
|
||||
/// Read the persisted oneliner state for a case.
|
||||
///
|
||||
/// Returns `(Some(state), Some(mtime))` when `oneliner.json` exists and
|
||||
/// parses. Missing file → `(None, None)`. A file that exists but fails
|
||||
/// to parse is treated as missing and logged — the next transcription
|
||||
/// job will overwrite it with a well-formed state.
|
||||
pub async fn read_oneliner_state(
|
||||
case_dir: &Path,
|
||||
) -> (Option<OnelinerState>, Option<OffsetDateTime>) {
|
||||
let path = case_dir.join(ONELINER_FILENAME);
|
||||
let bytes = match tokio::fs::read(&path).await {
|
||||
Ok(b) => b,
|
||||
Err(_) => return (None, None),
|
||||
};
|
||||
let state: OnelinerState = match serde_json::from_slice(&bytes) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
path = %path.display(),
|
||||
error = %e,
|
||||
"malformed oneliner.json; treating as missing"
|
||||
);
|
||||
return (None, None);
|
||||
}
|
||||
};
|
||||
let mtime = tokio::fs::metadata(&path)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|m| m.modified().ok())
|
||||
.map(OffsetDateTime::from);
|
||||
(Some(state), mtime)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user