Skip to content

ICD-11 Importer for OpenMRS 1.9+: Concepts, Mappings, and Hierarchical Sets - #843

Open
mwatha wants to merge 23 commits into
master_central_mahis_backendfrom
chore/ICD-11-script
Open

mwatha wants to merge 23 commits into
master_central_mahis_backendfrom
chore/ICD-11-script

Conversation

@mwatha

@mwatha mwatha commented Dec 15, 2025

Copy link
Copy Markdown
Contributor

Overview

This PR introduces a robust ICD-11 importer aligned with the OpenMRS 1.9+ data model.
It enables bulk ingestion of the official WHO ICD-11 MMS linearization into the OpenMRS concept dictionary, including:

  • Concept creation and updates
  • ICD-11 code mappings
  • Hierarchical chapter → block → category relationships
  • Backward-compatible schema upgrades from OpenMRS 1.7

The importer is designed to be idempotent, re-runnable, and safe for existing data.


Key Features & Implementation Details

1. ICD-11 Concept Import

  • Parses the WHO ICD-11 MMS Linearization Excel file.

  • Creates OpenMRS concepts using:

    • ConceptClass = Diagnosis
    • ConceptDatatype = N/A
  • Assigns:

    • Chapters, blocks, and categories
    • is_set where appropriate to support hierarchy
  • Automatically updates existing concepts if they already exist.

Duplicate handling

  • If a concept name already exists (same name + locale), the existing concept is reused and updated rather than duplicated.

2. Concept Naming (OpenMRS-compliant)

  • Creates ConceptName entries using:

    • locale = 'en'
    • concept_name_type = FULLY_SPECIFIED
    • locale_preferred = true
  • Prevents duplicate concept names on re-runs.


3. ICD-11 Code Mapping

  • Registers:

    • ConceptSource: ICD-11
    • ConceptMapType: ICD-11 Code
  • Each concept is mapped to its ICD-11 code using the concept_map table.

  • Mappings are uniquely constrained by (concept_id, concept_source_id, concept_code).


4. Proper ICD-11 Hierarchy Using concept_set_member

  • Implements ICD-11 structure using OpenMRS 1.9+ semantics:

    • Chapters contain Blocks
    • Blocks contain Categories
  • Uses the concept_set_member table instead of the deprecated concept_set.

  • Maintains correct ordering via sort_weight.

This ensures ICD-11 behaves as a navigable hierarchy in OpenMRS.


5. Automatic Schema Alignment (OpenMRS 1.7 → 1.9+)

The importer includes logic to detect and upgrade legacy schemas without data loss.

It will:

  • Create missing tables if absent:

    • concept_source
    • concept_map_type
    • concept_map
    • concept_set_member
    • concept_name_tag and related tables
  • Upgrade existing tables:

    • Rename legacy columns (source → concept_source_id, source_code → concept_code)
    • Add missing fields and indexes
  • Preserve all existing records

This allows the importer to run safely on older OpenMRS databases.


6. Idempotent & Safe by Design

  • Uses find_or_initialize_by / find_or_create_by patterns throughout.

  • Prevents:

    • Duplicate concepts
    • Duplicate mappings
    • Duplicate concept set members
  • Can be re-run multiple times without corrupting data.


Why This Matters

  • Enables ICD-11 adoption in OpenMRS-based systems
  • Supports clinical diagnosis coding, analytics, and interoperability
  • Aligns with OpenHIE / WHO-recommended terminologies
  • Provides a migration-safe path for systems upgrading from OpenMRS 1.7

How to Run

rails r bin/icd_11_concepts_exporter_openmrs_1.9.rb

Notes

  • Designed for OpenMRS 1.9+ but backward-compatible with 1.7 schemas.
  • UUIDs are explicitly set for reproducibility and interoperability.
  • Errors during mapping creation fail fast to prevent partial imports.

petroskayange and others added 23 commits December 2, 2025 13:09
- fetch patient by identifier instead of patient_id
🐛 fix(couchdb): fetch patient by identifier instead of patient_id
- add dispensed quantity, doses wasted, and location id
- include adjustments from pharmacy_obs table
- calculate dispensed quantity based on delivered, current, and adjustments
- add usage examples for sync tasks
- explain how to sync all records or run a specific job
- correct filtering of visits by closedDateTime
- ensure that only open visits can be closed
- add null string handling from frontend
Implement feature X to enhance user experience and optimize performance
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.

4 participants