app: add sidecar sync commands (export, detect, import, resolve, full export/import)
This commit is contained in:
@@ -4,16 +4,18 @@ use tokio::sync::Mutex;
|
||||
use domain::{
|
||||
entities::{
|
||||
Album, Asset, AssetMetadata, AssetTag, DuplicateGroup, DuplicateStatus,
|
||||
Group, IngestSession, InviteCode, Job, JobStatus, LibraryPath,
|
||||
MetadataSource, QuotaDefinition, Role, ShareLink, ShareScope, ShareTarget,
|
||||
Group, IngestSession, InviteCode, Job, JobBatch, JobStatus, LibraryPath,
|
||||
MetadataSource, Plugin, ProcessingPipeline, QuotaDefinition, Role,
|
||||
ShareLink, ShareScope, ShareTarget, SidecarRecord, SyncStatus,
|
||||
StorageVolume, Tag, UsageLedgerEntry, UsageType, User,
|
||||
},
|
||||
errors::DomainError,
|
||||
ports::{
|
||||
AlbumRepository, AssetMetadataRepository, AssetRepository,
|
||||
DuplicateRepository, GroupRepository, IngestSessionRepository,
|
||||
JobRepository, LibraryPathRepository, QuotaRepository,
|
||||
RoleRepository, ShareRepository, StorageVolumeRepository,
|
||||
JobBatchRepository, JobRepository, LibraryPathRepository,
|
||||
PipelineRepository, PluginRepository, QuotaRepository,
|
||||
RoleRepository, ShareRepository, SidecarRepository, StorageVolumeRepository,
|
||||
TagRepository, UsageLedgerRepository, UserRepository,
|
||||
},
|
||||
value_objects::{Checksum, DateTimeStamp, Email, SystemId},
|
||||
@@ -716,3 +718,141 @@ impl DuplicateRepository for InMemoryDuplicateRepository {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// --- InMemorySidecarRepository ---
|
||||
|
||||
pub struct InMemorySidecarRepository {
|
||||
data: Mutex<HashMap<String, SidecarRecord>>,
|
||||
}
|
||||
|
||||
impl InMemorySidecarRepository {
|
||||
pub fn new() -> Self {
|
||||
Self { data: Mutex::new(HashMap::new()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for InMemorySidecarRepository {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl SidecarRepository for InMemorySidecarRepository {
|
||||
async fn find_by_asset(&self, asset_id: &SystemId) -> Result<Option<SidecarRecord>, DomainError> {
|
||||
Ok(self.data.lock().await.get(&asset_id.to_string()).cloned())
|
||||
}
|
||||
|
||||
async fn find_by_status(&self, status: SyncStatus) -> Result<Vec<SidecarRecord>, DomainError> {
|
||||
Ok(self.data.lock().await.values()
|
||||
.filter(|r| r.sync_status == status)
|
||||
.cloned()
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn save(&self, record: &SidecarRecord) -> Result<(), DomainError> {
|
||||
self.data.lock().await.insert(record.asset_id.to_string(), record.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete(&self, asset_id: &SystemId) -> Result<(), DomainError> {
|
||||
self.data.lock().await.remove(&asset_id.to_string());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// --- InMemoryJobBatchRepository ---
|
||||
|
||||
pub struct InMemoryJobBatchRepository {
|
||||
data: Mutex<HashMap<String, JobBatch>>,
|
||||
}
|
||||
|
||||
impl InMemoryJobBatchRepository {
|
||||
pub fn new() -> Self {
|
||||
Self { data: Mutex::new(HashMap::new()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for InMemoryJobBatchRepository {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl JobBatchRepository for InMemoryJobBatchRepository {
|
||||
async fn find_by_id(&self, id: &SystemId) -> Result<Option<JobBatch>, DomainError> {
|
||||
Ok(self.data.lock().await.get(&id.to_string()).cloned())
|
||||
}
|
||||
|
||||
async fn save(&self, batch: &JobBatch) -> Result<(), DomainError> {
|
||||
self.data.lock().await.insert(batch.batch_id.to_string(), batch.clone());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// --- InMemoryPluginRepository ---
|
||||
|
||||
pub struct InMemoryPluginRepository {
|
||||
data: Mutex<HashMap<String, Plugin>>,
|
||||
}
|
||||
|
||||
impl InMemoryPluginRepository {
|
||||
pub fn new() -> Self {
|
||||
Self { data: Mutex::new(HashMap::new()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for InMemoryPluginRepository {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl PluginRepository for InMemoryPluginRepository {
|
||||
async fn find_by_id(&self, id: &SystemId) -> Result<Option<Plugin>, DomainError> {
|
||||
Ok(self.data.lock().await.get(&id.to_string()).cloned())
|
||||
}
|
||||
|
||||
async fn find_enabled(&self) -> Result<Vec<Plugin>, DomainError> {
|
||||
Ok(self.data.lock().await.values()
|
||||
.filter(|p| p.is_enabled)
|
||||
.cloned()
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn save(&self, plugin: &Plugin) -> Result<(), DomainError> {
|
||||
self.data.lock().await.insert(plugin.plugin_id.to_string(), plugin.clone());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// --- InMemoryPipelineRepository ---
|
||||
|
||||
pub struct InMemoryPipelineRepository {
|
||||
data: Mutex<HashMap<String, ProcessingPipeline>>,
|
||||
}
|
||||
|
||||
impl InMemoryPipelineRepository {
|
||||
pub fn new() -> Self {
|
||||
Self { data: Mutex::new(HashMap::new()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for InMemoryPipelineRepository {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl PipelineRepository for InMemoryPipelineRepository {
|
||||
async fn find_by_id(&self, id: &SystemId) -> Result<Option<ProcessingPipeline>, DomainError> {
|
||||
Ok(self.data.lock().await.get(&id.to_string()).cloned())
|
||||
}
|
||||
|
||||
async fn find_by_trigger(&self, event: &str) -> Result<Vec<ProcessingPipeline>, DomainError> {
|
||||
Ok(self.data.lock().await.values()
|
||||
.filter(|p| p.trigger_event == event)
|
||||
.cloned()
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn save(&self, pipeline: &ProcessingPipeline) -> Result<(), DomainError> {
|
||||
self.data.lock().await.insert(pipeline.pipeline_id.to_string(), pipeline.clone());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user