Skip to content

feat: implement patient demographic merge and unmerge#128

Open
D3V41 wants to merge 134 commits into
MagentaHealth:release/2026-03-17from
openo-beta:feature/demographic-merge-base-release
Open

feat: implement patient demographic merge and unmerge#128
D3V41 wants to merge 134 commits into
MagentaHealth:release/2026-03-17from
openo-beta:feature/demographic-merge-base-release

Conversation

@D3V41
Copy link
Copy Markdown
Collaborator

@D3V41 D3V41 commented Apr 25, 2026

Summary

  • Add full patient record merge workflow: search patients, select primary record, merge all associated data (notes, prescriptions, ticklers, labs, consultations, billing, etc.)
  • Add unmerge support with DemographicMergeEvent audit trail tracking which records were merged
image

D3V41 added 30 commits April 24, 2026 22:18
  - Interface with all method signatures for the copy engine
  - copyDemographic() uses INSERT INTO...SELECT (single SQL statement, no row-by-row)
  - DatabaseMetaData replaces information_schema (JDBC standard, H2-compatible)
  - ConcurrentHashMap caches table existence and column lists across 40+ table copies
  - validateIdentifier() whitelist prevents SQL injection on dynamic table/column names
…eMgmtIssue, CaseMgmtIssueNotes, CaseMgmtIssueNotesPK JPA entity classes
BillingONItem, Consent, ConsultationRequest, ConsultationRequestExt,
DemographicCustArchive, DemographicExtArchive, DigitalSignature, EFormValue,
EReferAttachment, EmailAttachment, EmailLog, Measurement, MeasurementsDeleted,
OLISQueryLog, OLISResults, PatientLabRouting, Prescription, Prevention,
PreventionExt, FormBCAR2020, HRMDocumentToDemographic to support
Hibernate detach-persist copy pattern
- Add DemographicMergeManager interface and DemographicMergeManagerImpl
- Add MERGED to PatientStatus enum in Demographic model
- Mark primary and secondaries as MERGED after merge (not IN)
- Restore to AC on unmerge; deactivate merged record C to IN
- Block MERGED and IN patients from re-merging (validation guard)
- Add demographicMergeRecord.jsp (step 1: search & select patients)
- Add demographicMergePrimarySelect.jsp (step 2: pick primary record)
- Both JSPs use pure JSTL/EL - no scriptlets, Bootstrap 5, OWASP e: encoding
- Security check via security:oscarSec tag with c:redirect (no scriptlets)
- Add searchDemographicsForMerge() and searchMergedDemographicsForUnmerge() to DemographicManager/DemographicManagerImpl
- Refactor DemographicMergeAction to handle search/selectPrimary display routes and use only managers (no direct DAO access)
- Register admin/DemographicMerge action in struts.xml with search, selectPrimary, success, successUnMerge, and failure results
- Fix action URLs in both JSPs to use admin/DemographicMerge.do
- Add Merge Patient Records link to admin.jsp popup menu
- Add Merge Patient Records link to leftNav.jspf
- Add admin.admin.mergeDemographic key to all 5 language resource files en, fr, es, pl, pt_BR)
…pyFormBooleanValues(). No generated key is needed here so batching is straightforward. Reduces DB round-trips from O(n) to 1 per form.
In copyCasemgmtNoteGroup(), the previous nested loop fired one JPQL UPDATE per (note × appointment) pair. Rewrite to loop once per appointment and pass all copied note PKs via IN :noteIds, reducing UPDATE statements from notes×appointments down to appointments.
D3V41 added 21 commits April 24, 2026 22:25
…emographic_merged table

Rename DemographicMergeEvent/DemographicMergeEventDao/DemographicMergeEventDaoImpl to DemographicMerge/DemographicMergeDao/DemographicMergeDaoImpl. Change @table  annotation from demographic_merge_event to demographic_merged so the new merge entity uses the existing table rather than a separate one.
Remove DemographicMerged.java, DemographicMergedDao.java, and DemographicMergedDaoImpl.java - entirely replaced by the renamed DemographicMerge/DemographicMergeDao classes that map to the same demographic_merged table.
Remove old DemographicMergeRecord2Action, demographic/data/DemographicMergede - rename event class references service class, demographicmergerecord.jsp, the entire commn.merge interceptor pattern (4 files), 10 domain-specific MergedDemographic DAOs, the old REST layer (DemographicMergeService + 3 DTOs), and the old DemographicMergedDaoTest.

Fix DemographicSearchResultTransformer and MessageUploader to use Demographic.getHeadRecord() instead of the deleted DemographicMerged service.
Remove @Autowired DemographicMergedDao field and delete the three methods that only existed to serve the deleted old merge action and REST endpoint: mergeDemographics(), unmergeDemographics(), getMergedDemographics(). Remove matching signatures from the DemographicManager interface.
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @D3V41, your pull request is larger than the review limit of 300000 diff characters

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant