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 chrono::NaiveDate;
|
||||||
use domain::{
|
use domain::{
|
||||||
errors::DomainError,
|
errors::DomainError,
|
||||||
models::wrapup::{DateRange, WrapUpRecord, WrapUpScope, WrapUpStatus},
|
models::wrapup::{DateRange, WrapUpRecord, WrapUpReport, WrapUpScope, WrapUpStatus},
|
||||||
ports::{WrapUpMovieRow, WrapUpRepository, WrapUpStatsQuery},
|
ports::{WrapUpMovieRow, WrapUpRepository, WrapUpStatsQuery},
|
||||||
value_objects::WrapUpId,
|
value_objects::WrapUpId,
|
||||||
};
|
};
|
||||||
@@ -68,7 +68,7 @@ impl WrapUpRepository for PostgresWrapUpRepository {
|
|||||||
.bind(record.start_date)
|
.bind(record.start_date)
|
||||||
.bind(record.end_date)
|
.bind(record.end_date)
|
||||||
.bind(status)
|
.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.error_message)
|
||||||
.bind(record.created_at)
|
.bind(record.created_at)
|
||||||
.bind(record.completed_at)
|
.bind(record.completed_at)
|
||||||
@@ -99,15 +99,17 @@ impl WrapUpRepository for PostgresWrapUpRepository {
|
|||||||
Ok(())
|
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 id_str = id.value().to_string();
|
||||||
|
let json = serde_json::to_string(report)
|
||||||
|
.map_err(|e| DomainError::InfrastructureError(e.to_string()))?;
|
||||||
|
|
||||||
sqlx::query(
|
sqlx::query(
|
||||||
"UPDATE wrap_up_records \
|
"UPDATE wrap_up_records \
|
||||||
SET status = 'ready', report_json = $1, completed_at = NOW() \
|
SET status = 'ready', report_json = $1, completed_at = NOW() \
|
||||||
WHERE id = $2",
|
WHERE id = $2",
|
||||||
)
|
)
|
||||||
.bind(report_json)
|
.bind(&json)
|
||||||
.bind(&id_str)
|
.bind(&id_str)
|
||||||
.execute(&self.pool)
|
.execute(&self.pool)
|
||||||
.await
|
.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 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 {
|
Ok(WrapUpRecord {
|
||||||
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
||||||
user_id,
|
user_id,
|
||||||
start_date,
|
start_date,
|
||||||
end_date,
|
end_date,
|
||||||
status: parse_status(&status_str)?,
|
status: parse_status(&status_str)?,
|
||||||
report_json,
|
report,
|
||||||
error_message,
|
error_message,
|
||||||
created_at: parse_datetime(&created_at_str)?,
|
created_at: parse_datetime(&created_at_str)?,
|
||||||
completed_at: completed_at_str
|
completed_at: completed_at_str
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use async_trait::async_trait;
|
|||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
use domain::{
|
use domain::{
|
||||||
errors::DomainError,
|
errors::DomainError,
|
||||||
models::wrapup::{DateRange, WrapUpRecord, WrapUpScope, WrapUpStatus},
|
models::wrapup::{DateRange, WrapUpRecord, WrapUpReport, WrapUpScope, WrapUpStatus},
|
||||||
ports::{WrapUpMovieRow, WrapUpRepository, WrapUpStatsQuery},
|
ports::{WrapUpMovieRow, WrapUpRepository, WrapUpStatsQuery},
|
||||||
value_objects::WrapUpId,
|
value_objects::WrapUpId,
|
||||||
};
|
};
|
||||||
@@ -79,7 +79,7 @@ impl WrapUpRepository for SqliteWrapUpRepository {
|
|||||||
.bind(&start)
|
.bind(&start)
|
||||||
.bind(&end)
|
.bind(&end)
|
||||||
.bind(status)
|
.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.error_message)
|
||||||
.bind(&created)
|
.bind(&created)
|
||||||
.bind(&completed)
|
.bind(&completed)
|
||||||
@@ -110,15 +110,17 @@ impl WrapUpRepository for SqliteWrapUpRepository {
|
|||||||
Ok(())
|
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 id_str = id.value().to_string();
|
||||||
|
let json = serde_json::to_string(report)
|
||||||
|
.map_err(|e| DomainError::InfrastructureError(e.to_string()))?;
|
||||||
|
|
||||||
sqlx::query(
|
sqlx::query(
|
||||||
"UPDATE wrap_up_records \
|
"UPDATE wrap_up_records \
|
||||||
SET status = 'ready', report_json = ?, completed_at = strftime('%Y-%m-%d %H:%M:%S', 'now') \
|
SET status = 'ready', report_json = ?, completed_at = strftime('%Y-%m-%d %H:%M:%S', 'now') \
|
||||||
WHERE id = ?",
|
WHERE id = ?",
|
||||||
)
|
)
|
||||||
.bind(report_json)
|
.bind(&json)
|
||||||
.bind(&id_str)
|
.bind(&id_str)
|
||||||
.execute(&self.pool)
|
.execute(&self.pool)
|
||||||
.await
|
.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 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 {
|
Ok(WrapUpRecord {
|
||||||
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
||||||
user_id,
|
user_id,
|
||||||
start_date: parse_date(&start_date_str)?,
|
start_date: parse_date(&start_date_str)?,
|
||||||
end_date: parse_date(&end_date_str)?,
|
end_date: parse_date(&end_date_str)?,
|
||||||
status: parse_status(&status_str)?,
|
status: parse_status(&status_str)?,
|
||||||
report_json,
|
report,
|
||||||
error_message,
|
error_message,
|
||||||
created_at: parse_datetime(&created_at_str)?,
|
created_at: parse_datetime(&created_at_str)?,
|
||||||
completed_at: completed_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(),
|
start_date: date_range.start(),
|
||||||
end_date: date_range.end(),
|
end_date: date_range.end(),
|
||||||
status: WrapUpStatus::Pending,
|
status: WrapUpStatus::Pending,
|
||||||
report_json: None,
|
report: None,
|
||||||
error_message: None,
|
error_message: None,
|
||||||
created_at: Utc::now().naive_utc(),
|
created_at: Utc::now().naive_utc(),
|
||||||
completed_at: None,
|
completed_at: None,
|
||||||
|
|||||||
@@ -40,11 +40,9 @@ pub async fn execute(
|
|||||||
|
|
||||||
match compute::execute(ctx, query).await {
|
match compute::execute(ctx, query).await {
|
||||||
Ok(report) => {
|
Ok(report) => {
|
||||||
let json = serde_json::to_string(&report)
|
|
||||||
.map_err(|e| DomainError::InfrastructureError(e.to_string()))?;
|
|
||||||
ctx.repos
|
ctx.repos
|
||||||
.wrapup_repo
|
.wrapup_repo
|
||||||
.set_complete(&wrapup_id, &json)
|
.set_complete(&wrapup_id, &report)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let Some(ref renderer) = ctx.services.video_renderer {
|
if let Some(ref renderer) = ctx.services.video_renderer {
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ pub struct WrapUpRecord {
|
|||||||
pub start_date: NaiveDate,
|
pub start_date: NaiveDate,
|
||||||
pub end_date: NaiveDate,
|
pub end_date: NaiveDate,
|
||||||
pub status: WrapUpStatus,
|
pub status: WrapUpStatus,
|
||||||
pub report_json: Option<String>,
|
pub report: Option<WrapUpReport>,
|
||||||
pub error_message: Option<String>,
|
pub error_message: Option<String>,
|
||||||
pub created_at: NaiveDateTime,
|
pub created_at: NaiveDateTime,
|
||||||
pub completed_at: Option<NaiveDateTime>,
|
pub completed_at: Option<NaiveDateTime>,
|
||||||
|
|||||||
@@ -485,7 +485,7 @@ pub trait WrapUpRepository: Send + Sync {
|
|||||||
status: &WrapUpStatus,
|
status: &WrapUpStatus,
|
||||||
error: Option<&str>,
|
error: Option<&str>,
|
||||||
) -> Result<(), DomainError>;
|
) -> 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 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_for_user(&self, user_id: Uuid) -> Result<Vec<WrapUpRecord>, DomainError>;
|
||||||
async fn list_global(&self) -> 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();
|
let mut store = self.store.lock().unwrap();
|
||||||
if let Some(rec) = store.iter_mut().find(|r| r.id == *id) {
|
if let Some(rec) = store.iter_mut().find(|r| r.id == *id) {
|
||||||
rec.status = crate::models::wrapup::WrapUpStatus::Ready;
|
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());
|
rec.completed_at = Some(chrono::Utc::now().naive_utc());
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@@ -1189,7 +1189,7 @@ impl WrapUpRepository for PanicWrapUpRepository {
|
|||||||
) -> Result<(), DomainError> {
|
) -> Result<(), DomainError> {
|
||||||
panic!("PanicWrapUpRepository called")
|
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")
|
panic!("PanicWrapUpRepository called")
|
||||||
}
|
}
|
||||||
async fn get_by_id(
|
async fn get_by_id(
|
||||||
|
|||||||
@@ -134,8 +134,9 @@ pub async fn get_report(
|
|||||||
Path(id): Path<Uuid>,
|
Path(id): Path<Uuid>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
match get_wrapup::execute(&state.app_ctx, WrapUpId::from_uuid(id)).await {
|
match get_wrapup::execute(&state.app_ctx, WrapUpId::from_uuid(id)).await {
|
||||||
Ok(Some(record)) if record.status == WrapUpStatus::Ready => match record.report_json {
|
Ok(Some(record)) if record.status == WrapUpStatus::Ready => match record.report {
|
||||||
Some(json) => {
|
Some(ref report) => {
|
||||||
|
let json = serde_json::to_string(report).unwrap_or_default();
|
||||||
(StatusCode::OK, [("content-type", "application/json")], json).into_response()
|
(StatusCode::OK, [("content-type", "application/json")], json).into_response()
|
||||||
}
|
}
|
||||||
None => StatusCode::NOT_FOUND.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(),
|
_ => return StatusCode::NOT_FOUND.into_response(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let report: WrapUpReport = match &record.report_json {
|
let report = match record.report {
|
||||||
Some(json) => match serde_json::from_str(json) {
|
Some(r) => r,
|
||||||
Ok(r) => r,
|
|
||||||
Err(_) => return StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
|
||||||
},
|
|
||||||
None => return StatusCode::NOT_FOUND.into_response(),
|
None => return StatusCode::NOT_FOUND.into_response(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -334,11 +332,8 @@ pub async fn get_global_wrapup_html(
|
|||||||
_ => return StatusCode::NOT_FOUND.into_response(),
|
_ => return StatusCode::NOT_FOUND.into_response(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let report: WrapUpReport = match &record.report_json {
|
let report = match record.report {
|
||||||
Some(json) => match serde_json::from_str(json) {
|
Some(r) => r,
|
||||||
Ok(r) => r,
|
|
||||||
Err(_) => return StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
|
||||||
},
|
|
||||||
None => return StatusCode::NOT_FOUND.into_response(),
|
None => return StatusCode::NOT_FOUND.into_response(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -602,7 +602,7 @@ impl domain::ports::WrapUpRepository for Panic {
|
|||||||
async fn set_complete(
|
async fn set_complete(
|
||||||
&self,
|
&self,
|
||||||
_: &domain::value_objects::WrapUpId,
|
_: &domain::value_objects::WrapUpId,
|
||||||
_: &str,
|
_: &domain::models::wrapup::WrapUpReport,
|
||||||
) -> Result<(), DomainError> {
|
) -> Result<(), DomainError> {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user