06 · HIS 整合對映

醫院 HIS 已有一套非 FHIR 的事件介面。本章定義 EMR 整合層如何把 FHIR 資源翻成這些事件,以及回應如何落回 FHIR。

臨床端永遠不碰本章的任何欄位。 這些欄位在 FHIR 資源上只以 Identifierextension[hisTransmissionEvent] 形式出現。

6.1 事件總覽

HIS 事件 方向 觸發 FHIR 對應
PrescriptionCreated EMR → HIS POST /MedicationRequest/{id}/$submit MedicationRequest
PrescriptionCancelled EMR → HIS 醫囑取消 MedicationRequest.status = cancelled
MedicationChangeStatus HIS → EMR HIS 端狀態變更 只寫 extension[hisTransmissionEvent]
ServiceRequestCreated EMR → HIS $submit ServiceRequest
ServiceRequestUpdated EMR → HIS 服務項目異動 ServiceRequest
ServiceRequestCancelled EMR → HIS 服務取消 ServiceRequest.status = revoked
檢驗結果回報 HIS → EMR 報告產出 DiagnosticReportObservationSpecimen
CoverageUpdated HIS → EMR 保險異動 Coverage

6.2 PrescriptionCreated

送出對映

FHIR HIS 欄位 取得 約束
Encounter.identifier archiveId H HIS 當前存檔代碼。不可拿病歷號或舊科別 archiveId 代替
MedicationRequest.authoredOn prescriptionTime M 格式 yyyyMMddHHmm。院方時區須明確(Q-01)
MedicationRequest.note advice M 醫師叮囑,可空
supportingInformationComposition P 段 progressNote P 取已確認版本的治療進度。空白阻擋送出
extension[emergencyCart] stockCode M 開立至急救車時條件必填;常規預備處方留空
medicationCodeableConcept.coding[his-medication] medications[]. 藥品碼 M 必須來自已同步目錄
dosageInstruction.timing(四時段) medications[].morning/noon/afternoon/evening M 單位由藥品/調劑目錄核對,各時段不可混用不同單位
(計算) medications[].quantity C 任一時段有值時 quantity = morning+noon+afternoon+evening
dispenseRequest.expectedSupplyDuration medications[].expectedSupplyDuration M 不得把天數自動乘入四時段 quantity 公式
dispenseRequest.performer medications[].dispenseStockCode M 無已同步代碼 → 阻擋送出
extension[consultationRequired] medications[].medicationConsultationRequest C 星號藥 true;非星號明確 false。不省略、不以 nullfalse
dosageInstruction.timing.repeat medications[].repeatPeriod M D1 無完整代碼字典,UI 選單未定(Q-05)

阻擋條件(送出前檢查)

編號 條件 錯誤碼
BR-INT-001 progressNote 為空 PROGRESS-NOTE-REQUIRED
BR-INT-002 任一藥品缺 dispenseStockCode 對照 DISPENSE-STOCK-UNMAPPED
BR-INT-003 medicationConsultationRequestnull TRISTATE-NOT-RESOLVED
BR-INT-005 四時段單位不一致 DOSE-UNIT-INCONSISTENT
BR-INT-006 archiveId 非本次就醫的當前值 ARCHIVE-ID-STALE

阻擋一律在 $submit422醫囑維持已簽未送,不進入 sent

回應落回

data.hisPrescriptionNumber        → MedicationRequest.identifier[system=…/his-prescription-number]
data.medications[].medicationRequestId → MedicationRequest.identifier[system=…/his-medication-request-id]
error / message / status          → extension[hisTransmissionEvent]

medicationRequestId 必須儲存,否則後續狀態回推與對帳無法配對。

回應的 medications[] 要與送出行逐行對帳:行數不符或有行對不上 → 標記 hisTransmissionStatus=unknown,產生人工處理 Task不自動重送

取消

PrescriptionCancelled:
  encounterNumber       ← Encounter.identifier
  hisPrescriptionNumber ← MedicationRequest.identifier[his-prescription-number]
  requester             ← 執行取消的醫師帳號(從權杖,非客戶端指定)

hisPrescriptionNumber 是整張 HIS 處方的號碼,不是 medicationRequestId

送錯會取消到別張處方。整合層必須驗證這個 identifier 的 system 正確(BR-INT-007),不接受任意字串。

6.3 ServiceRequestCreated / Updated / Cancelled

送出對映

FHIR HIS 欄位 取得 TDL 約束
requester.extension[department] requestRoomCode H 當前開立病房代碼
note.text note M 臨床備註
bodySite services[].bodySite M TDL.1166 不混用檢體類型
specimenSpecimen.type services[].specimen M TDL.1165 查不到正式字典時不用自由文字冒充代碼
extension[useContrast] services[].useContrastEnhanced M 未選不等於 false
extension[isConsumable] services[].isConsumable M 必須明確 true/false
extension[sameSurgicalTeam] services[].isSameSurgicalTeam M true/false/null 三態不可合併
locationReference services[].performingPlaceCode M 有病房優先病房,否則科室。查無對照時阻擋
Coverage → HIS doituong_id services[].patientType H 不得送範例字串 BHYTCoverageUpdated 沒有此欄
(HIS 字典) services[].priceType H HIS loaigia_id。查不到價格類型字典 → 缺值阻擋
priority severity(僅建立) M TDL.1157 建立用 1 正常/2 急/3 特急;修改時不送(Q-05)

阻擋條件

編號 條件 錯誤碼
BR-INT-008 performingPlaceCode 查無對照 PERFORMING-PLACE-UNMAPPED
BR-INT-009 priceType 缺值 PRICE-TYPE-MISSING
BR-INT-010 specimen 無正式字典代碼 SPECIMEN-CODE-UNMAPPED
BR-INT-011 isConsumable / useContrastEnhanced 未明確給值 TRISTATE-NOT-RESOLVED
BR-INT-012 patientType 為字面值 BHYT 或非 doituong_id PATIENT-TYPE-INVALID

修改的兩種語義

ServiceRequestUpdatedservices[].serviceRequestNumber 決定行為:

帶不帶 HIS 行為 FHIR 表達
舊詳細行碼 HIS 取消舊服務並新增新服務 ServiceRequest.status=revoked,建新的 ServiceRequest replaces 舊的
不帶 純新增 新建 ServiceRequest

orderNumber 必須填原需求單號,不得填詳細行碼(BR-INT-013)。這是兩個不同層級的識別碼:

取消

ipAddresscomputerName 為取得=C:由伺服器從連線取得,不接受客戶端提供,也不暴露權杖(BR-INT-014)。

6.4 MedicationChangeStatus(HIS → EMR)

HIS status 意義
1 新開立
2 審核
3 匯總領取
4 發放
5 急救車補充

這五個值沒有一個代表 eMAR 已給藥。

處理規則(BR-INT-004):

  1. 只寫入 MedicationRequest.extension[hisTransmissionEvent],附 changeStatusTime
  2. 絕不建立或修改 MedicationAdministration
  3. 絕不改變 MedicationRequest.status(臨床狀態軸)。
  4. 較舊的 changeStatusTime 不覆蓋較新的狀態(規格標【推論】,需 FPT 確認事件是否保證有序)。

6.5 檢驗結果回報(HIS → EMR)

HIS 送回報告時,整合層以 transaction Bundle 一次落地,確保報告與其逐項數值同時可見:

Bundle(transaction)
  ├─ Specimen        (upsert by TDL.1246 檢體編號)
  ├─ Observation ×N  (每個檢驗指標一筆)
  └─ DiagnosticReport(result → 上述 Observation)

落地規則:

來源 規則
旗標 有旗標才填 Observation.interpretation無旗標不填,不推定正常
缺值 dataAbsentReason,不填 value[x]不送 0
指標代碼 Q-02 未定前,Observation.code 只帶院內/來源碼,不硬指派 LOINC
重發 新版本 DiagnosticReport.status = corrected,舊版保留
無關聯醫囑 basedOn 留空並在 UI 顯示「未提供來源醫囑關聯」。不按名稱猜測配對

最後一條來自原型原文:「來源未提供醫囑關聯,不按名稱猜測配對」。名稱相近就自動綁定會產生錯誤的醫囑-結果對應。

6.6 冪等與重試

冪等鍵

outbound_request.idempotency_key(取得=C)由伺服器產生:

idempotency_key = sha256(encounterNumber ‖ resourceType ‖ resourceId ‖ versionId ‖ eventType)

重試

HIS 回應 動作
2xx + error=false 落回識別碼,hisTransmissionStatus=accepted
2xx + error=true rejected,保留 message不重試
連線失敗 指數退避重試 ≤3 次,同一冪等鍵
逾時無回應 hisTransmissionStatus=unknown停止重試,產生人工查明 Task

unknown 之後禁止自動重送(BR-ORD-007)。重送可能造成重複處方;必須由人確認 HIS 端的實際結果。

部分成功(Q-06)

ServiceRequestCreated 的回應是 data.services[] 陣列,但規格註明「未明確部分成功契約」。在 FPT 確認前,整合層採保守處理:

  1. 逐行對帳;行數或行碼對不上即視為整體結果不確定。
  2. 已取得 serviceRequestNumber 的行 → accepted
  3. 未取得的行 → unknown不重送,產生人工處理 Task
  4. 不因為部分行成功就把整張標成成功。

6.7 整合層邊界

整合層是獨立元件,不是 FHIR server 的一部分: