HIGH: fix watch_medium data-loss bug, standardize error handling on ApiError, fix dep direction (rss/template-askama no longer dep on application), extract ImageFetcher port (remove reqwest from app layer), move event construction from save_review to use case, extract infra-wiring crate (DbPool/EventBusBackend dedup), deduplicate presentation helpers (encode_error, export streaming, multipart parsing) MEDIUM: split LocalApContentQuery god-trait 10→3 methods, dedup movie resolution orchestration, add RemoteActorDto/PersonDto mappers, move AppConfig to infra-wiring, fix SocialQueryPort Uuid→UserId, replace stringly-typed api-types with domain enums, move count_reviews_in_year to StatsRepository, dedup event publisher cfg blocks, extract should_enrich, move group_by_month to application, dedup count_local_posts, add FederationFlags Default, TUI input helper + ShowError rename + typed auth errors, api-types cleanup (UserSettingsDto/UserProfileBase/PreviewRowData) 102 files changed, -681 lines net
52 lines
1.5 KiB
Rust
52 lines
1.5 KiB
Rust
use domain::{
|
|
errors::DomainError,
|
|
events::DomainEvent,
|
|
models::Movie,
|
|
ports::{EventPublisher, MetadataClient, MovieRepository},
|
|
value_objects::MovieId,
|
|
};
|
|
|
|
use crate::diary::commands::MovieInput;
|
|
use crate::diary::movie_resolver::{MovieResolver, MovieResolverDeps};
|
|
|
|
/// Resolves a movie from input, persists it, and publishes `MovieDiscovered` if new.
|
|
///
|
|
/// Returns `(movie, is_new_movie)`.
|
|
pub async fn resolve_and_persist_movie(
|
|
input: &MovieInput,
|
|
movie_repo: &dyn MovieRepository,
|
|
metadata_client: &dyn MetadataClient,
|
|
event_publisher: &dyn EventPublisher,
|
|
) -> Result<(Movie, bool), DomainError> {
|
|
let (movie, is_new) = if let Some(id) = input.movie_id {
|
|
let movie_id = MovieId::from_uuid(id);
|
|
let movie = movie_repo
|
|
.get_movie_by_id(&movie_id)
|
|
.await?
|
|
.ok_or_else(|| DomainError::NotFound(format!("Movie {id}")))?;
|
|
(movie, false)
|
|
} else {
|
|
let deps = MovieResolverDeps {
|
|
repository: movie_repo,
|
|
metadata_client,
|
|
};
|
|
MovieResolver::default_pipeline()
|
|
.resolve(input, &deps)
|
|
.await?
|
|
};
|
|
|
|
if is_new {
|
|
movie_repo.upsert_movie(&movie).await?;
|
|
if let Some(ext_id) = movie.external_metadata_id() {
|
|
let _ = event_publisher
|
|
.publish(&DomainEvent::MovieDiscovered {
|
|
movie_id: movie.id().clone(),
|
|
external_metadata_id: ext_id.clone(),
|
|
})
|
|
.await;
|
|
}
|
|
}
|
|
|
|
Ok((movie, is_new))
|
|
}
|