Files
movies-diary/crates/application/src/diary/edit_review.rs
Gabriel Kaszewski bb2001b9cc Add Spoiler Flag with veil, AP content-warning encoding, and full-stack plumbing
Authors can flag a review's comment as containing spoilers; the comment is
blurred behind a reveal control for every viewer except the author, omitted
from RSS, and federates as containsSpoilers plus an AP summary content
warning (ADR-0011) so Mastodon-class clients also collapse it. Flag follows
the general-edit path (ADR-0001) across domain, both DB backends, REST,
HTML templates, SPA (shadcn), TUI fixtures, and exports.
2026-10-17 21:12:56 +02:00

62 lines
1.8 KiB
Rust

use crate::diary::{commands::EditReviewCommand, deps::EditReviewDeps};
use domain::{
errors::DomainError,
events::DomainEvent,
models::ReviewEdit,
value_objects::{Comment, Rating, ReviewId, UserId},
};
pub async fn execute(deps: &EditReviewDeps, cmd: EditReviewCommand) -> Result<(), DomainError> {
let review_id = ReviewId::from_uuid(cmd.review_id);
let requesting_user_id = UserId::from_uuid(cmd.requesting_user_id);
let review = deps
.review
.get_review_by_id(&review_id)
.await?
.ok_or_else(|| DomainError::NotFound(format!("review {}", cmd.review_id)))?;
if review.is_remote() {
return Err(DomainError::Forbidden(
"cannot edit a federated review".into(),
));
}
if review.user_id() != &requesting_user_id {
return Err(DomainError::Forbidden("not your review".into()));
}
let updated = review.apply_edit(ReviewEdit {
rating: cmd.rating.map(Rating::new).transpose()?,
comment: cmd
.comment
.map(|c| c.map(Comment::new).transpose())
.transpose()?,
watched_at: cmd.watched_at,
watch_medium: cmd.watch_medium,
spoilers: cmd.spoilers,
});
deps.review.update_review(&updated).await?;
if let Err(e) = deps
.event_publisher
.publish(&DomainEvent::ReviewUpdated {
review_id: updated.id().clone(),
movie_id: updated.movie_id().clone(),
user_id: updated.user_id().clone(),
rating: updated.rating().clone(),
watched_at: *updated.watched_at(),
})
.await
{
tracing::warn!("failed to publish ReviewUpdated: {e}");
}
Ok(())
}
#[cfg(test)]
#[path = "tests/edit_review.rs"]
mod tests;