use async_trait::async_trait; use crate::errors::DomainResult; use crate::models::{ LibraryCollection, LibrarySyncLogEntry, LibrarySyncResult, MediaItem, SeasonSummary, ShowSummary, }; use crate::value_objects::{ContentType, LibrarySearchFilter, MediaRole}; use super::media::IMediaProvider; #[async_trait] pub trait LibraryCommand: Send + Sync { async fn upsert_items(&self, provider_id: &str, items: Vec) -> DomainResult<()>; async fn clear_provider(&self, provider_id: &str) -> DomainResult<()>; async fn log_sync_start(&self, provider_id: &str) -> DomainResult; async fn log_sync_finish(&self, log_id: i64, result: &LibrarySyncResult) -> DomainResult<()>; async fn update_role(&self, item_id: &str, role: MediaRole) -> DomainResult<()>; } #[async_trait] pub trait LibraryQuery: Send + Sync { async fn search( &self, filter: &LibrarySearchFilter, ) -> DomainResult<(Vec, u32)>; async fn get_by_id(&self, id: &str) -> DomainResult>; async fn list_collections( &self, provider_id: Option<&str>, ) -> DomainResult>; async fn list_series(&self, provider_id: Option<&str>) -> DomainResult>; async fn list_genres( &self, content_type: Option<&ContentType>, provider_id: Option<&str>, ) -> DomainResult>; async fn latest_sync_status(&self) -> DomainResult>; async fn is_sync_running(&self, provider_id: &str) -> DomainResult; async fn list_shows( &self, provider_id: Option<&str>, search_term: Option<&str>, genres: &[String], ) -> DomainResult>; async fn list_seasons( &self, series_name: &str, provider_id: Option<&str>, ) -> DomainResult>; } #[async_trait] pub trait LibrarySyncAdapter: Send + Sync { async fn sync_provider( &self, provider: &dyn IMediaProvider, provider_id: &str, ) -> LibrarySyncResult; }