refactor: group use cases into DDD bounded contexts
Flat use_cases/ (44 files) + monolithic commands.rs/queries.rs split into diary/, movies/, watchlist/, import/, auth/, users/, integrations/, search/, person/, federation/ — each with own commands.rs, queries.rs, and use case modules. Inline tests extracted to sibling tests/ dirs.
This commit is contained in:
71
crates/application/src/integrations/ingest.rs
Normal file
71
crates/application/src/integrations/ingest.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use chrono::Duration;
|
||||
use domain::{
|
||||
errors::DomainError, events::DomainEvent, models::WatchEvent, ports::MediaServerParser,
|
||||
};
|
||||
|
||||
use crate::{context::AppContext, integrations::commands::IngestWatchEventCommand};
|
||||
|
||||
pub async fn execute(
|
||||
ctx: &AppContext,
|
||||
cmd: IngestWatchEventCommand,
|
||||
parser: &dyn MediaServerParser,
|
||||
) -> Result<(), DomainError> {
|
||||
let token_hash = super::generate_token::hash_token(&cmd.token);
|
||||
let webhook_token = ctx
|
||||
.repos
|
||||
.webhook_token
|
||||
.find_by_token_hash(&token_hash)
|
||||
.await?
|
||||
.ok_or_else(|| DomainError::Unauthorized("invalid webhook token".into()))?;
|
||||
|
||||
let _ = ctx
|
||||
.repos
|
||||
.webhook_token
|
||||
.touch_last_used(webhook_token.id())
|
||||
.await;
|
||||
|
||||
let parsed = match parser.parse_playback_event(&cmd.raw_payload)? {
|
||||
Some(event) => event,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
let external_metadata_id = parsed.tmdb_id.or(parsed.imdb_id);
|
||||
let user_id = webhook_token.user_id().clone();
|
||||
|
||||
if let Some(ref ext_id) = external_metadata_id {
|
||||
let one_hour_ago = chrono::Utc::now().naive_utc() - Duration::hours(1);
|
||||
if ctx
|
||||
.repos
|
||||
.watch_event
|
||||
.find_duplicate(&user_id, ext_id, one_hour_ago)
|
||||
.await?
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let watched_at = chrono::Utc::now().naive_utc();
|
||||
let event = WatchEvent::new(
|
||||
user_id,
|
||||
parsed.title,
|
||||
parsed.year,
|
||||
external_metadata_id,
|
||||
cmd.source,
|
||||
watched_at,
|
||||
None,
|
||||
);
|
||||
|
||||
ctx.repos.watch_event.save(&event).await?;
|
||||
|
||||
let _ = ctx
|
||||
.services
|
||||
.event_publisher
|
||||
.publish(&DomainEvent::WatchEventIngested {
|
||||
user_id: event.user_id().clone(),
|
||||
title: event.title().to_string(),
|
||||
source: event.source().to_string(),
|
||||
})
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user