From a32dc56d2e5447ef8988cb98b8686476cc94e70c Mon Sep 17 00:00:00 2001 From: soryu Date: Tue, 23 Dec 2025 02:14:58 +0000 Subject: Add Postgres for persistence and File cabinet Migrations are local only currently, and must be run manually by setting POSTGRES_CONNECTION_URI --- makima/src/db/models.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 makima/src/db/models.rs (limited to 'makima/src/db/models.rs') diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs new file mode 100644 index 0000000..45b0e53 --- /dev/null +++ b/makima/src/db/models.rs @@ -0,0 +1,101 @@ +//! Database models for the files table. + +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use sqlx::FromRow; +use utoipa::ToSchema; +use uuid::Uuid; + +/// TranscriptEntry stored in JSONB - matches frontend TranscriptEntry +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct TranscriptEntry { + pub id: String, + pub speaker: String, + pub start: f32, + pub end: f32, + pub text: String, + pub is_final: bool, +} + +/// File record from the database. +#[derive(Debug, Clone, FromRow, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct File { + pub id: Uuid, + pub owner_id: Uuid, + pub name: String, + pub description: Option, + #[sqlx(json)] + pub transcript: Vec, + pub location: Option, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +/// Request payload for creating a new file. +#[derive(Debug, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct CreateFileRequest { + /// Name of the file (auto-generated if not provided) + pub name: Option, + /// Optional description + pub description: Option, + /// Transcript entries + pub transcript: Vec, + /// Storage location (e.g., s3://bucket/path) - not used yet + pub location: Option, +} + +/// Request payload for updating an existing file. +#[derive(Debug, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct UpdateFileRequest { + /// New name (optional) + pub name: Option, + /// New description (optional) + pub description: Option, + /// New transcript (optional) + pub transcript: Option>, +} + +/// Response for file list endpoint. +#[derive(Debug, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct FileListResponse { + pub files: Vec, + pub total: i64, +} + +/// Summary of a file for list views (excludes full transcript). +#[derive(Debug, Clone, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct FileSummary { + pub id: Uuid, + pub name: String, + pub description: Option, + pub transcript_count: usize, + /// Duration derived from last transcript end time + pub duration: Option, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +impl From for FileSummary { + fn from(file: File) -> Self { + let duration = file + .transcript + .iter() + .map(|t| t.end) + .fold(0.0_f32, f32::max); + Self { + id: file.id, + name: file.name, + description: file.description, + transcript_count: file.transcript.len(), + duration: if duration > 0.0 { Some(duration) } else { None }, + created_at: file.created_at, + updated_at: file.updated_at, + } + } +} -- cgit v1.2.3