fix: NewRemoteReview param struct, atomic review+orphan movie delete

This commit is contained in:
2026-10-26 01:19:09 +01:00
parent 9a4d0c1714
commit 7f9c252d35
18 changed files with 261 additions and 116 deletions

View File

@@ -557,7 +557,13 @@ impl ReviewRepository for PanicReviewRepository {
async fn update_review(&self, _: &Review, _: &[DomainEvent]) -> Result<(), DomainError> {
panic!("PanicReviewRepository called")
}
async fn delete_review(&self, _: &ReviewId, _: &[DomainEvent]) -> Result<(), DomainError> {
async fn delete_review_and_orphaned_movie(
&self,
_: &ReviewId,
_: &MovieId,
_: &[DomainEvent],
_: &[DomainEvent],
) -> Result<(), DomainError> {
panic!("PanicReviewRepository called")
}
async fn get_all_reviews_for_user(&self, _: &UserId) -> Result<Vec<Review>, DomainError> {

View File

@@ -37,7 +37,13 @@ impl ReviewRepository for RefusingReviewRepository {
async fn update_review(&self, _: &Review, _: &[DomainEvent]) -> Result<(), DomainError> {
Err(refused())
}
async fn delete_review(&self, _: &ReviewId, _: &[DomainEvent]) -> Result<(), DomainError> {
async fn delete_review_and_orphaned_movie(
&self,
_: &ReviewId,
_: &MovieId,
_: &[DomainEvent],
_: &[DomainEvent],
) -> Result<(), DomainError> {
Err(refused())
}
async fn get_all_reviews_for_user(&self, _: &UserId) -> Result<Vec<Review>, DomainError> {

View File

@@ -60,6 +60,15 @@ impl MovieCommand for InMemoryStore {
"Database operation failed".into(),
));
}
self.remove_movie_with_cascades(id);
self.record_events(events);
Ok(())
}
}
impl InMemoryStore {
/// Removes the movie row and applies the schema's cascades.
pub(super) fn remove_movie_with_cascades(&self, id: uuid::Uuid) {
self.movies.write().unwrap().remove(&id);
self.watchlist
.write()
@@ -72,9 +81,6 @@ impl MovieCommand for InMemoryStore {
*event = detached_from_movie(event);
}
}
drop(events_guard);
self.record_events(events);
Ok(())
}
}

View File

@@ -5,7 +5,7 @@ use crate::{
events::DomainEvent,
models::Review,
ports::ReviewRepository,
value_objects::{ReviewId, UserId},
value_objects::{MovieId, ReviewId, UserId},
};
use super::InMemoryStore;
@@ -47,13 +47,24 @@ impl ReviewRepository for InMemoryStore {
Ok(())
}
async fn delete_review(
async fn delete_review_and_orphaned_movie(
&self,
review_id: &ReviewId,
events: &[DomainEvent],
movie_id: &MovieId,
review_events: &[DomainEvent],
orphan_events: &[DomainEvent],
) -> Result<(), DomainError> {
self.reviews.write().unwrap().remove(&review_id.value());
self.record_events(events);
let movie = movie_id.value();
let still_referenced = {
let mut reviews = self.reviews.write().unwrap();
reviews.remove(&review_id.value());
reviews.values().any(|r| r.movie_id().value() == movie)
};
self.record_events(review_events);
if !still_referenced && self.movies.read().unwrap().contains_key(&movie) {
self.remove_movie_with_cascades(movie);
self.record_events(orphan_events);
}
Ok(())
}