domain: add person enrichment fields, event, port
This commit is contained in:
@@ -3,6 +3,7 @@ use chrono::NaiveDateTime;
|
||||
|
||||
use crate::{
|
||||
errors::DomainError,
|
||||
models::PersonId,
|
||||
value_objects::{
|
||||
ExternalMetadataId, GoalId, MovieId, PosterPath, Rating, ReviewId, UserId, WrapUpId,
|
||||
},
|
||||
@@ -43,6 +44,10 @@ pub enum DomainEvent {
|
||||
movie_id: MovieId,
|
||||
external_metadata_id: String,
|
||||
},
|
||||
PersonEnrichmentRequested {
|
||||
person_id: PersonId,
|
||||
external_person_id: String,
|
||||
},
|
||||
ImageStored {
|
||||
key: String,
|
||||
},
|
||||
|
||||
@@ -43,7 +43,9 @@ pub use import::{
|
||||
};
|
||||
pub use import_profile::ImportProfile;
|
||||
pub use import_session::ImportSession;
|
||||
pub use person::{CastCredit, CrewCredit, ExternalPersonId, Person, PersonCredits, PersonId};
|
||||
pub use person::{
|
||||
CastCredit, CrewCredit, ExternalPersonId, Person, PersonCredits, PersonEnrichmentData, PersonId,
|
||||
};
|
||||
pub use search::{
|
||||
EntityType, IndexableDocument, MovieSearchHit, PersonSearchHit, SearchFilters, SearchQuery,
|
||||
SearchResults,
|
||||
|
||||
@@ -46,15 +46,56 @@ pub struct Person {
|
||||
name: String,
|
||||
known_for_department: Option<String>,
|
||||
profile_path: Option<String>,
|
||||
biography: Option<String>,
|
||||
birthday: Option<chrono::NaiveDate>,
|
||||
deathday: Option<chrono::NaiveDate>,
|
||||
place_of_birth: Option<String>,
|
||||
also_known_as: Vec<String>,
|
||||
homepage: Option<String>,
|
||||
imdb_id: Option<String>,
|
||||
enriched_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
}
|
||||
|
||||
impl Person {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
id: PersonId,
|
||||
external_id: ExternalPersonId,
|
||||
name: String,
|
||||
known_for_department: Option<String>,
|
||||
profile_path: Option<String>,
|
||||
biography: Option<String>,
|
||||
birthday: Option<chrono::NaiveDate>,
|
||||
deathday: Option<chrono::NaiveDate>,
|
||||
place_of_birth: Option<String>,
|
||||
also_known_as: Vec<String>,
|
||||
homepage: Option<String>,
|
||||
imdb_id: Option<String>,
|
||||
enriched_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
external_id,
|
||||
name,
|
||||
known_for_department,
|
||||
profile_path,
|
||||
biography,
|
||||
birthday,
|
||||
deathday,
|
||||
place_of_birth,
|
||||
also_known_as,
|
||||
homepage,
|
||||
imdb_id,
|
||||
enriched_at,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn basic(
|
||||
id: PersonId,
|
||||
external_id: ExternalPersonId,
|
||||
name: String,
|
||||
known_for_department: Option<String>,
|
||||
profile_path: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
@@ -62,6 +103,14 @@ impl Person {
|
||||
name,
|
||||
known_for_department,
|
||||
profile_path,
|
||||
biography: None,
|
||||
birthday: None,
|
||||
deathday: None,
|
||||
place_of_birth: None,
|
||||
also_known_as: vec![],
|
||||
homepage: None,
|
||||
imdb_id: None,
|
||||
enriched_at: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +133,49 @@ impl Person {
|
||||
pub fn profile_path(&self) -> Option<&str> {
|
||||
self.profile_path.as_deref()
|
||||
}
|
||||
|
||||
pub fn biography(&self) -> Option<&str> {
|
||||
self.biography.as_deref()
|
||||
}
|
||||
|
||||
pub fn birthday(&self) -> Option<chrono::NaiveDate> {
|
||||
self.birthday
|
||||
}
|
||||
|
||||
pub fn deathday(&self) -> Option<chrono::NaiveDate> {
|
||||
self.deathday
|
||||
}
|
||||
|
||||
pub fn place_of_birth(&self) -> Option<&str> {
|
||||
self.place_of_birth.as_deref()
|
||||
}
|
||||
|
||||
pub fn also_known_as(&self) -> &[String] {
|
||||
&self.also_known_as
|
||||
}
|
||||
|
||||
pub fn homepage(&self) -> Option<&str> {
|
||||
self.homepage.as_deref()
|
||||
}
|
||||
|
||||
pub fn imdb_id(&self) -> Option<&str> {
|
||||
self.imdb_id.as_deref()
|
||||
}
|
||||
|
||||
pub fn enriched_at(&self) -> Option<chrono::DateTime<chrono::Utc>> {
|
||||
self.enriched_at
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PersonEnrichmentData {
|
||||
pub biography: Option<String>,
|
||||
pub birthday: Option<chrono::NaiveDate>,
|
||||
pub deathday: Option<chrono::NaiveDate>,
|
||||
pub place_of_birth: Option<String>,
|
||||
pub also_known_as: Vec<String>,
|
||||
pub homepage: Option<String>,
|
||||
pub imdb_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
||||
@@ -4,7 +4,7 @@ use super::*;
|
||||
fn person_new() {
|
||||
let ext = ExternalPersonId::new("tmdb:12345");
|
||||
let pid = PersonId::from_external(&ext);
|
||||
let p = Person::new(
|
||||
let p = Person::basic(
|
||||
pid,
|
||||
ext,
|
||||
"Keanu Reeves".into(),
|
||||
@@ -38,7 +38,7 @@ fn person_id_deterministic() {
|
||||
fn person_credits_default_empty() {
|
||||
let ext = ExternalPersonId::new("tmdb:1");
|
||||
let pid = PersonId::from_external(&ext);
|
||||
let p = Person::new(pid, ext, "Test".into(), None, None);
|
||||
let p = Person::basic(pid, ext, "Test".into(), None, None);
|
||||
let credits = PersonCredits {
|
||||
person: p,
|
||||
cast: vec![],
|
||||
|
||||
@@ -10,9 +10,9 @@ use crate::{
|
||||
AnnotatedRow, DiaryEntry, DiaryFilter, EntityType, ExportFormat, ExternalPersonId,
|
||||
FeedEntry, FieldMapping, FileFormat, Goal, ImportError, ImportProfile, ImportSession,
|
||||
IndexableDocument, Movie, MovieFilter, MovieProfile, MovieStats, MovieSummary, ParsedFile,
|
||||
ParsedPlaybackEvent, Person, PersonCredits, PersonId, RemoteGoalEntry,
|
||||
RemoteWatchlistEntry, Review, ReviewHistory, SearchQuery, SearchResults, User,
|
||||
UserSettings, UserStats, UserSummary, UserTrends, WatchEvent, WatchEventStatus,
|
||||
ParsedPlaybackEvent, Person, PersonCredits, PersonEnrichmentData, PersonId,
|
||||
RemoteGoalEntry, RemoteWatchlistEntry, Review, ReviewHistory, SearchQuery, SearchResults,
|
||||
User, UserSettings, UserStats, UserSummary, UserTrends, WatchEvent, WatchEventStatus,
|
||||
WatchlistEntry, WatchlistWithMovie, WebhookToken,
|
||||
collections::{self, PageParams, Paginated},
|
||||
wrapup::{DateRange, WrapUpRecord, WrapUpScope, WrapUpStatus},
|
||||
@@ -292,6 +292,14 @@ pub trait MovieEnrichmentClient: Send + Sync {
|
||||
) -> Result<MovieProfile, DomainError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait PersonEnrichmentClient: Send + Sync {
|
||||
async fn fetch_details(
|
||||
&self,
|
||||
external_id: &str,
|
||||
) -> Result<PersonEnrichmentData, DomainError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait ImportSessionRepository: Send + Sync {
|
||||
async fn create(&self, session: &ImportSession) -> Result<(), DomainError>;
|
||||
@@ -339,6 +347,11 @@ pub trait PersonCommand: Send + Sync {
|
||||
&self,
|
||||
batch_size: u32,
|
||||
) -> Result<(u64, bool), DomainError>;
|
||||
async fn update_enrichment(
|
||||
&self,
|
||||
id: &PersonId,
|
||||
data: &PersonEnrichmentData,
|
||||
) -> Result<(), DomainError>;
|
||||
}
|
||||
|
||||
/// Read port — queries persons and credits. No mutations.
|
||||
|
||||
@@ -223,7 +223,7 @@ impl PersonQuery for FakePersonQuery {
|
||||
}
|
||||
|
||||
async fn get_credits(&self, id: &PersonId) -> Result<PersonCredits, DomainError> {
|
||||
let dummy = Person::new(
|
||||
let dummy = Person::basic(
|
||||
id.clone(),
|
||||
ExternalPersonId::new("tmdb:0"),
|
||||
"Unknown".into(),
|
||||
|
||||
@@ -5,7 +5,8 @@ use crate::{
|
||||
models::{
|
||||
AnnotatedRow, DiaryEntry, DiaryFilter, EntityType, ExportFormat, ExternalPersonId,
|
||||
FeedEntry, FieldMapping, FileFormat, ImportError, ImportProfile, ImportSession,
|
||||
IndexableDocument, MovieProfile, MovieStats, ParsedFile, Person, PersonCredits, PersonId,
|
||||
IndexableDocument, MovieProfile, MovieStats, ParsedFile, Person, PersonCredits,
|
||||
PersonEnrichmentData, PersonId,
|
||||
ReviewHistory, SearchQuery, SearchResults, UserStats, UserTrends,
|
||||
collections::{PageParams, Paginated},
|
||||
},
|
||||
@@ -150,6 +151,13 @@ impl PersonCommand for PanicPersonCommand {
|
||||
async fn backfill_from_credits_batch(&self, _: u32) -> Result<(u64, bool), DomainError> {
|
||||
panic!("PanicPersonCommand called")
|
||||
}
|
||||
async fn update_enrichment(
|
||||
&self,
|
||||
_: &PersonId,
|
||||
_: &PersonEnrichmentData,
|
||||
) -> Result<(), DomainError> {
|
||||
panic!("PanicPersonCommand called")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PanicPersonQuery;
|
||||
|
||||
Reference in New Issue
Block a user