use uuid::Uuid; use crate::{error::Result, model::*, storage::DynStorageBackend}; /// Creates a new collection. /// /// # Arguments /// /// * `storage` - Storage backend /// * `name` - Collection name /// * `kind` - Manual or virtual collection /// * `description` - Optional description /// * `filter_query` - For virtual collections, the search query /// /// # Returns /// /// The created collection pub async fn create_collection( storage: &DynStorageBackend, name: &str, kind: CollectionKind, description: Option<&str>, filter_query: Option<&str>, ) -> Result { storage .create_collection(name, kind, description, filter_query) .await } /// Adds a media item to a collection. /// /// # Arguments /// /// * `storage` - Storage backend /// * `collection_id` - Target collection /// * `media_id` - Media item to add /// * `position` - Position in the collection order /// /// # Returns /// /// `Ok(())` on success pub async fn add_member( storage: &DynStorageBackend, collection_id: Uuid, media_id: MediaId, position: i32, ) -> Result<()> { storage .add_to_collection(collection_id, media_id, position) .await?; crate::audit::record_action( storage, Some(media_id), AuditAction::AddedToCollection, Some(format!("collection_id={collection_id}")), ) .await } /// Removes a media item from a collection. /// /// # Arguments /// /// * `storage` - Storage backend /// * `collection_id` - Target collection /// * `media_id` - Media item to remove /// /// # Returns /// /// `Ok(())` on success pub async fn remove_member( storage: &DynStorageBackend, collection_id: Uuid, media_id: MediaId, ) -> Result<()> { storage .remove_from_collection(collection_id, media_id) .await?; crate::audit::record_action( storage, Some(media_id), AuditAction::RemovedFromCollection, Some(format!("collection_id={collection_id}")), ) .await } /// Returns all media items in a collection. /// /// Virtual collections are evaluated dynamically using their filter query. /// Manual collections return stored members. /// /// # Arguments /// /// * `storage` - Storage backend /// * `collection_id` - Collection to query /// /// # Returns /// /// List of media items in the collection pub async fn get_members( storage: &DynStorageBackend, collection_id: Uuid, ) -> Result> { let collection = storage.get_collection(collection_id).await?; match collection.kind { CollectionKind::Virtual => { // Virtual collections evaluate their filter_query dynamically if let Some(ref query_str) = collection.filter_query { let query = crate::search::parse_search_query(query_str)?; let request = crate::search::SearchRequest { query, sort: crate::search::SortOrder::DateDesc, pagination: Pagination::new(0, 10000, None), }; let results = storage.search(&request).await?; Ok(results.items) } else { Ok(Vec::new()) } }, CollectionKind::Manual => { storage.get_collection_members(collection_id).await }, } }