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:
2026-07-10 03:50:43 +02:00
parent 12da356a40
commit dee013c7eb
99 changed files with 1262 additions and 896 deletions

View File

@@ -12,32 +12,38 @@ pub trait MediaServerParser: Send + Sync {
-> Result<Option<ParsedPlaybackEvent>, DomainError>;
}
/// Write port — mutates watch events.
#[async_trait]
pub trait WatchEventRepository: Send + Sync {
pub trait WatchEventCommand: Send + Sync {
async fn save(&self, event: &WatchEvent) -> Result<(), DomainError>;
async fn update_status(
&self,
id: &WatchEventId,
status: WatchEventStatus,
) -> Result<(), DomainError>;
async fn list_pending(&self, user_id: &UserId) -> Result<Vec<WatchEvent>, DomainError>;
async fn get_by_id(&self, id: &WatchEventId) -> Result<Option<WatchEvent>, DomainError>;
async fn get_by_ids(&self, ids: &[WatchEventId]) -> Result<Vec<WatchEvent>, DomainError>;
async fn update_status_batch(
&self,
ids: &[WatchEventId],
status: WatchEventStatus,
) -> Result<u64, DomainError>;
async fn delete_non_pending_older_than(
&self,
before: NaiveDateTime,
) -> Result<u64, DomainError>;
}
/// Read port — queries watch events. No mutations.
#[async_trait]
pub trait WatchEventQuery: Send + Sync {
async fn list_pending(&self, user_id: &UserId) -> Result<Vec<WatchEvent>, DomainError>;
async fn get_by_id(&self, id: &WatchEventId) -> Result<Option<WatchEvent>, DomainError>;
async fn get_by_ids(&self, ids: &[WatchEventId]) -> Result<Vec<WatchEvent>, DomainError>;
async fn find_duplicate(
&self,
user_id: &UserId,
external_id: &str,
after: NaiveDateTime,
) -> Result<bool, DomainError>;
async fn delete_non_pending_older_than(
&self,
before: NaiveDateTime,
) -> Result<u64, DomainError>;
}
#[async_trait]

View File

@@ -9,8 +9,16 @@ use crate::{
value_objects::{ExternalMetadataId, MovieId, MovieTitle, PosterUrl, ReleaseYear},
};
/// Write port — mutates the movies table.
#[async_trait]
pub trait MovieRepository: Send + Sync {
pub trait MovieCommand: Send + Sync {
async fn upsert_movie(&self, movie: &Movie) -> Result<(), DomainError>;
async fn delete_movie(&self, movie_id: &MovieId) -> Result<(), DomainError>;
}
/// Read port — queries movies. No mutations.
#[async_trait]
pub trait MovieQuery: Send + Sync {
async fn get_movie_by_external_id(
&self,
external_metadata_id: &ExternalMetadataId,
@@ -21,8 +29,6 @@ pub trait MovieRepository: Send + Sync {
title: &MovieTitle,
year: &ReleaseYear,
) -> Result<Vec<Movie>, DomainError>;
async fn upsert_movie(&self, movie: &Movie) -> Result<(), DomainError>;
async fn delete_movie(&self, movie_id: &MovieId) -> Result<(), DomainError>;
async fn existing_external_ids(
&self,
ids: &[ExternalMetadataId],