summaryrefslogtreecommitdiff
path: root/makima/src/db
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/db')
-rw-r--r--makima/src/db/models.rs43
-rw-r--r--makima/src/db/repository.rs21
2 files changed, 57 insertions, 7 deletions
diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs
index 45b0e53..135ae75 100644
--- a/makima/src/db/models.rs
+++ b/makima/src/db/models.rs
@@ -18,6 +18,40 @@ pub struct TranscriptEntry {
pub is_final: bool,
}
+/// Chart type for visualization elements
+#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
+#[serde(rename_all = "lowercase")]
+pub enum ChartType {
+ Line,
+ Bar,
+ Pie,
+ Area,
+}
+
+/// Body element types for structured file content
+#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
+#[serde(tag = "type", rename_all = "camelCase")]
+pub enum BodyElement {
+ /// Heading element (h1-h6)
+ Heading { level: u8, text: String },
+ /// Paragraph text
+ Paragraph { text: String },
+ /// Chart visualization
+ Chart {
+ #[serde(rename = "chartType")]
+ chart_type: ChartType,
+ title: Option<String>,
+ data: serde_json::Value,
+ config: Option<serde_json::Value>,
+ },
+ /// Image element (deferred for MVP)
+ Image {
+ src: String,
+ alt: Option<String>,
+ caption: Option<String>,
+ },
+}
+
/// File record from the database.
#[derive(Debug, Clone, FromRow, Serialize, ToSchema)]
#[serde(rename_all = "camelCase")]
@@ -29,6 +63,11 @@ pub struct File {
#[sqlx(json)]
pub transcript: Vec<TranscriptEntry>,
pub location: Option<String>,
+ /// AI-generated summary of the transcript
+ pub summary: Option<String>,
+ /// Structured body content (headings, paragraphs, charts)
+ #[sqlx(json)]
+ pub body: Vec<BodyElement>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -57,6 +96,10 @@ pub struct UpdateFileRequest {
pub description: Option<String>,
/// New transcript (optional)
pub transcript: Option<Vec<TranscriptEntry>>,
+ /// AI-generated summary (optional)
+ pub summary: Option<String>,
+ /// Structured body content (optional)
+ pub body: Option<Vec<BodyElement>>,
}
/// Response for file list endpoint.
diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs
index 90cb1b9..f8b90b3 100644
--- a/makima/src/db/repository.rs
+++ b/makima/src/db/repository.rs
@@ -19,12 +19,13 @@ fn generate_default_name() -> String {
pub async fn create_file(pool: &PgPool, req: CreateFileRequest) -> Result<File, sqlx::Error> {
let name = req.name.unwrap_or_else(generate_default_name);
let transcript_json = serde_json::to_value(&req.transcript).unwrap_or_default();
+ let body_json = serde_json::to_value::<Vec<super::models::BodyElement>>(vec![]).unwrap();
sqlx::query_as::<_, File>(
r#"
- INSERT INTO files (owner_id, name, description, transcript, location)
- VALUES ($1, $2, $3, $4, $5)
- RETURNING id, owner_id, name, description, transcript, location, created_at, updated_at
+ INSERT INTO files (owner_id, name, description, transcript, location, summary, body)
+ VALUES ($1, $2, $3, $4, $5, NULL, $6)
+ RETURNING id, owner_id, name, description, transcript, location, summary, body, created_at, updated_at
"#,
)
.bind(ANONYMOUS_OWNER_ID)
@@ -32,6 +33,7 @@ pub async fn create_file(pool: &PgPool, req: CreateFileRequest) -> Result<File,
.bind(&req.description)
.bind(&transcript_json)
.bind(&req.location)
+ .bind(&body_json)
.fetch_one(pool)
.await
}
@@ -40,7 +42,7 @@ pub async fn create_file(pool: &PgPool, req: CreateFileRequest) -> Result<File,
pub async fn get_file(pool: &PgPool, id: Uuid) -> Result<Option<File>, sqlx::Error> {
sqlx::query_as::<_, File>(
r#"
- SELECT id, owner_id, name, description, transcript, location, created_at, updated_at
+ SELECT id, owner_id, name, description, transcript, location, summary, body, created_at, updated_at
FROM files
WHERE id = $1 AND owner_id = $2
"#,
@@ -55,7 +57,7 @@ pub async fn get_file(pool: &PgPool, id: Uuid) -> Result<Option<File>, sqlx::Err
pub async fn list_files(pool: &PgPool) -> Result<Vec<File>, sqlx::Error> {
sqlx::query_as::<_, File>(
r#"
- SELECT id, owner_id, name, description, transcript, location, created_at, updated_at
+ SELECT id, owner_id, name, description, transcript, location, summary, body, created_at, updated_at
FROM files
WHERE owner_id = $1
ORDER BY created_at DESC
@@ -83,13 +85,16 @@ pub async fn update_file(
let description = req.description.or(existing.description);
let transcript = req.transcript.unwrap_or(existing.transcript);
let transcript_json = serde_json::to_value(&transcript).unwrap_or_default();
+ let summary = req.summary.or(existing.summary);
+ let body = req.body.unwrap_or(existing.body);
+ let body_json = serde_json::to_value(&body).unwrap_or_default();
sqlx::query_as::<_, File>(
r#"
UPDATE files
- SET name = $3, description = $4, transcript = $5
+ SET name = $3, description = $4, transcript = $5, summary = $6, body = $7, updated_at = NOW()
WHERE id = $1 AND owner_id = $2
- RETURNING id, owner_id, name, description, transcript, location, created_at, updated_at
+ RETURNING id, owner_id, name, description, transcript, location, summary, body, created_at, updated_at
"#,
)
.bind(id)
@@ -97,6 +102,8 @@ pub async fn update_file(
.bind(&name)
.bind(&description)
.bind(&transcript_json)
+ .bind(&summary)
+ .bind(&body_json)
.fetch_optional(pool)
.await
}