Skip to content

Improve OpenCR patient matching rules for Haiti#4

Closed
mherman22 wants to merge 1 commit into
charess-org:mainfrom
mherman22:improve/opencr-matching-rules
Closed

Improve OpenCR patient matching rules for Haiti#4
mherman22 wants to merge 1 commit into
charess-org:mainfrom
mherman22:improve/opencr-matching-rules

Conversation

@mherman22

@mherman22 mherman22 commented Apr 2, 2026

Copy link
Copy Markdown

Summary

Replaces the minimal 2-rule OpenCR matching configuration with a comprehensive 10-rule set adapted for Haiti's identifier systems. The previous config only matched on exact biometric codes or exact demographics (all fields at jaro-winkler threshold 1.0), which missed patients with minor data entry errors.

Problem

The existing matching rules were too strict:

  • Only 2 rules with no fallback chain — if biometric match failed, the only alternative was an exact match on ALL demographic fields
  • All thresholds at 1.0 (exact match) — any typo in a name or birthdate caused a missed match
  • No swapped name detection — "Jean Baptiste" and "Baptiste Jean" were treated as different people
  • No fuzzy matching — "Jeen" vs "Jean" was a miss
  • No handling for missing fields — patients without a birthdate could never match

In Haiti's context, where data is often entered by different clerks at different facilities with varying data quality, strict exact matching leads to duplicate patient records in the master patient index.

Solution

10 matching rules evaluated in order (first match wins):

Rule Strategy Fields Use Case
1 Biometric exact Fingerprint code Strongest — biometric hardware match
2 Code National exact National ID Same person across facilities
3 Code National + demographics National ID + name + gender + DOB National ID with demographic confirmation
4 iSantePlus ID + demographics Facility ID + name + gender + DOB Re-registration at same facility
5 Exact demographics Name + gender + DOB No identifier available
6 Swapped names Given↔family + gender + DOB Data entry name order mistake
7 Fuzzy demographics Fuzzy name (0.8) + fuzzy DOB (0.8) Typos in names and birthdates
8 Exact names + fuzzy DOB Exact name + DateDamerau DOB (0.8) Birthdate typo only
9 Code National + partial National ID + name + gender (no DOB) Missing birthdate
10 Phone + demographics Phone + name + gender No identifiers, has phone number

Haiti-specific identifier systems used

  • http://isanteplus.org/openmrs/fhir2/6-biometrics-national-reference-code — M2Sys biometric fingerprint
  • http://isanteplus.org/openmrs/fhir2/5-code-national — National identification code
  • http://isanteplus.org/openmrs/fhir2/3-isanteplus-id — iSantePlus facility patient ID

Matching algorithms

  • exact — binary match (rules 1-6, 9-10)
  • jaro-winkler-similarity at 0.8 threshold — catches minor string typos (rule 7)
  • DateDamerau at 0.8 threshold — catches date entry errors like transposed digits (rules 7-8)

Auto-match vs potential match thresholds

Rules 5-10 use split thresholds to prevent false merges:

  • potentialMatchThreshold: 5 — flags for manual review in OpenCR dashboard
  • autoMatchThreshold: 6 — auto-links only when ALL fields in the rule match

This means fuzzy matches (rule 7) surface as potential matches for human review rather than being auto-merged, reducing the risk of incorrectly merging different patients.

Test plan

  • Deploy OpenCR with new rules
  • Create patient "Jean Baptiste" at facility 1
  • Create patient "Jean Baptiste" (same demographics) at facility 2 → should auto-match (rule 5)
  • Create patient "Baptiste Jean" (swapped names, same DOB/gender) → should match (rule 6)
  • Create patient "Jeen Baptiste" (typo in given name, same DOB/gender) → should flag as potential match (rule 7)
  • Create patient with same Code National at different facility → should auto-match (rule 2)
  • Create patient with same demographics but different birthdate (off by 1 digit) → should flag as potential match (rule 8)
  • Verify no false merges — patients with genuinely different demographics should NOT match

The previous matching config had only 2 rules with strict exact-match
thresholds (jaro-winkler 1.0), which caused missed matches for:
- Patients with minor name typos ("Jean" vs "Jeen")
- Patients with swapped given/family names ("Jean Baptiste" vs "Baptiste Jean")
- Patients with birthdate entry errors (1985-03-15 vs 1985-03-51)
- Patients missing identifiers (no biometric, no national code)
- Patients with missing birthdates

New matching rules (evaluated in order, first match wins):

1. Biometric exact match — fingerprint (strongest identifier)
2. Code National exact match — national ID alone
3. Code National + full demographics — national ID confirmed by name/gender/DOB
4. iSantePlus ID + full demographics — facility ID confirmed by demographics
5. Exact demographics — name + gender + DOB (no identifier needed)
6. Swapped name detection — given↔family + gender + DOB
7. Fuzzy demographics — jaro-winkler 0.8 for names + DateDamerau 0.8 for DOB
8. Exact names + fuzzy birthdate — catches DOB typos with exact name
9. Code National + partial demographics — for patients with missing DOB
10. Phone + demographics — last resort for patients without identifiers

All rules use Haiti-specific identifier systems:
- http://isanteplus.org/openmrs/fhir2/6-biometrics-national-reference-code
- http://isanteplus.org/openmrs/fhir2/5-code-national
- http://isanteplus.org/openmrs/fhir2/3-isanteplus-id

Rules 5-10 use split thresholds:
- potentialMatchThreshold: 5 (flags for manual review)
- autoMatchThreshold: 6 (auto-links only when ALL fields match)

This prevents false auto-merges while still surfacing potential matches
for human review in the OpenCR dashboard.
@mherman22

Copy link
Copy Markdown
Author

Merged into #3 (fix/pipeline-shr-integration). Closing this PR.

@mherman22 mherman22 closed this Apr 4, 2026
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