iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0

摘要
Day 4 把 TW Core validation 降級處理為 NOT_EVALUATED。Day 5 實測 HAPI/HL7 package cache 能不能載入 tw.gov.mohw.twcore#1.0.0,並確認三個 MVP Profile canonical 是否能從 package 中讀到。

為什麼需要先實測 package loading?

Day 4 已經回答:

如果 TW Core 未正式驗證,畫面應該怎麼誠實顯示?

Day 5 要回答的是另一個問題:

HAPI 到底能不能在本機拿到 TW Core IG v1.0.0 的 package 與 Profile 定義?

這兩件事不同。

Day 4 是狀態設計,Day 5 是載入實測。

如果 package loading 失敗,下一步就不該急著寫 Profile validation,因為 validation support chain 連 Profile 來源都還不穩。

如果 package loading 成功,也不能直接把 TW Core validation 顯示成 PASSED。它只代表系統已經能讀到 Profile 定義,還沒有真的拿 Bundle 裡的 Patient、Observation、DiagnosticReport 去跑 Profile validation。

今天的實測範圍

Day 5 固定測試這個 package:

Package ID: tw.gov.mohw.twcore
Package version: 1.0.0
Package coordinate: tw.gov.mohw.twcore#1.0.0
Canonical base: https://twcore.mohw.gov.tw/ig/twcore
FHIR version: R4 4.0.1

並檢查三個 MVP Profile canonical:

Resource Canonical
Patient https://twcore.mohw.gov.tw/ig/twcore/StructureDefinition/Patient-twcore
Observation https://twcore.mohw.gov.tw/ig/twcore/StructureDefinition/Observation-simple-twcore
DiagnosticReport https://twcore.mohw.gov.tw/ig/twcore/StructureDefinition/DiagnosticReport-twcore

學習重點

  • HAPI 的 base validation、TW Core package loading、TW Core Profile validation 是三個不同層次。
  • package loading 成功只能證明 Profile 定義可取得,不能證明輸入資料符合 TW Core。
  • canonical resolution 要先實測,不能假設 package 裡一定有自己寫的 canonical。
  • probe 失敗時要能分類,否則後面排查會不知道是 dependency、package source、canonical 還是 validation support 設定問題。
  • Reference 測試資料可以先準備,但規則判定要留到交換契約層。

核心流程

Day 5 新增的流程在合法 Bundle 通過前置 gate 之後:

Bundle 已通過 JSON / FHIR R4 parse / Resource Type Gate
        ↓
TwCoreValidationService
        ↓
TwCorePackageProbe
        ↓
FilesystemPackageCacheManager
        ↓
loadPackage("tw.gov.mohw.twcore", "1.0.0")
        ↓
檢查 package metadata
        ↓
檢查三個 StructureDefinition canonical
        ↓
回報 package loading probe 結果
        ↓
TW Core validation 仍顯示 NOT_EVALUATED

重點是最後一步仍然是 NOT_EVALUATED

因為 Day 5 的成果是:

package 可載入,Profile canonical 找得到。

不是:

Bundle 已通過 TW Core Profile validation。

實作

Day 5 新增三個小型類別:

src/main/java/com/twlab/qualitygate/validation
├─ TwCorePackageProbe.java
├─ TwCorePackageProbeResult.java
└─ HapiTwCorePackageProbe.java
  1. 建立 TwCorePackageProbe
public interface TwCorePackageProbe {

  TwCorePackageProbeResult probe();
}

抽成介面的原因不是為了複雜抽象,而是測試需要控制 probe 成功或失敗,不應該讓單元測試真的依賴 package server。

  1. 建立 TwCorePackageProbeResult

probe result 回報四個資訊:

public record TwCorePackageProbeResult(
    boolean loaded,
    String category,
    String message,
    List<String> missingCanonicals
) {}

其中 category 用來協助排查:

category 意義
LOADED package 載入成功,必要 canonical 都找得到
DEPENDENCY HAPI/HL7 package loading 相關 dependency 不完整
PACKAGE_SOURCE package server、cache 或 package 來源問題
TERMINOLOGY terminology 相關問題
CANONICAL_RESOLUTION package 已載入,但必要 canonical 找不到
VALIDATION_SUPPORT_CONFIG 其他 validation support 設定問題
  1. FilesystemPackageCacheManager 載入 TW Core package

Day 5 的實際載入程式如下:

FilesystemPackageCacheManager packageCacheManager =
    new FilesystemPackageCacheManager.Builder()
        .build();

NpmPackage npmPackage = packageCacheManager.loadPackage(
    TwCoreValidationResult.PACKAGE_ID,
    TwCoreValidationResult.PACKAGE_VERSION
);

這裡使用 HAPI 帶入的 HL7 utilities package cache。實測後 package 會被放在本機 FHIR package cache 中。

  1. 檢查三個 canonical

載入 package 後,Day 5 確認 Profile 定義可讀:

private static final List<String> REQUIRED_CANONICALS = List.of(
    CANONICAL_BASE + "/StructureDefinition/Patient-twcore",
    CANONICAL_BASE + "/StructureDefinition/Observation-simple-twcore",
    CANONICAL_BASE + "/StructureDefinition/DiagnosticReport-twcore"
);

每個 canonical 都用 npmPackage.loadByCanonical(canonical) 檢查。

只要有一個找不到,就回報 CANONICAL_RESOLUTION,代表 TW Core package 不可用於 MVP。

  1. 接回 TwCoreValidationService

TwCoreValidationService 現在會在合法 Bundle 通過前置 gate 後執行 probe。

回傳狀態仍然是 NOT_EVALUATED

if (probeResult.loaded()) {
  return TwCoreValidationResult.notEvaluated(
      probeResult.message()
          + " Day 5 僅完成 package loading probe,尚未執行正式 TW Core Profile validation,不冒充 Profile 通過。"
  );
}

這裡刻意不新增 PASSED,避免把 package loading 成功誤解成資料通過 TW Core。

  1. 快取 probe 結果

package loading 不應該每次上傳 Bundle 都重新執行。

因此 TwCoreValidationService 會快取第一次 probe 結果:

private volatile TwCorePackageProbeResult packageProbeResult;

這樣上傳第二份 Bundle 時,不會重複下載或讀取 package。

實測結果

Day 5 用本機 probe 實際跑過一次,結果如下:

loaded=true
category=LOADED
message=TW Core package loading probe 成功:tw.gov.mohw.twcore#1.0.0,canonical base https://twcore.mohw.gov.tw/ig/twcore,FHIR R4 4.0.1 confirmed,已找到 Patient、Observation-simple、DiagnosticReport StructureDefinition。
missing=[]

這代表:

  • tw.gov.mohw.twcore#1.0.0 可以被本機 HAPI/HL7 package cache 載入。
  • package 回報的 FHIR version 包含 4.0.1
  • 三個 MVP Profile canonical 都能被讀取。

https://ithelp.ithome.com.tw/upload/images/20260806/20177913ibgJzbJqBA.png

頁面結果

使用 valid-minimal-lab-bundle.json 驗證時,頁面會顯示:

JSON parse: PASSED
FHIR R4 parse: PASSED
Resource Type Gate: PASSED
FHIR R4 validation: PASSED
TW Core validation: NOT_EVALUATED
tw.gov.mohw.twcore#1.0.0
TW Core package loading probe 成功:tw.gov.mohw.twcore#1.0.0...
Day 5 僅完成 package loading probe,尚未執行正式 TW Core Profile validation,不冒充 Profile 通過。

https://ithelp.ithome.com.tw/upload/images/20260806/20177913AclfbYSAQs.png

這張圖代表:

package loading 成功,但 TW Core validation 仍未執行。

Reference 探索資料

Day 5 另外新增三份 fixture,為 Reference rule 做準備。

Fixture 目的
valid-internal-reference.json Bundle 內 reference 都存在
missing-internal-reference.json Observation.subject 指向不存在的 Patient
external-http-reference.json 使用外部 HTTP reference

今天只確認這三份資料可以被現有 parser 與 inventory 穩定讀取。

例如三份資料都應該能顯示:

Patient: 1
Observation: 1
DiagnosticReport: 1
Not evaluated: 0

https://ithelp.ithome.com.tw/upload/images/20260806/20177913SLQy2DARrZ.png

注意:畫面目前不會顯示 LAB-REF-001 failed,且這三份 fixture 在 Day 5 的畫面結果會很相似,因為目前尚未實作 Reference rule。它們的價值是先固定後續要使用的正反例素材。

Day 4 與 Day 5 的差異

項目 Day 4 Day 5
主要問題 尚未驗證時怎麼誠實顯示 package 能不能真的載入
新增核心 TwCoreValidationResultTwCoreValidationService TwCorePackageProbeHapiTwCorePackageProbe
TW Core 狀態 NOT_EVALUATED 仍是 NOT_EVALUATED
差異 有固定 package metadata 與降級原因 message 進一步包含 package loading probe 實測結果
是否正式 Profile validation
是否準備 Reference fixture

真正的差異是:

Day 4 的 NOT_EVALUATED 是「未穩定載入 package」;Day 5 的 NOT_EVALUATED 是「package loading 已實測成功,但 Profile validation 尚未執行」。

自動化驗證

指令:

./mvnw test

測試結果:

Tests run: 16, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS

Day 5 測試重點:

  • package loading 成功時,TW Core result 仍然是 NOT_EVALUATED
  • package loading 失敗時,TW Core result 仍然是 NOT_EVALUATED,並顯示失敗分類。
  • 非法 JSON 與非 Bundle 不會觸發 package probe。
  • 同一個 service 只會執行一次 package probe,後續使用快取結果。
  • 三個 reference fixture 都能被 parser 與 resource inventory 讀取。

常見錯誤 & 排查

  1. loaded=true 寫成 TW Core validation passed

loaded=true 只代表 package 載入成功,不代表 Bundle 符合 TW Core Profile。

  1. canonical 拼錯卻歸類成 package 下載失敗

package 成功載入但找不到 StructureDefinition 時,應該歸類為 CANONICAL_RESOLUTION

  1. 測試直接依賴 package server

單元測試使用 fake probe 控制成功與失敗情境。真實 package loading probe 可以用手動實測或整合測試補充,不應讓一般單元測試因網路不穩而失敗。

  1. Reference fixture 被誤當成 Reference rule

missing-internal-reference.json 目前不會觸發 LAB-REF-001,後續才會建立交換契約規則。

  1. 每次驗證都跑一次 package loading

probe 結果已在 service 中快取。如果後續要支援切換 package version,才需要重新設計 cache key。

今天完成了什麼

  • 新增 TwCorePackageProbe 介面。
  • 新增 TwCorePackageProbeResult
  • 新增 HapiTwCorePackageProbe
  • 使用 FilesystemPackageCacheManager 實測載入 tw.gov.mohw.twcore#1.0.0
  • 確認 FHIR version 為 R4 4.0.1
  • 確認 Patient、Observation-simple、DiagnosticReport 三個 StructureDefinition canonical 可讀取。
  • TwCoreValidationService 接入 package loading probe,並快取 probe 結果。
  • 保持 TW Core validation 為 NOT_EVALUATED,不冒充 Profile validation 通過。
  • 新增三個 Reference exploration fixture。
  • 補上 package success、package failure、Bundle gate 前不執行 probe、reference fixture parsing 測試。

Day 5 尚未處理:

  • 正式 TW Core Patient Profile validation。
  • 正式 TW Core Simple Observation Profile validation。
  • 正式 TW Core DiagnosticReport Profile validation。
  • TW Core OperationOutcome issue 轉換。
  • LAB-REF-001LAB-REF-002LAB-REF-003
  • LOINC/UCUM 契約允許集合。
  • Quality Gate 的 Passed / Warning / Blocked 判定。

後續分層預計會變成:

quality-gate
├─ parser
├─ fhir-r4-validator
├─ resource-inventory
├─ tw-core-package-probe
├─ tw-core-validator
├─ reference-checker
├─ contract-rule
└─ report

Repository:twcore-data-quality-gate


上一篇
Day4 - TW Core 的降級處理 (Graceful Degradation)
系列文
醫療資料通過標準驗證,就真的能交換嗎?——30 天打造 TW Core 資料品質閘門5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言