refactor: remaining MEDIUM — CQRS splits, DI Deps, profile dedup, event Value, response enum
M1: MovieRepository→MovieCommand/MovieQuery, WatchEventRepository→ WatchEventCommand/WatchEventQuery M2: goals/ and import/ use Deps structs M7: extract upload_image helper in update_profile M8: FederationDeliveryRequested activity_json String→serde_json::Value M11: UserProfileResponse uses ProfileViewData enum
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::Duration;
|
||||
use domain::{errors::DomainError, ports::WatchEventRepository};
|
||||
use domain::{errors::DomainError, ports::WatchEventCommand};
|
||||
|
||||
pub async fn execute(watch_event: Arc<dyn WatchEventRepository>) -> Result<u64, DomainError> {
|
||||
pub async fn execute(watch_event_command: Arc<dyn WatchEventCommand>) -> Result<u64, DomainError> {
|
||||
let cutoff = chrono::Utc::now().naive_utc() - Duration::days(30);
|
||||
watch_event.delete_non_pending_older_than(cutoff).await
|
||||
watch_event_command.delete_non_pending_older_than(cutoff).await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
models::WatchEventStatus,
|
||||
ports::WatchEventRepository,
|
||||
ports::{WatchEventCommand, WatchEventQuery},
|
||||
value_objects::{UserId, WatchEventId},
|
||||
};
|
||||
|
||||
@@ -14,7 +14,8 @@ use crate::{
|
||||
};
|
||||
|
||||
pub async fn execute(
|
||||
watch_event: Arc<dyn WatchEventRepository>,
|
||||
watch_event_command: Arc<dyn WatchEventCommand>,
|
||||
watch_event_query: Arc<dyn WatchEventQuery>,
|
||||
review_logger: Arc<dyn ReviewLogger>,
|
||||
cmd: ConfirmWatchEventsCommand,
|
||||
) -> Result<u32, DomainError> {
|
||||
@@ -23,7 +24,7 @@ pub async fn execute(
|
||||
|
||||
for c in cmd.confirmations {
|
||||
let event_id = WatchEventId::from_uuid(c.watch_event_id);
|
||||
let event = watch_event
|
||||
let event = watch_event_query
|
||||
.get_by_id(&event_id)
|
||||
.await?
|
||||
.ok_or_else(|| DomainError::NotFound(format!("WatchEvent {}", c.watch_event_id)))?;
|
||||
@@ -61,7 +62,7 @@ pub async fn execute(
|
||||
|
||||
review_logger.log_review(review_cmd).await?;
|
||||
|
||||
watch_event
|
||||
watch_event_command
|
||||
.update_status(&event_id, WatchEventStatus::Confirmed)
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::ports::{EventPublisher, WatchEventRepository, WebhookTokenRepository};
|
||||
use domain::ports::{EventPublisher, WatchEventCommand, WatchEventQuery, WebhookTokenRepository};
|
||||
|
||||
pub struct IngestWatchEventDeps {
|
||||
pub webhook_token: Arc<dyn WebhookTokenRepository>,
|
||||
pub watch_event: Arc<dyn WatchEventRepository>,
|
||||
pub watch_event_command: Arc<dyn WatchEventCommand>,
|
||||
pub watch_event_query: Arc<dyn WatchEventQuery>,
|
||||
pub event_publisher: Arc<dyn EventPublisher>,
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@ use std::sync::Arc;
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
models::WatchEventStatus,
|
||||
ports::WatchEventRepository,
|
||||
ports::{WatchEventCommand, WatchEventQuery},
|
||||
value_objects::{UserId, WatchEventId},
|
||||
};
|
||||
|
||||
use crate::integrations::commands::DismissWatchEventsCommand;
|
||||
|
||||
pub async fn execute(
|
||||
watch_event: Arc<dyn WatchEventRepository>,
|
||||
watch_event_command: Arc<dyn WatchEventCommand>,
|
||||
watch_event_query: Arc<dyn WatchEventQuery>,
|
||||
cmd: DismissWatchEventsCommand,
|
||||
) -> Result<u32, DomainError> {
|
||||
let user_id = UserId::from_uuid(cmd.user_id);
|
||||
@@ -24,7 +25,7 @@ pub async fn execute(
|
||||
.map(|id| WatchEventId::from_uuid(*id))
|
||||
.collect();
|
||||
|
||||
let events = watch_event.get_by_ids(&ids).await?;
|
||||
let events = watch_event_query.get_by_ids(&ids).await?;
|
||||
|
||||
if events.len() != ids.len() {
|
||||
return Err(DomainError::NotFound(
|
||||
@@ -37,7 +38,7 @@ pub async fn execute(
|
||||
}
|
||||
}
|
||||
|
||||
let count = watch_event
|
||||
let count = watch_event_command
|
||||
.update_status_batch(&ids, WatchEventStatus::Dismissed)
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::{
|
||||
errors::DomainError, models::WatchEvent, ports::WatchEventRepository, value_objects::UserId,
|
||||
errors::DomainError, models::WatchEvent, ports::WatchEventQuery, value_objects::UserId,
|
||||
};
|
||||
|
||||
use crate::integrations::queries::GetWatchQueueQuery;
|
||||
|
||||
pub async fn execute(
|
||||
watch_event: Arc<dyn WatchEventRepository>,
|
||||
watch_event_query: Arc<dyn WatchEventQuery>,
|
||||
query: GetWatchQueueQuery,
|
||||
) -> Result<Vec<WatchEvent>, DomainError> {
|
||||
let user_id = UserId::from_uuid(query.user_id);
|
||||
watch_event.list_pending(&user_id).await
|
||||
watch_event_query.list_pending(&user_id).await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -30,7 +30,7 @@ pub async fn execute(
|
||||
if let Some(ref ext_id) = external_metadata_id {
|
||||
let one_hour_ago = chrono::Utc::now().naive_utc() - Duration::hours(1);
|
||||
if deps
|
||||
.watch_event
|
||||
.watch_event_query
|
||||
.find_duplicate(&user_id, ext_id, one_hour_ago)
|
||||
.await?
|
||||
{
|
||||
@@ -49,7 +49,7 @@ pub async fn execute(
|
||||
None,
|
||||
);
|
||||
|
||||
deps.watch_event.save(&event).await?;
|
||||
deps.watch_event_command.save(&event).await?;
|
||||
|
||||
let _ = deps
|
||||
.event_publisher
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::ports::WatchEventRepository;
|
||||
use domain::testing::InMemoryWatchEventRepository;
|
||||
|
||||
use crate::integrations::cleanup;
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_zero_when_nothing_to_clean() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
|
||||
let count = cleanup::execute(watch_events).await.unwrap();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::models::{WatchEvent, WatchEventSource};
|
||||
use domain::ports::{MovieRepository, WatchEventRepository};
|
||||
use domain::ports::{MovieCommand, WatchEventCommand};
|
||||
use domain::testing::{InMemoryWatchEventRepository, NoopEventPublisher};
|
||||
use domain::value_objects::UserId;
|
||||
use uuid::Uuid;
|
||||
@@ -16,7 +16,7 @@ fn noop_logger() -> Arc<dyn crate::ports::ReviewLogger> {
|
||||
|
||||
#[tokio::test]
|
||||
async fn confirms_watch_event_via_review_logger() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let uid = Uuid::new_v4();
|
||||
|
||||
let event = WatchEvent::new(
|
||||
@@ -32,7 +32,8 @@ async fn confirms_watch_event_via_review_logger() {
|
||||
watch_events.save(&event).await.unwrap();
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
noop_logger(),
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: uid,
|
||||
@@ -51,10 +52,11 @@ async fn confirms_watch_event_via_review_logger() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn empty_confirmations_returns_zero() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
noop_logger(),
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: Uuid::new_v4(),
|
||||
@@ -69,7 +71,7 @@ async fn empty_confirmations_returns_zero() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn confirms_event_with_external_metadata_id_and_no_movie_id() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let uid = Uuid::new_v4();
|
||||
|
||||
let event = WatchEvent::new(
|
||||
@@ -85,7 +87,8 @@ async fn confirms_event_with_external_metadata_id_and_no_movie_id() {
|
||||
watch_events.save(&event).await.unwrap();
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
noop_logger(),
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: uid,
|
||||
@@ -104,7 +107,7 @@ async fn confirms_event_with_external_metadata_id_and_no_movie_id() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn rejects_other_users_event() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let owner = Uuid::new_v4();
|
||||
let intruder = Uuid::new_v4();
|
||||
|
||||
@@ -121,7 +124,8 @@ async fn rejects_other_users_event() {
|
||||
watch_events.save(&event).await.unwrap();
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
noop_logger(),
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: intruder,
|
||||
@@ -139,10 +143,11 @@ async fn rejects_other_users_event() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn fails_when_event_not_found() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
noop_logger(),
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: Uuid::new_v4(),
|
||||
@@ -160,7 +165,7 @@ async fn fails_when_event_not_found() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn confirms_event_with_movie_id() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let events = NoopEventPublisher::new();
|
||||
let uid = Uuid::new_v4();
|
||||
let movie_uuid = Uuid::new_v4();
|
||||
@@ -194,6 +199,7 @@ async fn confirms_event_with_movie_id() {
|
||||
let watchlist = domain::testing::InMemoryWatchlistRepository::new();
|
||||
let review_logger: Arc<dyn crate::ports::ReviewLogger> =
|
||||
Arc::new(crate::diary::review_logger::DefaultReviewLogger::new(
|
||||
Arc::clone(&movies) as _,
|
||||
Arc::clone(&movies) as _,
|
||||
Arc::clone(&reviews) as _,
|
||||
Arc::clone(&watchlist) as _,
|
||||
@@ -202,7 +208,8 @@ async fn confirms_event_with_movie_id() {
|
||||
));
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
review_logger,
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: uid,
|
||||
@@ -221,7 +228,7 @@ async fn confirms_event_with_movie_id() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn confirms_event_without_movie_id_and_without_external_metadata_id() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let uid = Uuid::new_v4();
|
||||
|
||||
let event = WatchEvent::new(
|
||||
@@ -237,7 +244,8 @@ async fn confirms_event_without_movie_id_and_without_external_metadata_id() {
|
||||
watch_events.save(&event).await.unwrap();
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
noop_logger(),
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: uid,
|
||||
@@ -256,7 +264,7 @@ async fn confirms_event_without_movie_id_and_without_external_metadata_id() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn confirms_multiple_events() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let uid = Uuid::new_v4();
|
||||
|
||||
let event1 = WatchEvent::new(
|
||||
@@ -285,7 +293,8 @@ async fn confirms_multiple_events() {
|
||||
watch_events.save(&event2).await.unwrap();
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
noop_logger(),
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: uid,
|
||||
@@ -311,7 +320,7 @@ async fn confirms_multiple_events() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn confirms_event_without_year() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let uid = Uuid::new_v4();
|
||||
|
||||
let event = WatchEvent::new(
|
||||
@@ -327,7 +336,8 @@ async fn confirms_event_without_year() {
|
||||
watch_events.save(&event).await.unwrap();
|
||||
|
||||
let result = confirm::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
noop_logger(),
|
||||
ConfirmWatchEventsCommand {
|
||||
user_id: uid,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::models::{WatchEvent, WatchEventSource};
|
||||
use domain::ports::WatchEventRepository;
|
||||
use domain::ports::WatchEventCommand;
|
||||
use domain::testing::InMemoryWatchEventRepository;
|
||||
use domain::value_objects::UserId;
|
||||
use uuid::Uuid;
|
||||
@@ -10,10 +10,11 @@ use crate::integrations::{commands::DismissWatchEventsCommand, dismiss};
|
||||
|
||||
#[tokio::test]
|
||||
async fn dismisses_empty_list_returns_zero() {
|
||||
let events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let events = InMemoryWatchEventRepository::new();
|
||||
|
||||
let result = dismiss::execute(
|
||||
Arc::clone(&events),
|
||||
Arc::clone(&events) as _,
|
||||
Arc::clone(&events) as _,
|
||||
DismissWatchEventsCommand {
|
||||
user_id: Uuid::new_v4(),
|
||||
event_ids: vec![],
|
||||
@@ -27,10 +28,11 @@ async fn dismisses_empty_list_returns_zero() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn fails_when_event_not_found() {
|
||||
let events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let events = InMemoryWatchEventRepository::new();
|
||||
|
||||
let result = dismiss::execute(
|
||||
Arc::clone(&events),
|
||||
Arc::clone(&events) as _,
|
||||
Arc::clone(&events) as _,
|
||||
DismissWatchEventsCommand {
|
||||
user_id: Uuid::new_v4(),
|
||||
event_ids: vec![Uuid::new_v4()],
|
||||
@@ -43,7 +45,7 @@ async fn fails_when_event_not_found() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn dismisses_existing_events() {
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let uid = Uuid::new_v4();
|
||||
let user_id = UserId::from_uuid(uid);
|
||||
|
||||
@@ -71,7 +73,8 @@ async fn dismisses_existing_events() {
|
||||
watch_events.save(&e2).await.unwrap();
|
||||
|
||||
let result = dismiss::execute(
|
||||
Arc::clone(&watch_events),
|
||||
Arc::clone(&watch_events) as _,
|
||||
Arc::clone(&watch_events) as _,
|
||||
DismissWatchEventsCommand {
|
||||
user_id: uid,
|
||||
event_ids: vec![id1, id2],
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use chrono::Utc;
|
||||
use domain::models::{WatchEvent, WatchEventSource};
|
||||
use domain::ports::WatchEventRepository;
|
||||
use domain::ports::WatchEventCommand;
|
||||
use domain::testing::InMemoryWatchEventRepository;
|
||||
use domain::value_objects::UserId;
|
||||
use uuid::Uuid;
|
||||
@@ -11,10 +11,10 @@ use crate::integrations::{get_queue, queries::GetWatchQueueQuery};
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_empty_when_no_events() {
|
||||
let events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let events = InMemoryWatchEventRepository::new();
|
||||
|
||||
let result = get_queue::execute(
|
||||
Arc::clone(&events),
|
||||
Arc::clone(&events) as _,
|
||||
GetWatchQueueQuery {
|
||||
user_id: Uuid::new_v4(),
|
||||
},
|
||||
@@ -27,7 +27,7 @@ async fn returns_empty_when_no_events() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_pending_events() {
|
||||
let events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let events = InMemoryWatchEventRepository::new();
|
||||
|
||||
let user_id = Uuid::new_v4();
|
||||
let event = WatchEvent::new(
|
||||
@@ -41,7 +41,7 @@ async fn returns_pending_events() {
|
||||
);
|
||||
events.save(&event).await.unwrap();
|
||||
|
||||
let result = get_queue::execute(Arc::clone(&events), GetWatchQueueQuery { user_id })
|
||||
let result = get_queue::execute(Arc::clone(&events) as _, GetWatchQueueQuery { user_id })
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::models::WatchEventSource;
|
||||
use domain::ports::{EventPublisher, WatchEventRepository, WebhookTokenRepository};
|
||||
use domain::ports::{EventPublisher, WebhookTokenRepository};
|
||||
use domain::testing::{
|
||||
InMemoryWatchEventRepository, InMemoryWebhookTokenRepository, NoopEventPublisher,
|
||||
};
|
||||
@@ -30,7 +30,7 @@ impl domain::ports::MediaServerParser for FakeParser {
|
||||
#[tokio::test]
|
||||
async fn ingests_watch_event() {
|
||||
let tokens: Arc<dyn WebhookTokenRepository> = InMemoryWebhookTokenRepository::new();
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let event_publisher: Arc<dyn EventPublisher> = NoopEventPublisher::new();
|
||||
|
||||
let user_id = Uuid::new_v4();
|
||||
@@ -47,7 +47,8 @@ async fn ingests_watch_event() {
|
||||
|
||||
let deps = IngestWatchEventDeps {
|
||||
webhook_token: Arc::clone(&tokens),
|
||||
watch_event: Arc::clone(&watch_events),
|
||||
watch_event_command: Arc::clone(&watch_events) as _,
|
||||
watch_event_query: Arc::clone(&watch_events) as _,
|
||||
event_publisher: Arc::clone(&event_publisher),
|
||||
};
|
||||
|
||||
@@ -68,12 +69,13 @@ async fn ingests_watch_event() {
|
||||
#[tokio::test]
|
||||
async fn rejects_invalid_token() {
|
||||
let tokens: Arc<dyn WebhookTokenRepository> = InMemoryWebhookTokenRepository::new();
|
||||
let watch_events: Arc<dyn WatchEventRepository> = InMemoryWatchEventRepository::new();
|
||||
let watch_events = InMemoryWatchEventRepository::new();
|
||||
let event_publisher: Arc<dyn EventPublisher> = NoopEventPublisher::new();
|
||||
|
||||
let deps = IngestWatchEventDeps {
|
||||
webhook_token: Arc::clone(&tokens),
|
||||
watch_event: Arc::clone(&watch_events),
|
||||
watch_event_command: Arc::clone(&watch_events) as _,
|
||||
watch_event_query: Arc::clone(&watch_events) as _,
|
||||
event_publisher: Arc::clone(&event_publisher),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user