Chuyển đến nội dung chính

Bài 13: Profiles, Extensions và Implementation Guides

StructureDefinition, tạo Profile để ràng buộc Resource, Extensions (simple, complex, modifier), Slicing, Invariants (FHIRPath constraints). Implementation Guide (IG), IG Publisher, US Core Profile làm ví dụ, International Patient Summary (IPS). FHIR Shorthand (FSH).

🏗️ Kiến trúc — Bài 13 Bài 13: Profiles, Extensions và Implementation Guides

HL7 FHIR - Chuẩn Dữ liệu Y tế từ Cơ bản đến Nâng cao

Phần 4: Data Types, Terminologies và Profiles

xdev.asia

Xem bản video

1. Profiles — Ràng buộc Resources

Một Profile (StructureDefinition) thêm các ràng buộc lên resource FHIR cơ sở — bắt buộc elements, giới hạn cardinalities, binding terminologies, thêm extensions.

Ví dụ Profile bằng FHIR Shorthand (FSH)

Profile: VNPatient
Parent: Patient
Id: vn-patient
Title: "VN Core Patient Profile"
Description: "Patient profile cho y tế Việt Nam, yêu cầu CCCD, ngày sinh, giới tính"

// Bắt buộc các elements
* identifier 1..* MS
* identifier ^slicing.discriminator.type = #pattern
* identifier ^slicing.discriminator.path = "type"
* identifier ^slicing.rules = #open

* identifier contains
    cccd 0..1 MS and
    bhyt 0..1 MS

* identifier[cccd].system = "http://cccd.gov.vn" (exactly)
* identifier[cccd].type = http://terminology.hl7.org/CodeSystem/v2-0203#NI
* identifier[cccd].value 1..1

* identifier[bhyt].system = "http://bhxh.gov.vn/bhyt" (exactly)
* identifier[bhyt].type = http://terminology.hl7.org/CodeSystem/v2-0203#SB

* name 1..* MS
* gender 1..1 MS
* birthDate 1..1 MS

// Extension
* extension contains
    VNEthnicity named ethnicity 0..1 MS and
    VNNationality named nationality 0..1 MS

// Binding
* maritalStatus from http://hl7.org/fhir/ValueSet/marital-status (extensible)

StructureDefinition (JSON)

{
  "resourceType": "StructureDefinition",
  "url": "http://fhir.vn/StructureDefinition/vn-patient",
  "name": "VNPatient",
  "title": "VN Core Patient Profile",
  "status": "active",
  "kind": "resource",
  "abstract": false,
  "type": "Patient",
  "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
  "derivation": "constraint",
  "differential": {
    "element": [
      {
        "id": "Patient.identifier",
        "path": "Patient.identifier",
        "min": 1,
        "mustSupport": true,
        "slicing": {
          "discriminator": [
            {"type": "pattern", "path": "type"}
          ],
          "rules": "open"
        }
      },
      {
        "id": "Patient.identifier:cccd",
        "path": "Patient.identifier",
        "sliceName": "cccd",
        "min": 0,
        "max": "1",
        "mustSupport": true
      },
      {
        "id": "Patient.identifier:cccd.system",
        "path": "Patient.identifier.system",
        "fixedUri": "http://cccd.gov.vn"
      },
      {
        "id": "Patient.identifier:cccd.value",
        "path": "Patient.identifier.value",
        "min": 1
      },
      {
        "id": "Patient.name",
        "path": "Patient.name",
        "min": 1,
        "mustSupport": true
      },
      {
        "id": "Patient.gender",
        "path": "Patient.gender",
        "min": 1,
        "mustSupport": true
      },
      {
        "id": "Patient.birthDate",
        "path": "Patient.birthDate",
        "min": 1,
        "mustSupport": true
      }
    ]
  }
}

2. Extensions

Extensions cho phép thêm data mà base FHIR Resource không có — đây là cơ chế extensibility cốt lõi.

Simple Extension

Extension: VNEthnicity
Id: vn-ethnicity
Title: "Dân tộc Việt Nam"
Description: "Mã dân tộc theo danh mục 54 dân tộc Việt Nam"
Context: Patient
* value[x] only CodeableConcept
* valueCodeableConcept from VNEthnicityVS (required)
{
  "resourceType": "Patient",
  "extension": [
    {
      "url": "http://fhir.vn/StructureDefinition/vn-ethnicity",
      "valueCodeableConcept": {
        "coding": [
          {
            "system": "http://fhir.vn/CodeSystem/vn-ethnicity",
            "code": "01",
            "display": "Kinh"
          }
        ]
      }
    }
  ]
}

Complex Extension

Extension: VNAddress
Id: vn-address
Title: "Địa chỉ hành chính Việt Nam"
Context: Address
* extension contains
    province 1..1 MS and
    district 1..1 MS and
    ward 0..1 MS
* extension[province].value[x] only CodeableConcept
* extension[province].valueCodeableConcept from VNProvinceVS (required)
* extension[district].value[x] only CodeableConcept
* extension[district].valueCodeableConcept from VNDistrictVS (required)
* extension[ward].value[x] only CodeableConcept
* extension[ward].valueCodeableConcept from VNWardVS (required)

Modifier Extension

Modifier extension thay đổi ý nghĩa của element chứa nó — receivers PHẢI hiểu extension này.

{
  "resourceType": "AllergyIntolerance",
  "modifierExtension": [
    {
      "url": "http://hospital.vn/fhir/StructureDefinition/allergy-certainty",
      "valueCode": "unconfirmed"
    }
  ]
}

3. Slicing

Slicing chia một element lặp (cardinality 0..*) thành các "slices" riêng biệt với ràng buộc khác nhau.

* identifier ^slicing.discriminator.type = #pattern
* identifier ^slicing.discriminator.path = "type"
* identifier ^slicing.rules = #open
* identifier ^slicing.ordered = false

* identifier contains
    cccd 0..1 MS and    // Slice cho CCCD
    bhyt 0..1 MS and    // Slice cho BHYT
    mrn 1..1 MS         // Slice cho MRN (bắt buộc)
Discriminator TypeMô tả
valuePhân biệt bằng giá trị cụ thể
patternPhân biệt bằng pattern matching
typePhân biệt bằng type (choice types)
profilePhân biệt bằng profile
existsPhân biệt bằng sự tồn tại

4. Invariants (FHIRPath Constraints)

Invariant: vn-patient-1
Description: "Phải có ít nhất CCCD hoặc BHYT"
Expression: "identifier.where(system='http://cccd.gov.vn').exists() or identifier.where(system='http://bhxh.gov.vn/bhyt').exists()"
Severity: #error

Invariant: vn-patient-2
Description: "Nếu có CCCD thì phải có 12 chữ số"
Expression: "identifier.where(system='http://cccd.gov.vn').value.matches('^[0-9]{12}$')"
Severity: #error

5. Implementation Guide (IG)

IG là bộ đóng gói hoàn chỉnh: profiles, extensions, ValueSets, CodeSystems, examples, narrative documentation.

Cấu trúc dự án IG

vn-core-ig/
├── sushi-config.yaml        # SUSHI config
├── input/
│   ├── fsh/
│   │   ├── profiles/
│   │   │   ├── VNPatient.fsh
│   │   │   ├── VNEncounter.fsh
│   │   │   └── VNObservation.fsh
│   │   ├── extensions/
│   │   │   ├── VNEthnicity.fsh
│   │   │   └── VNAddress.fsh
│   │   ├── terminology/
│   │   │   ├── VNEthnicityCS.fsh
│   │   │   └── VNEthnicityVS.fsh
│   │   └── examples/
│   │       └── ExamplePatient.fsh
│   └── pagecontent/
│       ├── index.md
│       └── design.md
├── ig.ini
└── _genonce.sh

sushi-config.yaml

id: vn.fhir.core
canonical: http://fhir.vn/ig/core
name: VNCoreIG
title: "Vietnam Core FHIR Implementation Guide"
status: active
version: 0.1.0
fhirVersion: 5.0.0
copyrightYear: 2025+
releaseLabel: ci-build
publisher:
  name: Vietnam Health IT Association
dependencies:
  hl7.fhir.r5.core: 5.0.0

Build IG

# Install SUSHI
npm install -g fsh-sushi

# Compile FSH → FHIR JSON
sushi .

# Run IG Publisher
./_genonce.sh
# Output: output/ directory with HTML pages

6. US Core và IPS làm tham khảo

IGMô tảProfiles
US CoreHoa Kỳ, bắt buộc cho 21st Century Cures ActPatient, Encounter, Condition, Observation, Medication, ...
IPSInternational Patient Summary, ISO 27269Patient, Medication, Allergy, Problem, Immunization, ...
AU BaseAustraliaAU Patient, AU Practitioner, ...

7. Tổng kết

  • Profile — Ràng buộc Resource (bắt buộc elements, binding, cardinality)

  • Extension — Thêm data không có trong base (simple, complex, modifier)

  • Slicing — Chia repeating elements thành slices có ràng buộc riêng

  • Invariants — Business rules bằng FHIRPath

  • FSH + SUSHI — Ngôn ngữ DSL để viết profiles/extensions ngắn gọn

  • IG Publisher — Build documentation website từ FSH/JSON