diff --git a/crates/adapters/postgres/src/wrapup.rs b/crates/adapters/postgres/src/wrapup.rs index 36e55ad..8815ef9 100644 --- a/crates/adapters/postgres/src/wrapup.rs +++ b/crates/adapters/postgres/src/wrapup.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use chrono::NaiveDate; use domain::{ errors::DomainError, - models::wrapup::{DateRange, WrapUpRecord, WrapUpScope, WrapUpStatus}, + models::wrapup::{DateRange, WrapUpRecord, WrapUpReport, WrapUpScope, WrapUpStatus}, ports::{WrapUpMovieRow, WrapUpRepository, WrapUpStatsQuery}, value_objects::WrapUpId, }; @@ -68,7 +68,7 @@ impl WrapUpRepository for PostgresWrapUpRepository { .bind(record.start_date) .bind(record.end_date) .bind(status) - .bind(&record.report_json) + .bind(record.report.as_ref().and_then(|r| serde_json::to_string(r).ok())) .bind(&record.error_message) .bind(record.created_at) .bind(record.completed_at) @@ -99,15 +99,17 @@ impl WrapUpRepository for PostgresWrapUpRepository { Ok(()) } - async fn set_complete(&self, id: &WrapUpId, report_json: &str) -> Result<(), DomainError> { + async fn set_complete(&self, id: &WrapUpId, report: &WrapUpReport) -> Result<(), DomainError> { let id_str = id.value().to_string(); + let json = serde_json::to_string(report) + .map_err(|e| DomainError::InfrastructureError(e.to_string()))?; sqlx::query( "UPDATE wrap_up_records \ SET status = 'ready', report_json = $1, completed_at = NOW() \ WHERE id = $2", ) - .bind(report_json) + .bind(&json) .bind(&id_str) .execute(&self.pool) .await @@ -227,13 +229,15 @@ fn row_to_record(row: &sqlx::postgres::PgRow) -> Result Result<(), DomainError> { + async fn set_complete(&self, id: &WrapUpId, report: &WrapUpReport) -> Result<(), DomainError> { let id_str = id.value().to_string(); + let json = serde_json::to_string(report) + .map_err(|e| DomainError::InfrastructureError(e.to_string()))?; sqlx::query( "UPDATE wrap_up_records \ SET status = 'ready', report_json = ?, completed_at = strftime('%Y-%m-%d %H:%M:%S', 'now') \ WHERE id = ?", ) - .bind(report_json) + .bind(&json) .bind(&id_str) .execute(&self.pool) .await @@ -238,13 +240,15 @@ fn row_to_record(row: &sqlx::sqlite::SqliteRow) -> Result Result { - let json = serde_json::to_string(&report) - .map_err(|e| DomainError::InfrastructureError(e.to_string()))?; ctx.repos .wrapup_repo - .set_complete(&wrapup_id, &json) + .set_complete(&wrapup_id, &report) .await?; if let Some(ref renderer) = ctx.services.video_renderer { diff --git a/crates/domain/src/models/wrapup.rs b/crates/domain/src/models/wrapup.rs index 8752221..6619bb2 100644 --- a/crates/domain/src/models/wrapup.rs +++ b/crates/domain/src/models/wrapup.rs @@ -160,7 +160,7 @@ pub struct WrapUpRecord { pub start_date: NaiveDate, pub end_date: NaiveDate, pub status: WrapUpStatus, - pub report_json: Option, + pub report: Option, pub error_message: Option, pub created_at: NaiveDateTime, pub completed_at: Option, diff --git a/crates/domain/src/ports.rs b/crates/domain/src/ports.rs index 86e7d97..c153b27 100644 --- a/crates/domain/src/ports.rs +++ b/crates/domain/src/ports.rs @@ -485,7 +485,7 @@ pub trait WrapUpRepository: Send + Sync { status: &WrapUpStatus, error: Option<&str>, ) -> Result<(), DomainError>; - async fn set_complete(&self, id: &WrapUpId, report_json: &str) -> Result<(), DomainError>; + async fn set_complete(&self, id: &WrapUpId, report: &WrapUpReport) -> Result<(), DomainError>; async fn get_by_id(&self, id: &WrapUpId) -> Result, DomainError>; async fn list_for_user(&self, user_id: Uuid) -> Result, DomainError>; async fn list_global(&self) -> Result, DomainError>; diff --git a/crates/domain/src/testing.rs b/crates/domain/src/testing.rs index c47abb1..893a0c7 100644 --- a/crates/domain/src/testing.rs +++ b/crates/domain/src/testing.rs @@ -1099,11 +1099,11 @@ impl WrapUpRepository for InMemoryWrapUpRepository { } } - async fn set_complete(&self, id: &WrapUpId, report_json: &str) -> Result<(), DomainError> { + async fn set_complete(&self, id: &WrapUpId, report: &crate::models::wrapup::WrapUpReport) -> Result<(), DomainError> { let mut store = self.store.lock().unwrap(); if let Some(rec) = store.iter_mut().find(|r| r.id == *id) { rec.status = crate::models::wrapup::WrapUpStatus::Ready; - rec.report_json = Some(report_json.to_string()); + rec.report = Some(report.clone()); rec.completed_at = Some(chrono::Utc::now().naive_utc()); Ok(()) } else { @@ -1189,7 +1189,7 @@ impl WrapUpRepository for PanicWrapUpRepository { ) -> Result<(), DomainError> { panic!("PanicWrapUpRepository called") } - async fn set_complete(&self, _: &WrapUpId, _: &str) -> Result<(), DomainError> { + async fn set_complete(&self, _: &WrapUpId, _: &crate::models::wrapup::WrapUpReport) -> Result<(), DomainError> { panic!("PanicWrapUpRepository called") } async fn get_by_id( diff --git a/crates/presentation/src/handlers/wrapup.rs b/crates/presentation/src/handlers/wrapup.rs index 3a603d5..692c3fc 100644 --- a/crates/presentation/src/handlers/wrapup.rs +++ b/crates/presentation/src/handlers/wrapup.rs @@ -134,8 +134,9 @@ pub async fn get_report( Path(id): Path, ) -> impl IntoResponse { match get_wrapup::execute(&state.app_ctx, WrapUpId::from_uuid(id)).await { - Ok(Some(record)) if record.status == WrapUpStatus::Ready => match record.report_json { - Some(json) => { + Ok(Some(record)) if record.status == WrapUpStatus::Ready => match record.report { + Some(ref report) => { + let json = serde_json::to_string(report).unwrap_or_default(); (StatusCode::OK, [("content-type", "application/json")], json).into_response() } None => StatusCode::NOT_FOUND.into_response(), @@ -295,11 +296,8 @@ pub async fn get_user_wrapup_html( _ => return StatusCode::NOT_FOUND.into_response(), }; - let report: WrapUpReport = match &record.report_json { - Some(json) => match serde_json::from_str(json) { - Ok(r) => r, - Err(_) => return StatusCode::INTERNAL_SERVER_ERROR.into_response(), - }, + let report = match record.report { + Some(r) => r, None => return StatusCode::NOT_FOUND.into_response(), }; @@ -334,11 +332,8 @@ pub async fn get_global_wrapup_html( _ => return StatusCode::NOT_FOUND.into_response(), }; - let report: WrapUpReport = match &record.report_json { - Some(json) => match serde_json::from_str(json) { - Ok(r) => r, - Err(_) => return StatusCode::INTERNAL_SERVER_ERROR.into_response(), - }, + let report = match record.report { + Some(r) => r, None => return StatusCode::NOT_FOUND.into_response(), }; diff --git a/crates/presentation/src/tests/extractors.rs b/crates/presentation/src/tests/extractors.rs index 2a1601a..0da1a83 100644 --- a/crates/presentation/src/tests/extractors.rs +++ b/crates/presentation/src/tests/extractors.rs @@ -602,7 +602,7 @@ impl domain::ports::WrapUpRepository for Panic { async fn set_complete( &self, _: &domain::value_objects::WrapUpId, - _: &str, + _: &domain::models::wrapup::WrapUpReport, ) -> Result<(), DomainError> { panic!() }