refactor: split domain models, move presentation logic out of app layer
Some checks failed
CI / Check / Test (push) Failing after 47s

Split domain/models/mod.rs (630 lines) into focused files:
movie.rs, review.rs, user.rs, stats.rs, enrichment.rs, feed.rs.

Move URL/date formatting from application use cases to
presentation mappers — use cases now return raw domain data.

Delete watchlist/get_page.rs (was pure presentation logic),
replace with presentation/mappers/watchlist.rs.

Document signature conventions in CONTRIBUTING.md.
This commit is contained in:
2026-06-09 02:29:11 +02:00
parent ac03182aa6
commit 70b3ca0f5c
23 changed files with 761 additions and 1150 deletions

View File

@@ -0,0 +1,106 @@
use crate::value_objects::{ExternalMetadataId, MovieId, MovieTitle, PosterPath, ReleaseYear};
#[derive(Clone, Debug, Default)]
pub struct MovieFilter {
pub search: Option<String>,
pub genre: Option<String>,
pub language: Option<String>,
}
#[derive(Clone, Debug)]
pub struct MovieSummary {
pub movie: Movie,
pub genres: Vec<String>,
pub runtime_minutes: Option<u32>,
pub original_language: Option<String>,
pub overview: Option<String>,
pub collection_name: Option<String>,
}
#[derive(Clone, Debug)]
pub struct Movie {
id: MovieId,
external_metadata_id: Option<ExternalMetadataId>,
title: MovieTitle,
release_year: ReleaseYear,
director: Option<String>,
poster_path: Option<PosterPath>,
}
impl Movie {
pub fn new(
external_metadata_id: Option<ExternalMetadataId>,
title: MovieTitle,
release_year: ReleaseYear,
director: Option<String>,
poster_path: Option<PosterPath>,
) -> Self {
Self {
id: MovieId::generate(),
external_metadata_id,
title,
release_year,
director,
poster_path,
}
}
pub fn from_persistence(
id: MovieId,
external_metadata_id: Option<ExternalMetadataId>,
title: MovieTitle,
release_year: ReleaseYear,
director: Option<String>,
poster_path: Option<PosterPath>,
) -> Self {
Self {
id,
external_metadata_id,
title,
release_year,
director,
poster_path,
}
}
pub fn update_poster(&mut self, poster_path: PosterPath) {
self.poster_path = Some(poster_path);
}
pub fn id(&self) -> &MovieId {
&self.id
}
pub fn external_metadata_id(&self) -> Option<&ExternalMetadataId> {
self.external_metadata_id.as_ref()
}
pub fn title(&self) -> &MovieTitle {
&self.title
}
pub fn release_year(&self) -> &ReleaseYear {
&self.release_year
}
pub fn director(&self) -> Option<&str> {
self.director.as_deref()
}
pub fn poster_path(&self) -> Option<&PosterPath> {
self.poster_path.as_ref()
}
}
impl Movie {
pub fn is_manual_match(
&self,
title: &MovieTitle,
year: &ReleaseYear,
director: Option<&str>,
) -> bool {
if self.title != *title || self.release_year != *year {
return false;
}
match (self.director(), director) {
(Some(existing_dir), Some(new_dir)) => existing_dir.eq_ignore_ascii_case(new_dir),
_ => true,
}
}
}