refactor: store typed WrapUpReport in domain, serialize in adapters
Some checks failed
CI / Check / Test (push) Failing after 45s
Some checks failed
CI / Check / Test (push) Failing after 45s
This commit is contained in:
@@ -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<WrapUpRecord, DomainErro
|
||||
|
||||
let user_id = user_id_str.as_deref().map(parse_uuid).transpose()?;
|
||||
|
||||
let report = report_json.and_then(|j| serde_json::from_str(&j).ok());
|
||||
|
||||
Ok(WrapUpRecord {
|
||||
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
||||
user_id,
|
||||
start_date,
|
||||
end_date,
|
||||
status: parse_status(&status_str)?,
|
||||
report_json,
|
||||
report,
|
||||
error_message,
|
||||
created_at: parse_datetime(&created_at_str)?,
|
||||
completed_at: completed_at_str
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -79,7 +79,7 @@ impl WrapUpRepository for SqliteWrapUpRepository {
|
||||
.bind(&start)
|
||||
.bind(&end)
|
||||
.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(&created)
|
||||
.bind(&completed)
|
||||
@@ -110,15 +110,17 @@ impl WrapUpRepository for SqliteWrapUpRepository {
|
||||
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 = ?, 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<WrapUpRecord, DomainEr
|
||||
|
||||
let user_id = user_id_str.as_deref().map(parse_uuid).transpose()?;
|
||||
|
||||
let report = report_json.and_then(|j| serde_json::from_str(&j).ok());
|
||||
|
||||
Ok(WrapUpRecord {
|
||||
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
||||
user_id,
|
||||
start_date: parse_date(&start_date_str)?,
|
||||
end_date: parse_date(&end_date_str)?,
|
||||
status: parse_status(&status_str)?,
|
||||
report_json,
|
||||
report,
|
||||
error_message,
|
||||
created_at: parse_datetime(&created_at_str)?,
|
||||
completed_at: completed_at_str
|
||||
|
||||
@@ -39,7 +39,7 @@ pub async fn execute(ctx: &AppContext, cmd: RequestWrapUpCommand) -> Result<Wrap
|
||||
start_date: date_range.start(),
|
||||
end_date: date_range.end(),
|
||||
status: WrapUpStatus::Pending,
|
||||
report_json: None,
|
||||
report: None,
|
||||
error_message: None,
|
||||
created_at: Utc::now().naive_utc(),
|
||||
completed_at: None,
|
||||
|
||||
@@ -40,11 +40,9 @@ pub async fn execute(
|
||||
|
||||
match compute::execute(ctx, query).await {
|
||||
Ok(report) => {
|
||||
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 {
|
||||
|
||||
@@ -160,7 +160,7 @@ pub struct WrapUpRecord {
|
||||
pub start_date: NaiveDate,
|
||||
pub end_date: NaiveDate,
|
||||
pub status: WrapUpStatus,
|
||||
pub report_json: Option<String>,
|
||||
pub report: Option<WrapUpReport>,
|
||||
pub error_message: Option<String>,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub completed_at: Option<NaiveDateTime>,
|
||||
|
||||
@@ -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<Option<WrapUpRecord>, DomainError>;
|
||||
async fn list_for_user(&self, user_id: Uuid) -> Result<Vec<WrapUpRecord>, DomainError>;
|
||||
async fn list_global(&self) -> Result<Vec<WrapUpRecord>, DomainError>;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -134,8 +134,9 @@ pub async fn get_report(
|
||||
Path(id): Path<Uuid>,
|
||||
) -> 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(),
|
||||
};
|
||||
|
||||
|
||||
@@ -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!()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user