diff --git a/core/src/library/sync_helpers.rs b/core/src/library/sync_helpers.rs index cfb7727cb..bff1e6161 100644 --- a/core/src/library/sync_helpers.rs +++ b/core/src/library/sync_helpers.rs @@ -63,6 +63,18 @@ impl Library { change_type: ChangeType, db: &DatabaseConnection, ) -> Result<()> { + // For Entry model, we need the database ID before it's excluded from sync JSON + // This is required to fetch directory_path for location roots + let entry_db_id = if M::SYNC_MODEL == "entry" { + // Serialize the full model to get all fields including "id" + serde_json::to_value(model) + .ok() + .and_then(|v| v.get("id").and_then(|id| id.as_i64())) + .map(|id| id as i32) + } else { + None + }; + let mut data = model .to_sync_json() .map_err(|e| anyhow::anyhow!("Failed to serialize model: {}", e))?; @@ -85,18 +97,22 @@ impl Library { if is_directory && is_root { // This is a location root - include absolute path - if let Some(id) = data.get("id").and_then(|v| v.as_i64()) { + // Use the entry_db_id we captured before field exclusions + if let Some(id) = entry_db_id { use crate::infra::db::entities::directory_paths; use sea_orm::ColumnTrait; use sea_orm::QueryFilter; if let Ok(Some(dir_path)) = directory_paths::Entity::find() - .filter(directory_paths::Column::EntryId.eq(id as i32)) + .filter(directory_paths::Column::EntryId.eq(id)) .one(db) .await { if let Some(obj) = data.as_object_mut() { - obj.insert("directory_path".to_string(), serde_json::Value::String(dir_path.path)); + obj.insert( + "directory_path".to_string(), + serde_json::Value::String(dir_path.path), + ); } } } @@ -313,8 +329,9 @@ impl Library { CT::Insert | CT::Update => { self.event_bus().emit(Event::ResourceChangedBatch { resource_type: model_type.to_string(), - resources: serde_json::to_value(&resources_for_event) - .map_err(|e| anyhow::anyhow!("Failed to serialize batch resources: {}", e))?, + resources: serde_json::to_value(&resources_for_event).map_err(|e| { + anyhow::anyhow!("Failed to serialize batch resources: {}", e) + })?, metadata: None, }); }