01 · 設計原則與資料權威

1.1 三層架構

┌──────────────────────────────────────────────┐
│ 臨床端(icu-vue 工作站)                        │
│   只講 FHIR。不知道 HIS 契約長什麼樣            │
└───────────────┬──────────────────────────────┘
                │ application/fhir+json
┌───────────────▼──────────────────────────────┐
│ EMR FHIR Server(本規格的範圍)                 │
│   資源儲存、業務規則、版本、稽核、簽章            │
└───────────────┬──────────────────────────────┘
                │ 整合層(見 06):非 FHIR
┌───────────────▼──────────────────────────────┐
│ 醫院 HIS                                      │
│   PrescriptionCreated / ServiceRequestCreated │
│   MedicationChangeStatus / CoverageUpdated…   │
└──────────────────────────────────────────────┘

分層的理由來自規格本身:S11S12 的 HIS 事件欄位帶著 archiveIddoituong_idloaigia_idperformingPlaceCode 這類HIS 內部識別碼,且明確標註「不可拿病歷號或舊科別 archiveId 代替」。這些不該洩漏到臨床端的資料模型,也不該塞進 FHIR 資源的核心元素——它們在 EMR 側一律存成 Identifier 或整合層的私有欄位。

1.2 資料權威:誰能寫什麼

29 份規格的每個欄位都標了「取得方式」。這直接決定 API 的可寫性:

取得 意義 欄位數 API 行為
M 手動輸入 431 可寫。臨床端 createupdate 的合法目標
H HIS 來源 425 唯讀。EMR 不接受寫入;由整合層同步後落地
P 引用其他資源 264 唯讀。以 Reference 表達,寫入時只接受被引用資源的 id
C 系統計算 88 唯讀。伺服器產生,客戶端送出即忽略或報錯
D 設備來源 1 唯讀Observation.device 標示來源設備

1.2.1 唯讀欄位被寫入時的行為

不要靜默忽略。伺服器回 422 Unprocessable Entity 並在 OperationOutcome.issue.expression 指出違規路徑:

{
  "resourceType": "OperationOutcome",
  "issue": [{
    "severity": "error",
    "code": "business-rule",
    "details": { "coding": [{ "system": "http://icu.emr.local/CodeSystem/api-error", "code": "READ-ONLY-SOURCE" }] },
    "diagnostics": "DiagnosticReport.issued 由 HIS 提供(取得=H),EMR 不接受寫入。",
    "expression": ["DiagnosticReport.issued"]
  }]
}

例外:update 時若客戶端把讀回來的唯讀欄位原值送回(常見於 read-modify-write),視為合法,不報錯。伺服器只在值有變動時才拒絕。

1.2.2 HIS 唯讀資源清單

以下資源在 EMR 側一律 read / search / history不開放 create / update / patch / delete

PatientEncounterCoverageDiagnosticReportSpecimenOrganizationLocationPractitioner

臨床端要對這些資源「做事」時,一律改成新增旁掛資源:例如對 DiagnosticReport 的「已閱/已判讀」記在 Provenance,不去改報告本身(見 02)。

1.3 缺值不補

這是整個原型最核心的臨床安全原則,必須在 API 層強制。

情境 錯誤做法 本規格要求
尚未量測 valueQuantity.value = 0 省略 value[x],填 Observation.dataAbsentReason = not-performed
檢驗待回 DiagnosticReport.conclusion = "正常" status = registered,不填 conclusion、不填 result
來源沒給旗標 interpretation = N 省略 interpretation。無旗標 ≠ 正常
醫囑未執行 MedicationAdministration.status = not-done 不存在執行紀錄就不建立資源。「沒有紀錄」與「記錄為未執行」是兩件事
過敏史查無 AllergyIntolerance 空集合當作無過敏 回空集合,並在 Patient 上帶 no-allergy-assertion-unknown 擴充;UI 顯示「來源未記錄,不能視為無過敏」
趨勢圖缺點 內插補值 序列斷開。03 的搜尋結果不補洞

dataAbsentReason 使用 R4 標準值集 http://terminology.hl7.org/CodeSystem/data-absent-reason,本專案只用其中五個:unknownnot-performednot-askederrormasked

1.4 不覆寫

任何「更正」都是新增,不是修改:

動作 FHIR 表達 保留
病歷更正 CompositionrelatesTo.code = replaces 指向舊版 舊版 statusamended,內容不動
交班更正 新交班 CompositionrelatesTo.code = replaces 舊版仍可讀,接收狀態獨立
醫師核對護理執行 Provenanceactivity = clinical-review 前次核對結論全部保留
照顧重點更新 CarePlanreplaces 指向舊版 每版作者與時間都在
檢驗結果重發 HIS 送新版 DiagnosticReportstatus = corrected 舊版保留於 _history

update 互動本身走 FHIR 標準版本控制(meta.versionId 遞增、_history 保留全部版本),但臨床語義上的更正一律建新資源,不靠 _history 表達。理由:_history 是技術稽核軌跡,臨床閱讀者需要在當前資源集合裡就看到「這份有更正版」。

1.5 時間

原型用 UTC+08 展示,正式部署需改為院區時區——這是 Q-01 的實際影響點。

1.6 識別碼策略

用途 表達 範例
EMR 內部主鍵 Resource.id(伺服器指派,不可預測) MedicationRequest/8f3a…
HIS 病歷號 Patient.identifier[use=usual] system: …/his-pid
HIS 就醫號 Encounter.identifier system: …/encounter-number
HIS 處方號 MedicationRequest.identifier system: …/his-prescription-number
HIS 每行藥品碼 MedicationRequest.identifier system: …/his-medication-request-id
HIS 需求單號/詳細行碼 ServiceRequest.identifier ×2 …/order-number…/service-request-number
給藥劑次 MedicationAdministration.identifier …/occurrence-id,值如 M1-V1-D1
送出冪等鍵 Bundle.entry.request.ifNoneExist + 整合層 idempotency_key 06

Resource.id 絕不等於任何 HIS 號碼。 規格明確警告「取消整張 HIS 處方的號碼;不是 medicationRequestId」——兩者混用會取消錯處方。

1.7 本規格不做的事