跳轉到

測試資料檔清單

這份文件記錄「從零重建整套系統」時實際用到的來源檔:每個檔案從哪裡來、放在哪裡、 餵給哪個模組。2026-07-14 的全清重建(docker compose down -v → up -d --build → 重新匯入所有模組)就是照這份清單做的。

fhir-code/ 完全不在版控裡(檔案大、部分有授權限制、且全部可重新取得)。所以這份 清單就是那個資料夾唯一的紀錄——換機器時照著它把檔案補齊即可。專案自己整理、下載不到的 那兩個 LOINC 對照表則放在版控中的 data/loinc/(見下)。

檔案清單

放在 repo 根目錄的 fhir-code/ 底下。sha256 只列前 16 碼,用來確認拿到的是同一份檔案。

檔案 大小 sha256 (前16碼) 模組 / source_role
icd/10/icd10cm/icd10cm-table-index-2025.zip 20 MB 7e0fa0cae6348fb6 icd / icd10cm
icd/10/icd10pcs/icd10pcs_tables_2025.zip 648 KB 728d9b8f5c315548 icd / icd10pcs
icd/10/1.2023年中文版ICD-10-CM_PCS_1131118V3(…).xlsx 7 MB 1bf34d1f92930f29 icd / icd_zh_tw
loinc/2.80/Loinc_2.80.zip 74 MB 5a6b10dd6ed29704 loinc / loinc
snomed/SnomedCT_InternationalRF2_PRODUCTION_20250601T120000Z.zip 540 MB 3d6c189288e375d4 snomed / snomed_ct
rxnorm/RxNorm_full_06032024.zip 241 MB fc612ca0abee8955 rxnorm / rxnorm_full
twcoreig/v1.0.0/package.tgz 2.8 MB 2fa1419fa48d1545 ig / ig
(下載後才有)36_2.csv 44 MB — drug / drug_index_csv
(2026-10 起建議)icd/10/icd10cm/april-1-2026-code-descriptions-tabular-order.zip — — icd / icd10cm
(選用,以腳本產生)icd10who.json — — icd / icd10_who

ICD-10-CM 改用 CMS order file

上表的 icd10cm-table-index-2025.zip(tabular XML)是 2026-07-14 重建時用的檔案。自 2026-10 起建議改用 CMS 「Code Descriptions in Tabular Order」zip(2026-04-01 版,內含 icd10cm_order_2026.txt,98,186 碼):只有這種完整版 (icd.editions.complete = true)才會讓 FHIR validator 對未知 ICD-10-CM 碼報 error。WHO ICD-10 的 icd10who.json 以 node-server/scripts/validator-audit/harness/fetch_tx_terms.py 從 tx.fhir.org 取得。兩者都還沒有收進本機的 fhir-code/,故無 sha256。

本機載入器(未經管理後台上傳時)在 fhir-code/icd/10/icd10cm/ 找 ICD-10-CM zip 的順序:ICD_CM_ZIP 環境變數 → 檔名含 order / code-descriptions 的 CMS order-file zip → 檔名含 table-index / tabular 的 zip(同類取檔名排序最後者)→ 舊預設 icd10cm-table-index-2025.zip。所以把 order-file zip 放進該資料夾即可,舊的 table-index zip 可以留著。

umls/umls-2024AA-metathesaurus-full.zip(4 GB)也在資料夾裡,但目前沒有任何匯入流程 用到它,重建時可以略過。

兩個在版控裡的 LOINC 對照表

data/loinc/taiwan_mapping.csv(loinc / loinc_taiwan_mapping)和 data/loinc/lab_reference_ranges.csv(loinc / loinc_reference_ranges)是專案自己整理的 (台灣檢驗代碼對應、各醫學中心參考值彙整),網路上下載不到,所以它們放在 data/ 底下、跟著 repo 走——不是 fhir-code/(那整個資料夾都不進版控)。這兩個 role 在來源目錄中是選用的,但少了它們就沒有中文名稱與參考值(interpret_lab_result 無法判讀), 記得跟 LOINC zip 一起上傳。

各檔案從哪裡來

ICD-10-CM / PCS:CMS 官方年度釋出(CM 建議用 2026-04-01 的「Code Descriptions in Tabular Order」)(https://www.cms.gov/medicare/coding-billing/icd-10-codes)。 中文名稱 XLSX 來自衛福部的中文版 ICD-10-CM/PCS 對照檔。

LOINC 2.80:Regenstrief Institute(https://loinc.org/downloads/),需註冊帳號後下載。

SNOMED CT International RF2:需有效授權(可經 NLM / UMLS 帳號取得); https://www.nlm.nih.gov/healthit/snomedct/。不可再散佈。

RxNorm Full Release:NLM,需 UMLS 帳號;https://www.nlm.nih.gov/research/umls/rxnorm/。 本專案只當作 concept-only 的參考術語(供 IG ValueSet 展開),不是獨立的藥品工具。

TW Core IG package.tgz:從 https://packages.fhir.org 取得 tw.gov.mohw.twcore。 匯入時會自動遞迴抓取相依套件(hl7.terminology、hl7.fhir.r4.core、 hl7.fhir.r4.examples…,來自 packages.fhir.org,失敗時退到 packages2.fhir.org),2026-07-14 重建時 DB 裡有 9 個 package、約 21,000 個 artifact——所以只需要準備這一個 tgz。相依下載而來的套件會標記 install_origin = 'dependency'。

TFDA 藥品許可證 36_2.csv:repo 裡沒有,也不必手動放進 fhir-code/,直接下載:

curl -L "https://data.fda.gov.tw/data/opendata/export/36/csv" -o drug36.zip
# 是一個 zip,裡面就是 36_2.csv(約 44 MB、71,921 列、UTF-8-BOM)

其他兩個看起來合理的網址(cacheData/36_2.csv、codedata/datadownload/36)都是 404。

保健食品與食品營養不需要來源檔:health_supplements_sync / food_nutrition_sync 直接 打 TFDA Open Data API。

重建步驟

設定(OCR / TFDA / registry 位址、模型 provider 帳號與路由、passkey)用設定匯出檔還原(管理後台 系統 → 備份與設定,或下列 API;目前匯出格式為 v3,仍可匯入 v1 / v2 檔案):

curl -X POST localhost:8080/admin/api/settings/import \
     -H 'Content-Type: application/json' \
     --data-binary @tw-health-settings-YYYY-MM-DD.json

該匯出檔含 API key 與 passkey,不要進版控。自己留一份備份。

來源檔透過各模組頁的「資料生命週期」分頁上傳(或用 API;注意要帶 Content-Type: application/octet-stream, 否則 body 會被 express 的 4 MB parser 攔下):

curl -X POST "localhost:8080/admin/api/uploads?module_key=icd&source_role=icd10cm&filename=april-1-2026-code-descriptions-tabular-order.zip&auto_activate=true" \
     -H 'Content-Type: application/octet-stream' \
     --data-binary @fhir-code/icd/10/icd10cm/april-1-2026-code-descriptions-tabular-order.zip

接著依序排入 job:icd_import、loinc_import、snomed_import、rxnorm_import、 ig_import(要帶 job_options.object_key,值是該來源檔的 MinIO object key)、 health_supplements_sync、food_nutrition_sync、drug_index_import。

藥品 pipeline 會自動接續

drug_index_import 成功後會 auto-chain 出 drug_enrichment,再接 drug_analysis。 Enrichment 會去爬 TFDA 官方網站、Analysis 會呼叫 OCR + LLM,兩者都要花錢/花時間, 而且待處理的許可證有兩萬多筆。auto-chain 現在每批上限 200 筆 (DRUG_AUTOCHAIN_BATCH_LIMIT),會分批慢慢推進;不想跑就在 Jobs 頁面停掉它。 只想小規模驗證的話,自己排一個帶 {"limit": 30} 的 drug_enrichment 即可。

這份清單對應的資料量

2026-07-14 全清重建後的實際結果,可以拿來核對匯入是否完整(ICD 診斷碼數為當時的 tabular XML;改用 2026-04-01 order file 後為 98,186 碼):

模組 筆數
ICD 46,498 診斷 + 78,948 處置
LOINC 104,672 concepts
SNOMED CT 373,972 concepts
RxNorm 222,199 concepts
FHIR IG 9 packages / 20,996 artifacts
藥品 66,395 張許可證
保健食品 565
食品營養 1,702

語意搜尋要另外跑 *_embed job(需要可連線的嵌入端點,於 整合 → 模型端點 設定,例如 Ollama)。沒有 embedding 時,中文關鍵字 搜尋幾乎搜不到東西——因為 Postgres 的 simple tokenizer 會把整串中文品名當成一個 token, 子字串比對不到。這不是 bug,是設計上就靠向量搜尋來補。