diff --git a/crates/application/src/context.rs b/crates/application/src/context.rs index 4543ca8..ab398f0 100644 --- a/crates/application/src/context.rs +++ b/crates/application/src/context.rs @@ -3,11 +3,11 @@ use std::sync::Arc; use domain::ports::{ AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, GoalRepository, ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository, - MovieRepository, ObjectStorage, PasswordHasher, PersonCommand, PersonQuery, - PosterFetcherClient, RemoteGoalRepository, RemoteWatchlistRepository, ReviewRepository, - SearchCommand, SearchPort, SocialQueryPort, StatsRepository, UserProfileFieldsRepository, - UserRepository, UserSettingsRepository, WatchEventRepository, WatchlistRepository, - WebhookTokenRepository, WrapUpRepository, WrapUpStatsQuery, + MovieRepository, ObjectStorage, PasswordHasher, PersonCommand, PersonEnrichmentClient, + PersonQuery, PosterFetcherClient, RemoteGoalRepository, RemoteWatchlistRepository, + ReviewRepository, SearchCommand, SearchPort, SocialQueryPort, StatsRepository, + UserProfileFieldsRepository, UserRepository, UserSettingsRepository, WatchEventRepository, + WatchlistRepository, WebhookTokenRepository, WrapUpRepository, WrapUpStatsQuery, }; use crate::config::AppConfig; @@ -51,6 +51,7 @@ pub struct Services { pub diary_exporter: Arc, pub document_parser: Arc, pub review_logger: Arc, + pub person_enrichment: Option>, } #[derive(Clone)] diff --git a/crates/application/src/person/enrich.rs b/crates/application/src/person/enrich.rs new file mode 100644 index 0000000..f47c4af --- /dev/null +++ b/crates/application/src/person/enrich.rs @@ -0,0 +1,13 @@ +use crate::context::AppContext; +use domain::{ + errors::DomainError, + models::{PersonEnrichmentData, PersonId}, +}; + +pub async fn execute( + ctx: &AppContext, + person_id: PersonId, + data: PersonEnrichmentData, +) -> Result<(), DomainError> { + ctx.repos.person_command.update_enrichment(&person_id, &data).await +} diff --git a/crates/application/src/person/get.rs b/crates/application/src/person/get.rs index 1199b45..eabd94f 100644 --- a/crates/application/src/person/get.rs +++ b/crates/application/src/person/get.rs @@ -1,11 +1,33 @@ use crate::context::AppContext; +use chrono::Utc; use domain::{ errors::DomainError, + events::DomainEvent, models::{Person, PersonId}, }; +const ENRICHMENT_TTL_DAYS: i64 = 90; + pub async fn execute(ctx: &AppContext, id: PersonId) -> Result, DomainError> { - ctx.repos.person_query.get_by_id(&id).await + let person = ctx.repos.person_query.get_by_id(&id).await?; + if let Some(ref p) = person { + if should_enrich(p) { + let _ = ctx.services.event_publisher.publish( + &DomainEvent::PersonEnrichmentRequested { + person_id: id, + external_person_id: p.external_id().value().to_string(), + }, + ).await; + } + } + Ok(person) +} + +fn should_enrich(p: &Person) -> bool { + match p.enriched_at() { + None => true, + Some(at) => (Utc::now() - at).num_days() >= ENRICHMENT_TTL_DAYS, + } } #[cfg(test)] diff --git a/crates/application/src/person/get_credits.rs b/crates/application/src/person/get_credits.rs index 6bb6863..01d3adf 100644 --- a/crates/application/src/person/get_credits.rs +++ b/crates/application/src/person/get_credits.rs @@ -1,11 +1,31 @@ use crate::context::AppContext; +use chrono::Utc; use domain::{ errors::DomainError, - models::{PersonCredits, PersonId}, + events::DomainEvent, + models::{Person, PersonCredits, PersonId}, }; +const ENRICHMENT_TTL_DAYS: i64 = 90; + pub async fn execute(ctx: &AppContext, id: PersonId) -> Result { - ctx.repos.person_query.get_credits(&id).await + let credits = ctx.repos.person_query.get_credits(&id).await?; + if should_enrich(&credits.person) { + let _ = ctx.services.event_publisher.publish( + &DomainEvent::PersonEnrichmentRequested { + person_id: id, + external_person_id: credits.person.external_id().value().to_string(), + }, + ).await; + } + Ok(credits) +} + +fn should_enrich(p: &Person) -> bool { + match p.enriched_at() { + None => true, + Some(at) => (Utc::now() - at).num_days() >= ENRICHMENT_TTL_DAYS, + } } #[cfg(test)] diff --git a/crates/application/src/person/mod.rs b/crates/application/src/person/mod.rs index 6b19006..246c9dc 100644 --- a/crates/application/src/person/mod.rs +++ b/crates/application/src/person/mod.rs @@ -1,2 +1,3 @@ +pub mod enrich; pub mod get; pub mod get_credits; diff --git a/crates/application/src/test_helpers.rs b/crates/application/src/test_helpers.rs index 5f43729..01c318e 100644 --- a/crates/application/src/test_helpers.rs +++ b/crates/application/src/test_helpers.rs @@ -297,6 +297,7 @@ impl TestContextBuilder { diary_exporter: self.diary_exporter, document_parser: self.document_parser, review_logger: self.review_logger, + person_enrichment: None, }, config: self.config, } diff --git a/crates/presentation/src/main.rs b/crates/presentation/src/main.rs index cd8844d..900c770 100644 --- a/crates/presentation/src/main.rs +++ b/crates/presentation/src/main.rs @@ -218,6 +218,7 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> { diary_exporter: Arc::new(ExportAdapter) as Arc, document_parser: Arc::new(ImporterDocumentParser) as Arc, review_logger, + person_enrichment: None, }, config: app_config, }; diff --git a/crates/presentation/src/tests/extractors.rs b/crates/presentation/src/tests/extractors.rs index f5c39bc..c93e699 100644 --- a/crates/presentation/src/tests/extractors.rs +++ b/crates/presentation/src/tests/extractors.rs @@ -781,6 +781,7 @@ pub fn make_test_state(auth_service: Arc) -> crate::state::AppS diary_exporter: Arc::clone(&repo) as _, document_parser: Arc::clone(&repo) as _, review_logger: Arc::clone(&repo) as _, + person_enrichment: None, }, config: AppConfig { allow_registration: false, diff --git a/crates/presentation/tests/api_test.rs b/crates/presentation/tests/api_test.rs index 7382f1c..5429066 100644 --- a/crates/presentation/tests/api_test.rs +++ b/crates/presentation/tests/api_test.rs @@ -470,6 +470,7 @@ async fn test_app() -> Router { diary_exporter: Arc::new(PanicExporter), document_parser: Arc::new(PanicDocumentParser), review_logger: Arc::new(PanicReviewLogger), + person_enrichment: None, }, config: AppConfig { allow_registration: false, diff --git a/crates/worker/src/main.rs b/crates/worker/src/main.rs index 0efdd2e..4972ab0 100644 --- a/crates/worker/src/main.rs +++ b/crates/worker/src/main.rs @@ -116,6 +116,7 @@ async fn main() -> anyhow::Result<()> { diary_exporter: Arc::new(ExportAdapter) as Arc, document_parser: Arc::new(ImporterDocumentParser) as Arc, review_logger, + person_enrichment: None, }, config: app_config, };