Summary
There is no dedicated patient-merge domain event. Consumers that need to react to a merge (read-store/CDC projections, cache invalidation, analytics) must depend on an incidental side effect rather than a first-class signal.
Environment
Problem
PatientService.mergePatients matches none of those method-name patterns, so no merge event is published. A merge currently surfaces only as a collection of incidental events:
VoidServiceEvent for the loser patient (voidPatient),
- per-record
SaveServiceEvents for the types that are reassigned through the proxy (encounters, visits, programs, non-encounter obs),
- a
SaveServiceEvent<PersonMergeLog> from the final savePersonMergeLog(...) call.
A consumer wanting to handle "a merge happened" has to key off SaveServiceEvent<PersonMergeLog> and read getWinner() / getLoser(). That works, but it is a dependency on an implementation detail (that the merge log is persisted through the service proxy) rather than a documented contract — a future refactor of how the merge log is saved would silently break every such consumer, with no event and no error.
Suggested fix
Publish a first-class merge event — e.g. a MergeServiceEvent carrying the winner and loser Person/Patient, fired from mergePatients after the transaction's work is complete — or extend OpenmrsServiceEventAdvice to recognise mergePatients. This gives consumers a stable, documented signal instead of relying on the PersonMergeLog save.
Related
Closely related to the data-completeness bug where mergePatients does not reassign Conditions/Allergies/MedicationDispenses (#6194) — fixing that also makes per-record save events fire for those types during a merge.
Summary
There is no dedicated patient-merge domain event. Consumers that need to react to a merge (read-store/CDC projections, cache invalidation, analytics) must depend on an incidental side effect rather than a first-class signal.
Environment
OpenmrsServiceEventAdviceadded in TRUNK-6429: Create application events for service method calls and en… #6084 emits typed*ServiceEvents forsave* / create* / void* / unvoid* / retire* / unretire* / purge*methods ofOpenmrsServices.Problem
PatientService.mergePatientsmatches none of those method-name patterns, so no merge event is published. A merge currently surfaces only as a collection of incidental events:VoidServiceEventfor the loser patient (voidPatient),SaveServiceEvents for the types that are reassigned through the proxy (encounters, visits, programs, non-encounter obs),SaveServiceEvent<PersonMergeLog>from the finalsavePersonMergeLog(...)call.A consumer wanting to handle "a merge happened" has to key off
SaveServiceEvent<PersonMergeLog>and readgetWinner()/getLoser(). That works, but it is a dependency on an implementation detail (that the merge log is persisted through the service proxy) rather than a documented contract — a future refactor of how the merge log is saved would silently break every such consumer, with no event and no error.Suggested fix
Publish a first-class merge event — e.g. a
MergeServiceEventcarrying the winner and loserPerson/Patient, fired frommergePatientsafter the transaction's work is complete — or extendOpenmrsServiceEventAdviceto recognisemergePatients. This gives consumers a stable, documented signal instead of relying on thePersonMergeLogsave.Related
Closely related to the data-completeness bug where
mergePatientsdoes not reassign Conditions/Allergies/MedicationDispenses (#6194) — fixing that also makes per-record save events fire for those types during a merge.