60 lines
1.7 KiB
Rust
60 lines
1.7 KiB
Rust
use domain::{
|
|
entities::Job,
|
|
errors::DomainError,
|
|
events::DomainEvent,
|
|
ports::{EventPublisher, JobBatchRepository, JobRepository},
|
|
value_objects::{DateTimeStamp, StructuredData, SystemId},
|
|
};
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
|
pub struct CompleteJobCommand {
|
|
pub job_id: SystemId,
|
|
pub result: StructuredData,
|
|
}
|
|
|
|
pub struct CompleteJobHandler {
|
|
job_repo: Arc<dyn JobRepository>,
|
|
batch_repo: Arc<dyn JobBatchRepository>,
|
|
event_pub: Arc<dyn EventPublisher>,
|
|
}
|
|
|
|
impl CompleteJobHandler {
|
|
pub fn new(
|
|
job_repo: Arc<dyn JobRepository>,
|
|
batch_repo: Arc<dyn JobBatchRepository>,
|
|
event_pub: Arc<dyn EventPublisher>,
|
|
) -> Self {
|
|
Self {
|
|
job_repo,
|
|
batch_repo,
|
|
event_pub,
|
|
}
|
|
}
|
|
|
|
pub async fn execute(&self, cmd: CompleteJobCommand) -> Result<Job, DomainError> {
|
|
let mut job = self
|
|
.job_repo
|
|
.find_by_id(&cmd.job_id)
|
|
.await?
|
|
.ok_or_else(|| DomainError::NotFound(format!("Job {} not found", cmd.job_id)))?;
|
|
job.complete(cmd.result);
|
|
self.job_repo.save(&job).await?;
|
|
if let Some(ref batch_id) = job.batch_id {
|
|
let mut batch =
|
|
self.batch_repo.find_by_id(batch_id).await?.ok_or_else(|| {
|
|
DomainError::NotFound(format!("Batch {} not found", batch_id))
|
|
})?;
|
|
batch.record_completion();
|
|
self.batch_repo.save(&batch).await?;
|
|
}
|
|
self.event_pub
|
|
.publish(DomainEvent::JobCompleted {
|
|
job_id: job.job_id,
|
|
timestamp: DateTimeStamp::now(),
|
|
})
|
|
.await?;
|
|
Ok(job)
|
|
}
|
|
}
|