From 9c24f1af8f13dba126be7bfa82a11a804310f75a Mon Sep 17 00:00:00 2001 From: Alex Groleau Date: Fri, 27 Mar 2026 02:08:45 -0400 Subject: [PATCH] fixed issue where merge lookups with no changes were not generating a notification --- fixtures/merger.json | 63 +++++++++++++++++++++++++++++++++++++++++++ src/merger/mod.rs | 12 +++++---- src/tests/fixtures.rs | 6 +++++ 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/fixtures/merger.json b/fixtures/merger.json index 6520218..74180cb 100644 --- a/fixtures/merger.json +++ b/fixtures/merger.json @@ -1152,6 +1152,69 @@ ] } }, + { + "description": "Replace existing person with id and no changes (lookup)", + "action": "merge", + "data": { + "id": "33333333-3333-3333-3333-333333333333", + "type": "person", + "first_name": "LookupFirst", + "last_name": "LookupLast", + "date_of_birth": "1990-01-01T00:00:00Z", + "pronouns": "they/them" + }, + "mocks": [ + { + "id": "22222222-2222-2222-2222-222222222222", + "type": "person", + "first_name": "LookupFirst", + "last_name": "LookupLast", + "date_of_birth": "1990-01-01T00:00:00Z", + "pronouns": "they/them", + "contact_id": "old-contact" + } + ], + "schema_id": "person", + "expect": { + "success": true, + "sql": [ + [ + "SELECT to_jsonb(t1.*) || to_jsonb(t2.*) || to_jsonb(t3.*) || to_jsonb(t4.*)", + "FROM agreego.\"person\" t1", + "LEFT JOIN agreego.\"user\" t2 ON t2.id = t1.id", + "LEFT JOIN agreego.\"organization\" t3 ON t3.id = t1.id", + "LEFT JOIN agreego.\"entity\" t4 ON t4.id = t1.id", + "WHERE", + " t1.id = '33333333-3333-3333-3333-333333333333'", + " OR (", + " \"first_name\" = 'LookupFirst'", + " AND \"last_name\" = 'LookupLast'", + " AND \"date_of_birth\" = '1990-01-01T00:00:00Z'", + " AND \"pronouns\" = 'they/them'", + " )" + ], + [ + "SELECT pg_notify('entity', '{", + " \"complete\":{", + " \"contact_id\":\"old-contact\",", + " \"date_of_birth\":\"1990-01-01T00:00:00Z\",", + " \"first_name\":\"LookupFirst\",", + " \"id\":\"22222222-2222-2222-2222-222222222222\",", + " \"last_name\":\"LookupLast\",", + " \"modified_at\":\"2026-03-10T00:00:00Z\",", + " \"modified_by\":\"00000000-0000-0000-0000-000000000000\",", + " \"pronouns\":\"they/them\",", + " \"type\":\"person\"", + " },", + " \"new\":{", + " \"type\":\"person\"", + " },", + " \"replaces\":\"33333333-3333-3333-3333-333333333333\"", + " }')" + ] + ] + } + }, { "description": "Update existing person with id (no lookup)", "action": "merge", diff --git a/src/merger/mod.rs b/src/merger/mod.rs index 39ccf4a..446e65b 100644 --- a/src/merger/mod.rs +++ b/src/merger/mod.rs @@ -508,7 +508,7 @@ impl Merger { ); entity_fields = new_fields; - } else if changes.is_empty() { + } else if changes.is_empty() && replaces_id.is_none() { let mut new_fields = serde_json::Map::new(); new_fields.insert( "id".to_string(), @@ -524,6 +524,8 @@ impl Merger { .unwrap_or(false); entity_change_kind = if is_archived { Some("delete".to_string()) + } else if changes.is_empty() && replaces_id.is_some() { + Some("replace".to_string()) } else { Some("update".to_string()) }; @@ -796,9 +798,9 @@ impl Merger { let mut old_vals = serde_json::Map::new(); let mut new_vals = serde_json::Map::new(); - let is_update = change_kind == "update" || change_kind == "delete"; + let exists = change_kind == "update" || change_kind == "delete" || change_kind == "replace"; - if !is_update { + if !exists { let system_keys = vec![ "id".to_string(), "created_by".to_string(), @@ -835,7 +837,7 @@ impl Merger { } let mut complete = entity_fields.clone(); - if is_update { + if exists { if let Some(fetched) = entity_fetched { let mut temp = fetched.clone(); for (k, v) in entity_fields { @@ -865,7 +867,7 @@ impl Merger { } let mut notify_sql = None; - if type_obj.historical { + if type_obj.historical && change_kind != "replace" { let change_sql = format!( "INSERT INTO agreego.change (\"old\", \"new\", entity_id, id, kind, modified_at, modified_by) VALUES ({}, {}, {}, {}, {}, {}, {})", Self::quote_literal(&old_val_obj), diff --git a/src/tests/fixtures.rs b/src/tests/fixtures.rs index 7952b31..834c6b5 100644 --- a/src/tests/fixtures.rs +++ b/src/tests/fixtures.rs @@ -8602,3 +8602,9 @@ fn test_merger_0_11() { let path = format!("{}/fixtures/merger.json", env!("CARGO_MANIFEST_DIR")); crate::tests::runner::run_test_case(&path, 0, 11).unwrap(); } + +#[test] +fn test_merger_0_12() { + let path = format!("{}/fixtures/merger.json", env!("CARGO_MANIFEST_DIR")); + crate::tests::runner::run_test_case(&path, 0, 12).unwrap(); +}