Skip to content

OCLOMRS: Support Concept Name Retirement (Voiding) and Name-Level Void Reasons #2519

@filiperochalopes

Description

@filiperochalopes

User story

As a Terminology Manager using the OCL Module, I want the subscription/import process to recognize when specific names of a concept are retired (voided) and to preserve the reason for that retirement, so my OpenMRS dictionary remains synchronized with CIEL’s data model and no editorial context is lost.

Use case

A user subscribes to a source (e.g., CIEL) where a concept has multiple names. In a new version, one of these names is marked as retired: true. OCL propagates the reason for this retirement via the update_comment at the concept version level. The OCL Module must parse this information during import to update the OpenMRS concept_name table, setting voided = 1 and populating void_reason.

Requirements

  • Support names[].retired in import logic
    • The importer in openmrs-module-openconceptlab must check the retired boolean for each item in names[].
    • If retired: true, the corresponding name in OpenMRS must be voided (concept_name.voided = 1).
  • Parse name-level void reasons from update_comment
    • Implement a parser for the established pattern:
      • Pattern: Retired name reason (NAME_UUID): REASON_TEXT
    • Match NAME_UUID to the name’s external_id (or uuid, when applicable) to extract the specific reason.
    • Handle multiple retired names in a single update_comment (multiple occurrences of the pattern).
  • Ensure data integrity in exports
    • Import must rely on the OCL version export file (bulk download).
    • Verify the export includes name-level retired flag and the concept-level update_comment.
  • Prevent data loss
    • If a name is voided and a reason is found, set void_reason to the extracted reason text.
    • If a name is voided and no matching reason is found, set a generic void_reason (e.g., “Retired in OCL”).
  • Keep concept active when only names are retired
    • If concept retired=false and name retired=true, only the name is voided; the concept remains active.

Acceptance criteria

  • Given a concept export includes:
    • names[].retired = true for a specific name, and
    • update_comment contains Retired name reason (external_id): reason,
    • When the OCL Module imports it,
    • Then the matching OpenMRS concept_name record is updated with:
      • voided = 1
      • void_reason = extracted reason
  • Given a name marked retired=true but no matching reason in update_comment,
    • When imported,
    • Then the name is still voided=1 and void_reason is set to a generic value.
  • Given concept retired=false but name retired=true,
    • When imported,
    • Then the concept remains active in OpenMRS and only the specific name is voided.

More details (collapsible)

Reference JSON (OCL API v2)

{
  "id": "1482",
  "retired": false,
  "names": [
    {
      "uuid": "259770136",
      "name": "Estructura del sistema cardiovascular",
      "external_id": "82622700-fa57-4431-99c3-b54343c22635",
      "retired": true
    }
  ],
  "update_comment": "Retired name reason (82622700-fa57-4431-99c3-b54343c22635): Este termo é obsoleto"
}

Expected OpenMRS result for the matching concept_name:

  • voided = 1
  • void_reason = "Obsolete term replaced by ..."

Example requests

curl -s -X GET \
  "https://api.staging.openconceptlab.org/orgs/CIEL/sources/CIEL/concepts/1482/19380208/" \
  -H "Authorization: Token ***" \
  -H "Accept: application/json" | jq
{
  "type": "Concept",
  "uuid": "19380208",
  "id": "1482",
  "external_id": "1482AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "concept_class": "Anatomy",
  "datatype": "N/A",
  "display_name": "Cardiovascular system",
  "display_locale": "en",
  "names": [
    {
      "uuid": "259770133",
      "name": "Cardiovascular system",
      "external_id": "1705BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
      "type": "ConceptName",
      "locale": "en",
      "locale_preferred": true,
      "name_type": "FULLY_SPECIFIED",
      "checksum": "b7a4699102829a2ddcd394e1730978d3",
      "retired": false
    },
    {
      "uuid": "259770134",
      "name": "Système cardio-vasculaire",
      "external_id": "1706BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
      "type": "ConceptName",
      "locale": "fr",
      "locale_preferred": true,
      "name_type": "FULLY_SPECIFIED",
      "checksum": "104df2980c35da0c7333d015dc78e86c",
      "retired": false
    },
    {
      "uuid": "259770135",
      "name": "Sistema circulatorio",
      "external_id": "b5777f44-0685-4602-8e17-73143b81b1fc",
      "type": "ConceptName",
      "locale": "es",
      "locale_preferred": false,
      "name_type": null,
      "checksum": "163a3aba94c6496b86ddf56f0b524e7d",
      "retired": false
    },
    {
      "uuid": "259770136",
      "name": "Estructura del sistema cardiovascular",
      "external_id": "82622700-fa57-4431-99c3-b54343c22635",
      "type": "ConceptName",
      "locale": "es",
      "locale_preferred": false,
      "name_type": null,
      "checksum": "12fbb3b03354112f3bbedf16f7406afa",
      "retired": true
    },
    {
      "uuid": "259770137",
      "name": "Estructura del aparato cardiovascular",
      "external_id": "5b585fea-fd26-4207-bfd0-1ab91dce4cdb",
      "type": "ConceptName",
      "locale": "es",
      "locale_preferred": false,
      "name_type": null,
      "checksum": "1b8ad49c99e2c77b6500475c03a84d73",
      "retired": false
    },
    {
      "uuid": "259770138",
      "name": "Mfumo wa damu mwilini",
      "external_id": "1707BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
      "type": "ConceptName",
      "locale": "sw",
      "locale_preferred": true,
      "name_type": "FULLY_SPECIFIED",
      "checksum": "69cfac6b133262dbc78f1c8000b5e98a",
      "retired": false
    },
    {
      "uuid": "259770140",
      "name": "Sistema cardiovascular",
      "external_id": "244ce535-9ac1-4799-8a78-200fb96f7826",
      "type": "ConceptName",
      "locale": "es",
      "locale_preferred": false,
      "name_type": null,
      "checksum": "a19f38e4fe3f7813f9a3ab1d3ac7536d",
      "retired": false
    },
    {
      "uuid": "259770141",
      "name": "Aparato cardiovascular",
      "external_id": "6330ba4b-e4f0-4a75-8a2a-5906fb8d03bb",
      "type": "ConceptName",
      "locale": "es",
      "locale_preferred": false,
      "name_type": null,
      "checksum": "93ab423844eab9c7b11f5e276c58120a",
      "retired": false
    },
    {
      "uuid": "259770139",
      "name": "Estructura cardiovascular",
      "external_id": "a1811490-03fd-4c74-b700-735cf262f64d",
      "type": "ConceptName",
      "locale": "es",
      "locale_preferred": false,
      "name_type": "FULLY_SPECIFIED",
      "checksum": "892c9f51a00df17b8e4e559a95aab5cc",
      "retired": false
    }
  ],
  "descriptions": [],
  "extras": {},
  "retired": false,
  "source": "CIEL",
  "source_url": "/orgs/CIEL/sources/CIEL/",
  "owner": "CIEL",
  "owner_name": "CIEL",
  "owner_url": "/orgs/CIEL/",
  "version": "19380208",
  "created_on": "2026-05-14T13:29:51.970865Z",
  "updated_on": "2026-05-14T13:29:52.008412Z",
  "version_created_on": "2026-05-14T13:29:51.970865Z",
  "version_created_by": "contato@filipelopes.med.br",
  "update_comment": "Retired name reason (82622700-fa57-4431-99c3-b54343c22635): [Insert the reason here]",
  "is_latest_version": true,
  "locale": null,
  "url": "/orgs/CIEL/sources/CIEL/concepts/1482/",
  "owner_type": "Organization",
  "version_url": "/orgs/CIEL/sources/CIEL/concepts/1482/19380208/",
  "mappings": [],
  "previous_version_url": "/orgs/CIEL/sources/CIEL/concepts/1482/19380206/",
  "source_versions": [],
  "collection_versions": [],
  "versioned_object_id": 310484,
  "checksums": {
    "smart": "24a2612b89bf88a79f41418d97aa0bcc",
    "standard": "a58795bb57c4ef41c1cbcae83821208a"
  },
  "version_updated_on": "2026-05-14T13:29:52.008412Z",
  "version_updated_by": "contato@filipelopes.med.br",
  "latest_source_version": null
}
Notes from review (PR context)
  • retiredReason not implemented: confirm whether to add a field or wire user input into existing comment field on PUT/DELETE.
  • Historical CIEL retired-name backfill needs a decision (populate from current CIELAdmin state vs no migration).
  • OCL Module sync layer update should be tracked explicitly (this issue).
  • Reference: OpenConceptLab/ocl_issues#2494 | locale retired oclapi2#865 (review)

Metadata

Metadata

Labels

component/omrsOpenMRS integrationsignal/has-dependenciesRelies on other work or external inputssignal/well-specifiedClear requirements and acceptance criteriastage/triagedAI triage complete — scored and classifiedtype/featureNew or improved functionality
No fields configured for Feature.

Projects

Status

Requirements

Relationships

None yet

Development

No branches or pull requests

Issue actions