Files
doctate/doctate-common/src/oneliners.rs
T
Brummel cdfa5ae90e Refactor timestamp handling for activity sorting
Introduce `last_recording_at` to `OnelinerEntry` and use it as the
primary sort key for cases. This ensures that cases with recent
dictation activity are prioritized, even if their initial creation date
is older.

The logic for determining a case's activity has been updated to consider
the most recent `.m4a` file's modification time (`last_recording_at`),
falling back to `updated_at` or `created_at` if necessary.

This change also refactors the timestamp formatting and handling within
the web interface to correctly display and sort cases based on their
actual last activity time, improving user experience and data relevance.
The `now_rfc3339` function is updated to strip sub-second precision for
consistent filename generation.
2026-04-18 11:33:35 +02:00

44 lines
1.7 KiB
Rust

//! Shared DTOs for the `/api/oneliners` endpoint.
//!
//! Server serializes [`OnelinersResponse`]; clients deserialize the same
//! type. Keeping this in a client-agnostic crate avoids drift between
//! server output and client parsing.
use serde::{Deserialize, Serialize};
/// HTTP path of the oneliners endpoint.
pub const ONELINERS_PATH: &str = "/api/oneliners";
/// Full response body of `GET /api/oneliners`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OnelinersResponse {
/// RFC3339 UTC timestamp at which the server built this response.
pub as_of: String,
/// Effective window (after server-side clamp).
pub window_hours: u32,
/// Oneliners of cases whose earliest recording sits inside the window,
/// sorted newest-first by `created_at`.
pub oneliners: Vec<OnelinerEntry>,
}
/// One case summary.
///
/// - `created_at` — earliest `.m4a` mtime in the case (first dictation
/// in this case).
/// - `last_recording_at` — latest `.m4a` mtime (most recent dictation,
/// including addenda). This is the **primary sort key** for clients:
/// "when did the doctor last work on this case?". Absent only if the
/// case has no recordings at all (shouldn't happen in normal flow).
/// - `updated_at` — `oneliner.txt` mtime, i.e. when the oneliner text
/// was last regenerated. Diagnostic only — not for sort or display.
/// - `oneliner` — the text itself; `None` while transcription / LLM
/// generation is still pending.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OnelinerEntry {
pub case_id: String,
pub oneliner: Option<String>,
pub created_at: String,
pub last_recording_at: Option<String>,
pub updated_at: Option<String>,
}