Skip to main content
Version: v2

Kafka Entity Change Event Processing

The EIMP event processing strategy uses the event payload fields and eventType to determine the operation type. The target enterprise identifier is determined by the masterIndividualIdentifier, and only this customer is updated if found in Customer Service.

The logic to identify whether the operation is a Split, Split and Merge, Merge, or Delete is determined by the records and oldRecords arrays populated in the entityChange object.


entityChange object schema

The entityChange object describes which source records now belong to this EID and which previously did.

{
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "",
"sourceTimestamp": null,
"userId": null
},
"records": [
{
"oldEnterpriseId": "",
"sourceSystem": "",
"sourceRecordId": "",
"surrogateIdentifier": "",
"changeType": ""
}
],
"oldRecords": [
{
"newEnterpriseId": "",
"sourceSystem": "",
"sourceEntityId": "",
"surrogateIdentifier": "",
"changeType": ""
}
]
}
}
FieldDescription
entityChange.lastUpdated.sourceSystemTimestampTimestamp from the originating source system.
entityChange.lastUpdated.sourceTimestampTimestamp from the EiMP source layer (may be null).
entityChange.lastUpdated.userIdUser who triggered the change (null for algorithmic events).
entityChange.recordsSource records that now belong to this Golden Record. Populated on MERGE and SPLIT_AND_MERGE.
records[].oldEnterpriseIdThe EID the source record previously belonged to before moving to this GR.
records[].sourceSystemThe originating source system (e.g., CSP_Facets).
records[].sourceRecordIdThe record identifier in the originating source system.
records[].surrogateIdentifierEiMP surrogate key for this source record.
records[].changeTypeThe type of change applied to this record entry.
entityChange.oldRecordsSource records that previously belonged to this GR but have since moved. Populated on SPLIT and SPLIT_AND_MERGE.
oldRecords[].newEnterpriseIdThe EID the source record has been moved to.
oldRecords[].sourceSystemThe originating source system for this record.
oldRecords[].sourceEntityIdThe entity identifier in the originating source system.
oldRecords[].surrogateIdentifierEiMP surrogate key for this source record.
oldRecords[].changeTypeThe type of change applied to this record entry.

The partyLinks object lists the source records currently linked to the Golden Record, complementing entityChange with the linkage reason code for each association.

{
"partyLinks": [
{
"lastUpdated": {
"sourceSystemTimestamp": "",
"sourceTimestamp": null,
"userId": null
},
"linkReasonCode": "",
"sourcePartyIdentifier": "",
"surrogateIdentifier": "",
"targetPartyIdentifier": ""
}
]
}
FieldDescription
linkReasonCodeNumeric code indicating why the record is linked. See the linkage type codes table below.
sourcePartyIdentifierIdentifier of the source party (member record) being linked.
surrogateIdentifierEiMP surrogate key for the party link entry.
targetPartyIdentifierIdentifier of the target Golden Record (EID).

Linkage type codes

CodeReasonDescription
2LinkRecords are automatically merged via the EiMP algorithm when the merge threshold score is met.
3UnlinkRecords are automatically split from their assigned EID when the merge threshold is not met. A new EID is assigned to at least one member record.

Sample event payloads

The following examples are real payloads provided by the EiMP team. Each scenario shows both sides of an operation — i.e. every EID that receives an event for that operation — so the full picture of what EiMP publishes is clear.


Scenario 1 — Simple Split (new EID created)

A record moves out of an existing EID into a brand new EID. EiMP publishes two events: one to the new EID (records joined) and one to the existing EID (records left).

New EID 5214230533 — records joined (changeType: merge, linkReasonCode: 2)

{
"partyLinks": [
{
"surrogateIdentifier": "2099344117",
"targetPartyIdentifier": "5214230533",
"sourcePartyIdentifier": "5123077187",
"linkReasonCode": "2",
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-05 13:39:39.000",
"sourceTimestamp": null,
"userId": null
}
},
{
"surrogateIdentifier": "2097428919",
"targetPartyIdentifier": "5214230533",
"sourcePartyIdentifier": "5123077187",
"linkReasonCode": "2",
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-05 13:39:39.000",
"sourceTimestamp": null,
"userId": null
}
}
],
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-05 13:39:39.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [],
"records": [
{
"changeType": "merge",
"oldEnterpriseId": "5123077187",
"sourceRecordId": "MOONEX 16168996201",
"sourceSystem": "CDB_AP",
"surrogateIdentifier": "2099344117"
},
{
"changeType": "merge",
"oldEnterpriseId": "5123077187",
"sourceRecordId": "161689962-01",
"sourceSystem": "CSP_Facets",
"surrogateIdentifier": "2097428919"
}
]
}
}

Existing EID 5123077187 — records left (changeType: split, linkReasonCode: 3)

{
"partyLinks": [
{
"surrogateIdentifier": "2099344117",
"targetPartyIdentifier": "5214230533",
"sourcePartyIdentifier": "5123077187",
"linkReasonCode": "3",
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-05 13:39:39.000",
"sourceTimestamp": null,
"userId": null
}
},
{
"surrogateIdentifier": "2097428919",
"targetPartyIdentifier": "5214230533",
"sourcePartyIdentifier": "5123077187",
"linkReasonCode": "3",
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-05 13:39:39.000",
"sourceTimestamp": null,
"userId": null
}
}
],
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-05 13:39:39.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [
{
"changeType": "split",
"newEnterpriseId": "5214230533",
"sourceRecordId": "MOONEX 16168996201",
"sourceSystem": "CDB_AP",
"surrogateIdentifier": "2099344117"
},
{
"changeType": "split",
"newEnterpriseId": "5214230533",
"sourceRecordId": "161689962-01",
"sourceSystem": "CSP_Facets",
"surrogateIdentifier": "2097428919"
}
],
"records": []
}
}
Reading this scenario
  • The new EID (5214230533) receives records[] entries with changeType: merge and linkReasonCode: 2 (Link) — meaning records joined this EID.
  • The existing EID (5123077187) receives oldRecords[] entries with changeType: split and linkReasonCode: 3 (Unlink) — meaning those records left this EID.
  • CCG processes the event for the EID that matches the customer stored in Customer Service.

Scenario 2a — Overmerge correction, no new EID (records moved between existing EIDs)

A record moves from EID 1 into EID 2 (both already exist). This is a Split/Merge pair without a newly created EID.

EID 1 572655692 — record left

{
"partyLinks": [
{
"surrogateIdentifier": "732572314",
"targetPartyIdentifier": "5214416707",
"sourcePartyIdentifier": "572655692",
"linkReasonCode": "3",
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 18:53:14.000",
"sourceTimestamp": null,
"userId": null
}
}
],
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 18:53:14.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [
{
"changeType": "split",
"newEnterpriseId": "5214416707",
"sourceRecordId": "SDMSDM75QP771299811610",
"sourceSystem": "RXCC",
"surrogateIdentifier": "732572314"
}
],
"records": []
}
}

EID 2 5214416707 — record joined

{
"partyLinks": [
{
"surrogateIdentifier": "732572314",
"targetPartyIdentifier": "5214416707",
"sourcePartyIdentifier": "572655692",
"linkReasonCode": "2",
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 18:53:14.000",
"sourceTimestamp": null,
"userId": null
}
}
],
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 18:53:14.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [],
"records": [
{
"changeType": "merge",
"oldEnterpriseId": "572655692",
"sourceRecordId": "SDMSDM75QP771299811610",
"sourceSystem": "RXCC",
"surrogateIdentifier": "732572314"
}
]
}
}

Scenario 2b — Overmerge correction, new EIDs created (records split across multiple new EIDs)

A single EID is split into two new EIDs. EiMP publishes three events: one to the original EID (all records left) and one to each new EID (their respective records joined).

EID 1 5214414483 — all records left (split into EID 2 and EID 3)

{
"partyLinks": [
{
"surrogateIdentifier": "2265797275",
"targetPartyIdentifier": "5214416445",
"sourcePartyIdentifier": "5214414483",
"linkReasonCode": "3",
"lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null }
},
{
"surrogateIdentifier": "2265798554",
"targetPartyIdentifier": "5214416445",
"sourcePartyIdentifier": "5214414483",
"linkReasonCode": "3",
"lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null }
},
{
"surrogateIdentifier": "2265798550",
"targetPartyIdentifier": "5214416445",
"sourcePartyIdentifier": "5214414483",
"linkReasonCode": "3",
"lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null }
},
{
"surrogateIdentifier": "2265798477",
"targetPartyIdentifier": "5214416446",
"sourcePartyIdentifier": "5214414483",
"linkReasonCode": "3",
"lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null }
},
{
"surrogateIdentifier": "2265798472",
"targetPartyIdentifier": "5214416446",
"sourcePartyIdentifier": "5214414483",
"linkReasonCode": "3",
"lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null }
}
],
"entityChange": {
"lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null },
"oldRecords": [
{ "changeType": "split", "newEnterpriseId": "5214416445", "sourceRecordId": "MOONEX 96458721301", "sourceSystem": "CDB_AP", "surrogateIdentifier": "2265797275" },
{ "changeType": "split", "newEnterpriseId": "5214416445", "sourceRecordId": "0068465165165465465164968461", "sourceSystem": "CDB_CS", "surrogateIdentifier": "2265798554" },
{ "changeType": "split", "newEnterpriseId": "5214416445", "sourceRecordId": "124565681968494960026529684", "sourceSystem": "CDB_CS", "surrogateIdentifier": "2265798550" },
{ "changeType": "split", "newEnterpriseId": "5214416446", "sourceRecordId": "112654987-02", "sourceSystem": "CSP_Facets","surrogateIdentifier": "2265798477" },
{ "changeType": "split", "newEnterpriseId": "5214416446", "sourceRecordId": "100972~123564516584~2", "sourceSystem": "GPS", "surrogateIdentifier": "2265798472" }
],
"records": []
}
}

EID 2 5214416445 — 3 records joined

{
"partyLinks": [
{ "surrogateIdentifier": "2265797275", "targetPartyIdentifier": "5214416445", "sourcePartyIdentifier": "5214414483", "linkReasonCode": "2", "lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null } },
{ "surrogateIdentifier": "2265798554", "targetPartyIdentifier": "5214416445", "sourcePartyIdentifier": "5214414483", "linkReasonCode": "2", "lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null } },
{ "surrogateIdentifier": "2265798550", "targetPartyIdentifier": "5214416445", "sourcePartyIdentifier": "5214414483", "linkReasonCode": "2", "lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null } }
],
"entityChange": {
"lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null },
"oldRecords": [],
"records": [
{ "changeType": "merge", "oldEnterpriseId": "5214414483", "sourceRecordId": "MOONEX 96458721301", "sourceSystem": "CDB_AP", "surrogateIdentifier": "2265797275" },
{ "changeType": "merge", "oldEnterpriseId": "5214414483", "sourceRecordId": "0068465165165465465164968461", "sourceSystem": "CDB_CS", "surrogateIdentifier": "2265798554" },
{ "changeType": "merge", "oldEnterpriseId": "5214414483", "sourceRecordId": "124565681968494960026529684", "sourceSystem": "CDB_CS", "surrogateIdentifier": "2265798550" }
]
}
}

EID 3 5214416446 — 2 records joined

{
"partyLinks": [
{ "surrogateIdentifier": "2265798477", "targetPartyIdentifier": "5214416446", "sourcePartyIdentifier": "5214414483", "linkReasonCode": "2", "lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null } },
{ "surrogateIdentifier": "2265798472", "targetPartyIdentifier": "5214416446", "sourcePartyIdentifier": "5214414483", "linkReasonCode": "2", "lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null } }
],
"entityChange": {
"lastUpdated": { "sourceSystemTimestamp": "2024-02-06 19:22:45.000", "sourceTimestamp": null, "userId": null },
"oldRecords": [],
"records": [
{ "changeType": "merge", "oldEnterpriseId": "5214414483", "sourceRecordId": "112654987-02", "sourceSystem": "CSP_Facets", "surrogateIdentifier": "2265798477" },
{ "changeType": "merge", "oldEnterpriseId": "5214414483", "sourceRecordId": "100972~123564516584~2", "sourceSystem": "GPS", "surrogateIdentifier": "2265798472" }
]
}
}

Scenario 3 — Simple Merge / Undermerge (duplicate EID deleted)

A record moves from a duplicate EID into an existing target EID. The source EID is deleted as a result.

Target (existing) EID 5063007019 — record joined

{
"partyLinks": [
{
"surrogateIdentifier": "2142237885",
"targetPartyIdentifier": "5063007019",
"sourcePartyIdentifier": "5150382880",
"linkReasonCode": "2",
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 18:28:02.000",
"sourceTimestamp": null,
"userId": null
}
}
],
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 18:28:02.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [],
"records": [
{
"changeType": "merge",
"oldEnterpriseId": "5150382880",
"sourceRecordId": "PNX9012291085989000",
"sourceSystem": "CDB_CO",
"surrogateIdentifier": "2142237885"
}
]
}
}

Deleted EID 5150382880 — record left, EID subsequently removed

{
"partyLinks": [
{
"surrogateIdentifier": "2142237885",
"targetPartyIdentifier": "5063007019",
"sourcePartyIdentifier": "5150382880",
"linkReasonCode": "2",
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-05 17:57:16.000",
"sourceTimestamp": null,
"userId": null
}
}
],
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-05 17:57:16.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [
{
"changeType": "merge",
"newEnterpriseId": "5063007019",
"sourceRecordId": "PNX9012291085989000",
"sourceSystem": "CDB_CO",
"surrogateIdentifier": "2142237885"
}
],
"records": []
}
}
note

In this scenario the source EID's oldRecords[].changeType is merge (not split), because the record was consumed into the target EID rather than forked to a new one. The source EID is then deleted by EiMP.


Scenario 4 — Brand new record added (merge-new)

A net-new source record is added to an existing EID for the first time. partyLinks is null and oldEnterpriseId is null because the record did not previously belong to any EID.

{
"partyLinks": null,
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 19:28:58.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [],
"records": [
{
"changeType": "merge-new",
"oldEnterpriseId": null,
"sourceRecordId": "135549877-01",
"sourceSystem": "CSP_Facets",
"surrogateIdentifier": "2265801124"
}
]
}
}

Scenario 5a — Memdrop deletion (record dropped, EID remains)

A single source record is dropped from an EID, but the EID itself is not deleted. partyLinks is null.

{
"partyLinks": null,
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 19:32:07.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [
{
"changeType": "delete",
"newEnterpriseId": null,
"sourceRecordId": "0068465165165465465164968461",
"sourceSystem": "CDB_CS",
"surrogateIdentifier": null
}
],
"records": []
}
}

Scenario 5b — Memdrop deletion (record dropped, EID deleted)

All remaining source records are dropped and the EID is also deleted. surrogateIdentifier is populated (unlike 5a) because EiMP still tracks the link reference at deletion time.

{
"partyLinks": null,
"entityChange": {
"lastUpdated": {
"sourceSystemTimestamp": "2024-02-06 19:28:58.000",
"sourceTimestamp": null,
"userId": null
},
"oldRecords": [
{
"changeType": "delete",
"newEnterpriseId": null,
"sourceRecordId": "135549877-01",
"sourceSystem": "CSP_Facets",
"surrogateIdentifier": "2265801124"
}
],
"records": []
}
}
changeType values at a glance
changeTypeWhere it appearsMeaning
mergerecords[]This record joined this EID (moved in from another EID).
splitoldRecords[]This record left this EID (moved out to another EID).
merge-newrecords[]Brand new record, no prior EID (oldEnterpriseId: null).
deleteoldRecords[]Record was dropped from the EID entirely (newEnterpriseId: null).

Over-merges

An over-merge occurs when two distinct individuals become co-mingled under the same EID in EiMP. EiMP monitors for over-merges via Tableau dashboards, and a Data Steward team reviews them weekly. CCG is a downstream consumer — when EiMP corrects an over-merge with a SPLIT event, CCG processes it and applies the corresponding customer lifecycle mutations.

EiMP identifies three categories of over-merge risk:

CategoryDescription
Category 1 — TwinsTwins who share similar or identical first name, last name, date of birth, address, and sometimes a co-mingled SSN. Shared parental email further increases merge likelihood. EiMP runs Tableau dashboards to monitor for this.
Category 2 — Shared attributesMembers with the same first name, last name, and date of birth whose contact details (phone, email, address) have been incorrectly co-mingled by a source system. Those attributes feed the EiMP matching algorithm, potentially pushing two separate members past the merge threshold.
Category 3 — Manual errorsOccasional over-merges introduced during manual Data Steward processing, where co-mingled records are difficult to distinguish from records that genuinely belong to two separate individuals.

Deriving the eimpDeleted flag

The internal eimpDeleted flag is computed in the Migration Service (EimpConsumer) from two conditions in the incoming payload — the active field and the entityChange.records array. Both conditions must be satisfied for the flag to be true:

private boolean checkIfItsEidIsDeleted(MasterIndividual masterIndividual) {
return !masterIndividual.getActive()
&& Optional.ofNullable(masterIndividual.getEntityChange())
.map(entityChange -> isNull(entityChange.getRecords())
|| entityChange.getRecords().isEmpty())
.orElse(false);
}

In other words:

active fieldentityChange.recordseimpDeleted
falsenull or emptytrue
falsenon-empty (records present)false
true (or absent)anyfalse
  • eimpDeleted = true only when active = false and entityChange.records is null or empty (i.e., no new records are joining this EID).
  • If active = false but entityChange.records is populated (e.g., a MERGE event where records are being absorbed into this EID), the flag remains false because the EID is still receiving records and is not considered fully deleted.

This two-part condition ensures that the hard-deletion / inactivation path is only triggered when an EID is both marked inactive and has no incoming records — i.e., the EID is genuinely being retired rather than simply reshuffled.


Event ingestion and throttling

Event consumption from the Kafka topic is rate limited to prevent overwhelming downstream services.

  • The maximum number of events processed per second is controlled by the configuration property:
    • eimp.gcp.entity-change.max-events-per-second
  • In the current configuration, this value is set to 10, meaning the Migration Service will process up to 10 entity change events per second.
  • This throttling applies regardless of event type (SPLIT, SPLIT_AND_MERGE, MERGE, DELETE, etc.).

Combined with the kafka-consumer-eimp-enabled feature flag, this provides two controls over event processing:

  • kafka-consumer-eimp-enabledon/off switch to start or stop consuming events.
  • eimp.gcp.entity-change.max-events-per-secondthrottle to cap the rate of processed events per second.

Event types evaluation in Migration Service

Split

A merchant customer identifier is split and moved to another enterprise identifier. The oldRecords array will show which record was migrated.

  • EventType: SPLIT

Merge

A merchant customer identifier is combined into an existing enterprise identifier. The records array will contain the record being added.

  • EventType: MERGE

Split and Merge

Occurs when enterprise identifiers have both split and merged in a single operation. The oldRecords and records arrays will contain several updates. New merchant customer identifiers are added to the enterprise identifier, and some other records may be migrated to another enterprise identifier.

  • EventType: SPLIT_AND_MERGE

Delete

This event indicates that a merchant customer identifier has been deleted from an enterprise identifier.

  • EventType: DELETE

EIMP Event Processing in Customer Service

SPLIT / SPLIT_AND_MERGE (eimpDeleted = false)

  • Payment Methods: All customer payment methods are requested for deletion via DeleteAllCustomerPaymentMethodsCommandHandler. Verification attempts to confirm each is marked as DELETED. Failures are logged and ignored (flow continues).
  • Merchant Customer Identifiers: All removed via merchantCustomerHandler.deleteAllMerchantCustomerIdentifiers.
  • Demographics / HSID: Refreshed from the Identity Service (if the enterpriseId resolves). The stored HSID is nulled first if it is no longer present among current Identity HSIDs.
  • Customer isActive: Remains true.
  • EnterpriseCustomer: Demographics (and HSID if present) updated; enterpriseId remains unchanged.

SPLIT / SPLIT_AND_MERGE (eimpDeleted = true)

  • Customer: Marked inactive; enterpriseId overridden with an inactive form.
  • EnterpriseCustomer: enterpriseId overridden similarly; HSID cleared.
  • Payment methods: All customer payment methods are still requested for deletion via DeleteAllCustomerPaymentMethodsCommandHandler (same as the eimpDeleted = false path). Verification failures are logged and ignored.
  • Merchant customer identifiers: All removed via merchantCustomerHandler.deleteAllMerchantCustomerIdentifiers.
  • Demographics / HSID: Not refreshed from the Identity Service (the demographic-update step is skipped).
  • Customer isActive: Set to false.

MERGE (eimpDeleted flag ignored)

  • Payment Methods: Unchanged (no deletion).
  • Merchant Customer Identifiers: All removed.
  • Demographics / HSID: Refreshed from the Identity Service (same HSID nulling rule applies).
  • Customer isActive: Remains true.
  • EnterpriseCustomer: Demographics and HSID updated.

DELETE (reason = DELETE, eimpDeleted = false)

  • Payment methods: Unchanged.
  • Merchant customer identifiers: Unchanged.
  • Demographics / HSID: Not refreshed from the Identity Service. However, a conditional HSID clearing step runs before reason-specific processing: if the event's oldRecords contain an HS_ID source-system record whose sourceRecordId matches the currently stored HSID, the HSID is cleared from the EnterpriseCustomer.
  • Customer isActive: Remains true.
  • EnterpriseCustomer: Unchanged apart from the conditional HSID clearing described above.

DELETE (reason = DELETE, eimpDeleted = true)

  • Customer: Marked inactive; enterpriseId overridden with a synthetic inactive form.
  • EnterpriseCustomer: enterpriseId overridden similarly; HSID cleared unconditionally (via the inactivation handler). In addition, the same conditional HSID clearing step described in the eimpDeleted = false section above runs beforehand.
  • Payment methods: Not deleted (the checkEimpReasonAndApplyAction step is a no-op for DELETE).
  • Merchant customer identifiers: Not deleted.
  • Demographics / HSID: Not refreshed from the Identity Service.
  • Customer isActive: Set to false.

Other Event Types

  • Ignored: No customer mutations.
  • Customer isActive: Unchanged.

HSID Handling

Applied only for SPLIT, SPLIT_AND_MERGE, and MERGE when eimpDeleted = false:

  • If the stored HSID (UUID form) is absent from current Identity HSID identifiers, it is nulled before applying updated demographics.
  • This prevents retaining stale HSID associations after identity reshaping.

HSID Deletion on Customer Inactivation

  • When a customer is inactivated (i.e., eimpDeleted = true — meaning the payload has active = false and entityChange.records is null or empty), the system clears the HSID on the EnterpriseCustomer as part of the handleEimpDeleted flow. This ensures that no stale HSID remains for inactive or deleted customers.
  • Inactivation applies to any event type where eimpDeleted resolves to true (SPLIT, SPLIT_AND_MERGE, or DELETE). Note that MERGE does not check the eimpDeleted flag.

Conditional HSID Deletion on Delete Events (December 2025 Update)

  • Previously, no action was taken on DELETE events. Now, when a DELETE event is received that is related to the deletion of an HSID for a given EID, the system will:
    • Delete the HSID only if the HSID being deleted matches the HSID currently stored in the system for the given EID.
    • If the HSID does not match, no action is performed, as the HSID may have already been updated or replaced.
  • This logic prevents accidental removal of updated or unrelated HSIDs and ensures data integrity during event-driven deletions.

Effect of eimpDeleted Flag (Summary)

Event categoryeimpDeleted = falseeimpDeleted = true
SPLIT / SPLIT_AND_MERGEPurge payment methods + merchant identifiers; refresh demographics/HSIDInactivate customer; override enterprise identifiers; clear HSID; purge payment methods + merchant identifiers; no demographic refresh
MERGERemove merchant identifiers; refresh demographics/HSIDSame as false — flag is not used in the merge path
DELETEConditionally clear HSID if event's HS_ID matches stored HSIDConditionally clear HSID + inactivate customer + override enterprise identifiers; clear HSID unconditionally via inactivation

isActive Changes

  • Remains true for: SPLIT, SPLIT_AND_MERGE, MERGE, DELETE (eimpDeleted = false), and ignored reasons.
  • Set to false only for: SPLIT, SPLIT_AND_MERGE, or DELETE with eimpDeleted = true (i.e., active = false and entityChange.records is null or empty). MERGE does not evaluate eimpDeleted.

Processing Status Tracking

  1. Persist an EimpMasterIndividualDetails record in PROCESSING state.
  2. Apply reason-specific (and eimpDeleted-specific) side effects.
  3. Optionally refresh demographics (only for SPLIT, SPLIT_AND_MERGE, MERGE with eimpDeleted = false).
  4. Mark the record as COMPLETED or FAILED (errors during side-effect phases update status to FAILED and stop further mutations).