Skip to content

Conversation

@epeartree
Copy link
Collaborator

@epeartree epeartree commented Dec 3, 2025

Overview:
Implemented MDM (Master Data Management) expansion support for Patient instance bulk export operations. When the _mdm parameter is enabled, patient exports now automatically include all MDM-linked patients (golden resources and linked patients) along with their patient compartment resources.

What was done:

  • Added new expandPatient() method to IBulkExportMdmResourceExpander interface
  • Implemented MDM patient expansion logic in BulkExportMdmResourceExpander:
    • Accepts a patient ID string (e.g., "Patient/123")
    • Queries MDM links to find the patient's golden resource
    • Retrieves all patients linked to that golden resource via MATCH relationships
    • Returns a set of expanded patient ID strings including original, golden, and all linked patients
    • Handles error cases gracefully (missing patients, no MDM links)
  • Implemented corresponding method in BulkExportMdmEidMatchOnlyResourceExpander reusing existing functionalities
  • Caching of expanded patient IDs for reuse across resource types for both Group and Patient exports
  • Added relevant unit tests

closes #7421

peartree and others added 15 commits November 27, 2025 13:08
This commit eliminates redundant MDM expansion queries in bulk export
operations by introducing a caching mechanism for expanded patient sets.

Changes:
- ExportPIDIteratorParameters: Added two cache fields to store expanded
  patient IDs across resource type iterations:
  * myExpandedPatientIdsForGroupExport (HashSet<JpaPid>) for Group exports
  * myExpandedPatientIdsForPatientExport (HashSet<String>) for Patient exports

- JpaBulkExportProcessor: Refactored expansion methods with caching:
  * Renamed getExpandedPatientList → getExpandedPatientSetForGroupExport
    with cache-first lookup logic
  * Created getExpandedPatientSetForPatientExport with caching support
  * Updated getPidsForPatientStyleExport to use cached expansion
  * Modified filterBySpecificPatient signature to accept expanded patient
    IDs directly instead of ExportPIDIteratorParameters

Performance Impact:
MDM expansion now happens ONCE per bulk export job instead of N times
(once per resource type), significantly reducing database queries for
multi-resource exports.

Tests:
- All 19 bulk export tests pass (JpaBulkExportProcessorTest,
  BulkExportHelperServiceTest)
- Code compiled successfully with spotless formatting applied

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude 4.5 Sonnet <noreply@anthropic.com>
Implements GL_7714 to enable MDM (Master Data Management) auto-expansion
for Patient instance-level bulk exports (POST /Patient/[id]/$export?_mdm=true),
extending existing Group export MDM expansion pattern to Patient exports.

## Changes

### API Layer
- BulkDataExportProvider: Added _mdm parameter to patientInstanceExport()
  operation (Patient/[id]/$export only, not type-level Patient/$export)
- Updated doPatientExport() to accept and propagate theMdm parameter
- Added StringType import for parameter conversion

### MDM Interface & Implementations
- IBulkExportMdmResourceExpander: Added expandPatient() method signature
  for expanding single patient IDs via MDM links
- BulkExportMdmResourceExpander: Implemented expandPatient() for full MDM mode
  * Uses expandPidsBySourcePidAndMatchResult() to find all patients in MDM cluster
  * Populates MDM cache for resource annotation
  * Handles patients without MDM links gracefully
- BulkExportMdmEidMatchOnlyResourceExpander: Implemented expandPatient() for
  EID Match-Only mode using EID-based matching via expandMdmBySourceResourceId()

### Core Bulk Export Logic
- JpaBulkExportProcessor.getExpandedPatientSetForPatientExport(): Added MDM
  expansion logic that calls expandPatient() for each patient when _mdm=true
- Leverages caching infrastructure from GL_XXXX (fix redundant expansion) to
  expand once per job across all resource types

### Documentation
- BulkExportJobParameters: Updated comment to reflect MDM support for both
  group and patient instance exports

## Technical Details

- **Caching**: Expansion results cached in ExportPIDIteratorParameters to avoid
  redundant queries across resource type iterations
- **Dual Mode Support**: Works with both full MDM mode (link table) and EID
  Match-Only mode
- **Partition Aware**: Properly propagates RequestPartitionId through all queries
- **Error Handling**: Returns empty set if patient doesn't exist; returns single
  patient if no MDM links found
- **Type Consistency**: Uses Set<String> for patient IDs (e.g., "Patient/123")

## Testing

- All 15 JpaBulkExportProcessorTest tests pass
- Modules compile successfully
- Code formatted with spotless

## Dependencies

- Prerequisite: GL_XXXX (fix redundant MDM expansion) - provides caching
  infrastructure via getExpandedPatientSetForPatientExport() method

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude 4.5 Sonnet <noreply@anthropic.com>
Implements unit tests for the expandPatient() method which expands a single
patient ID to include all MDM-linked patients in the cluster. Tests verify
MDM link expansion, numeric PID handling, partition propagation, and no-link
scenarios using Mockito mocks.

## Changes

### Test Class Created
- BulkExportMdmResourceExpanderTest: Unit tests for expandPatient() method
  * Uses MockitoExtension with @mock and @Injectmocks
  * Mocks: MdmExpansionCacheSvc, IMdmLinkDao, IIdHelperService, DaoRegistry,
    IFhirResourceDao<Patient>, FhirContext

### Test Coverage (4 tests)

1. testExpandPatient_withMdmLinks_returnsExpandedCluster
   - Verifies patient with MDM links expands to include golden + all linked patients
   - Tests expansion from 1 patient to 4 patients (golden + 3 sources)
   - Validates MDM link DAO called with MATCH result
   - Confirms cache populated via setCacheContents()

2. testExpandPatient_withoutMdmLinks_returnsOnlySelf
   - Verifies patient without MDM links returns only itself
   - Tests empty MDM link list handling
   - Confirms cache NOT populated when no links exist

3. testExpandPatient_withNumericPids_usesNumericIds
   - Verifies numeric PIDs used when forced IDs are absent
   - Tests Optional.empty() handling for forced ID translation
   - Validates correct formatting (e.g., "Patient/999", "Patient/123")

4. testExpandPatient_partitionContextPropagated
   - Verifies RequestPartitionId propagated to DAO calls
   - Uses ArgumentCaptor to validate partition in SystemRequestDetails
   - Tests specific partition (RequestPartitionId.fromPartitionId(5))
   - Confirms partition used in both read() and getPidOrNull()

## Technical Details

- **MdmPidTuple Construction**: Uses static factory method
  `MdmPidTuple.fromGoldenAndSource()` (constructor is private)
- **PersistentIdToForcedIdMap Mocking**: Created proper mock for
  translatePidsToForcedIds() to avoid NullPointerException in
  populateMdmResourceCache()
- **Test Strategy**: Pure unit tests with mocks, no database or Spring context
- **Assertions**: Uses AssertJ for fluent assertions

## Validation

All 4 tests pass:
- Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
- Build: SUCCESS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude 4.5 Sonnet <noreply@anthropic.com>
…roken due to volatile caching of expansion.
@robogary
Copy link
Contributor

robogary commented Dec 3, 2025

Formatting check succeeded!

@epeartree epeartree changed the title mdm patient export expand feature MDM expansion support for Patient instance bulk export operations Dec 3, 2025
peartree added 3 commits December 3, 2025 11:38
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.

Supporting MDM Expansion for Patient instance bulk export.

3 participants