diff --git a/crates/application/src/commands.rs b/crates/application/src/commands.rs index c8b1df8..54d5009 100644 --- a/crates/application/src/commands.rs +++ b/crates/application/src/commands.rs @@ -29,3 +29,8 @@ pub struct RegisterCommand { pub email: String, pub password: String, } + +pub struct DeleteReviewCommand { + pub review_id: Uuid, + pub requesting_user_id: Uuid, +} diff --git a/crates/application/src/use_cases/delete_review.rs b/crates/application/src/use_cases/delete_review.rs new file mode 100644 index 0000000..9d19dfc --- /dev/null +++ b/crates/application/src/use_cases/delete_review.rs @@ -0,0 +1,27 @@ +use domain::{errors::DomainError, value_objects::{ReviewId, UserId}}; +use crate::{commands::DeleteReviewCommand, context::AppContext}; + +pub async fn execute(ctx: &AppContext, cmd: DeleteReviewCommand) -> Result<(), DomainError> { + let review_id = ReviewId::from_uuid(cmd.review_id); + let requesting_user_id = UserId::from_uuid(cmd.requesting_user_id); + + let review = ctx + .repository + .get_review_by_id(&review_id) + .await? + .ok_or_else(|| DomainError::NotFound(format!("review {}", cmd.review_id)))?; + + if review.user_id() != &requesting_user_id { + return Err(DomainError::Unauthorized("not your review".into())); + } + + let movie_id = review.movie_id().clone(); + ctx.repository.delete_review(&review_id).await?; + + let history = ctx.repository.get_review_history(&movie_id).await?; + if history.viewings().is_empty() { + ctx.repository.delete_movie(&movie_id).await?; + } + + Ok(()) +} diff --git a/crates/application/src/use_cases/mod.rs b/crates/application/src/use_cases/mod.rs index 8ba7998..63da43b 100644 --- a/crates/application/src/use_cases/mod.rs +++ b/crates/application/src/use_cases/mod.rs @@ -1,3 +1,4 @@ +pub mod delete_review; pub mod get_diary; pub mod get_review_history; pub mod log_review;