4. CodeSystem资源深度解析

CodeSystem 是 FHIR 术语体系里承载“码从哪来、码长什么样、码之间什么关系”的核心资源。它不像 ValueSet 那样回答“哪些码可以用”,而是回答“这些码本身是什么”。工程上如果只把 CodeSystem 当成一张码表,往往会在后续做校验、翻译、筛选和本地化时踩坑。本节围绕 content、concept、property、designation、filter、supplement 六个机制展开,并给出可落地的建模判断。

content:决定这个 CodeSystem 是“完整码表”还是“片段”

content 是 CodeSystem 的必填枚举,取值有 not-present、example、fragment、complete 四种,它直接决定服务端和客户端对该资源的信任程度。complete 表示该 CodeSystem 已包含全部概念,可以用于强校验;fragment 表示只收录了部分概念,不能据此判定“码不存在”;example 表示示例性内容,通常不用于校验;not-present 表示资源本身不携带 concept,概念可能来自外部或 supplement。工程建模时,content 必须与业务用途对齐:如果要做必填校验,就必须保证 content=complete,否则校验逻辑应降级为“仅提示”。

concept 层次:用嵌套表达父子与分组

CodeSystem.concept 是递归结构,每个 concept 有 code、display,并可继续嵌套 concept 形成层次。层次通常表达 is-a 关系,例如“病毒性肝炎”下挂“乙型病毒性肝炎”。需要注意:层次是表达结构,不是强制的语义推理依据;若需要正式的子类关系,应通过 property 中的 subsumption 或 parent 明确声明。工程上建议控制嵌套深度,过深的树在检索和渲染时成本很高,必要时可用扁平结构加 parent 属性替代。

property:给码附加可计算的语义

property 是 CodeSystem 的“扩展字段”机制。先在顶层 CodeSystem.property 中声明属性定义(code、uri、type、description),再在每个 concept.property 中赋值。常见类型包括 code、string、boolean、integer、dateTime、Coding。典型用法有:status(active/retired)、parent、child、subsumption、effectiveDate。工程建模要点是:属性定义必须集中声明,避免每个 concept 自造字段;属性值类型要与声明一致,否则解析会失败。

designation:多语言与多场景显示名

designation 用于表达同一个码在不同语言、不同使用场景下的名称。它包含 language、use(Coding,如“同义词”“患者友好名”)、value。工程上,display 是默认显示名,designation 是补充。做中文界面时,应优先读取 language=zh 的 designation,找不到再回退到 display。需要注意 designation 不改变码的语义,只影响展示,因此不能用于校验。

filter:让客户端知道服务端支持哪些检索方式

CodeSystem.filter 声明该 CodeSystem 在 $validate-code 或 $lookup 等操作中支持的过滤参数,例如 is-a、descendent-of、regex、exists。它告诉客户端“你可以这样查”,而不是“你必须这样查”。工程上,如果服务端实现了某类过滤,应在 filter 中如实声明;客户端在发起筛选前应先读取 filter,避免发送服务端不支持的参数导致 400 或空结果。

supplement:在不改动原码表的前提下做本地化扩展

supplement 是一种特殊 CodeSystem,通过 CodeSystem.supplement 指向被补充的 CodeSystem,并只携带新增的 designation、property 等内容。它的价值在于:原码表保持只读和稳定,本地语言、本地别名、本地业务属性通过 supplement 叠加。工程建模时,supplement 的 content 通常为 complete 或 fragment,且必须声明 supplement 指向的规范 URL。查询时,服务端应将 supplement 与原 CodeSystem 合并后再返回。

CodeSystem 资源六大机制与工程关系 CodeSystem url / version / content content complete / fragment example / not-present concept 层次 递归嵌套 code / display / child property 顶层声明 + 概念赋值 status / parent / subsumption designation language / use / value 多语言显示名 filter is-a / descendent-of regex / exists supplement 指向原 CodeSystem 叠加 designation / property 工程判断 content=complete 才可强校验 supplement 合并后再查询

工程建模要点与示例

下面给出一个简化的 CodeSystem 片段,用于说明 content、concept、property、designation 的配合方式。示例为教学构造,非真实发布数据。

{
  "resourceType": "CodeSystem",
  "url": "http://example.org/CodeSystem/hepatitis",
  "version": "1.0.0",
  "content": "complete",
  "property": [
    { "code": "status", "type": "code" },
    { "code": "parent", "type": "code" }
  ],
  "concept": [
    {
      "code": "VH",
      "display": "Viral hepatitis",
      "property": [ { "code": "status", "valueCode": "active" } ],
      "concept": [
        {
          "code": "HBV",
          "display": "Hepatitis B",
          "property": [ { "code": "parent", "valueCode": "VH" } ],
          "designation": [
            { "language": "zh", "value": "乙型病毒性肝炎" },
            { "language": "en", "value": "Hepatitis B" }
          ]
        }
      ]
    }
  ]
}

建模时建议按以下顺序检查:第一,content 是否与校验强度匹配;第二,concept 层次是否与业务分类一致,是否需要额外 parent 属性;第三,property 是否在顶层集中声明,类型是否统一;第四,designation 是否覆盖目标语言,use 是否区分同义词与患者友好名;第五,filter 是否如实声明服务端能力;第六,supplement 是否只做叠加、不改原码。把这六项做成检查表,可以在集成测试前快速发现大部分术语服务问题。

当 content=fragment 时,$validate-code 返回“未找到”只能说明“当前资源未收录”,不能直接判定该码非法。工程上应把这种情况标记为“待人工确认”,而不是直接拒绝。
supplement 不能修改原 CodeSystem 中已有 concept 的 code 或 display,只能新增 designation 和 property。若强行覆盖,会导致不同服务端合并结果不一致。