use uuid::Uuid; use crate::error::Result; use crate::model::*; use crate::storage::DynStorageBackend; 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 } 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 } 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 } 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, } }