summaryrefslogtreecommitdiff
path: root/makima/src/db/models.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/db/models.rs')
-rw-r--r--makima/src/db/models.rs101
1 files changed, 101 insertions, 0 deletions
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<String>,
+ #[sqlx(json)]
+ pub transcript: Vec<TranscriptEntry>,
+ pub location: Option<String>,
+ pub created_at: DateTime<Utc>,
+ pub updated_at: DateTime<Utc>,
+}
+
+/// 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<String>,
+ /// Optional description
+ pub description: Option<String>,
+ /// Transcript entries
+ pub transcript: Vec<TranscriptEntry>,
+ /// Storage location (e.g., s3://bucket/path) - not used yet
+ pub location: Option<String>,
+}
+
+/// Request payload for updating an existing file.
+#[derive(Debug, Deserialize, ToSchema)]
+#[serde(rename_all = "camelCase")]
+pub struct UpdateFileRequest {
+ /// New name (optional)
+ pub name: Option<String>,
+ /// New description (optional)
+ pub description: Option<String>,
+ /// New transcript (optional)
+ pub transcript: Option<Vec<TranscriptEntry>>,
+}
+
+/// Response for file list endpoint.
+#[derive(Debug, Serialize, ToSchema)]
+#[serde(rename_all = "camelCase")]
+pub struct FileListResponse {
+ pub files: Vec<FileSummary>,
+ 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<String>,
+ pub transcript_count: usize,
+ /// Duration derived from last transcript end time
+ pub duration: Option<f32>,
+ pub created_at: DateTime<Utc>,
+ pub updated_at: DateTime<Utc>,
+}
+
+impl From<File> 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,
+ }
+ }
+}