Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
如何将诊所系统与 FHIR 后端集成
教程:将诊所 EMR 连接到患者的 FHIR R4 记录——医生目录,按记录号匹配,一次事务作为医生作者,实验室报告,其他提供者的数据和 Webhooks。
本教程将诊所的软件(EMR、实践管理系统或预订工具)连接到 Anpheros 中患者的 HL7 FHIR R4 记录:诊所及其医生在目录中注册,患者按诊所的记录号匹配,将就诊作为一次交易写入,并指定医生为作者,诊所将了解其他提供者添加的数据。 每个请求都 curl 针对免费沙箱进行,响应是平台自己的。
集成在诊所服务器上运行,对于诊所注册的患者使用项目 API 密钥,对于已有 Anpheros 记录的人,则使用他们批准的 OAuth 授权。
映射关系
| 诊所系统中的内容 | FHIR R4 中的内容 |
|---|---|
| 诊所、其部门 | Organization |
| 医生或护士 | Practitioner |
| 在该诊所工作、具有专科的该人员 | PractitionerRole |
| 病人档案及其编号 | 诊所系统中的 Patient,带有 identifier |
| 就诊 | Encounter |
| 生命体征、就诊期间测量的结果 | 链接到 Encounter 的 Observation |
| 诊断 | Condition (ICD-10),带有 verificationStatus 临时或确诊 |
| 处方、当前治疗 | MedicationStatement (ATC) |
| 信函、出院小结、扫描件 | 档案中的 DocumentReference |
| 实验室结果 | 实验室连接器,转换为 Observation |
步骤 1:注册诊所及其医生
目录资源不包含患者信息。同一环境中的其他项目可以读取它们,因此患者的其他提供者可以看到谁编写了什么,但只有您的项目可以更改它们。
export BASE=https://platform.anpheros.com/fhir/R4
export KEY=sk_test_…
H=(-H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json")
curl -X POST $BASE/Organization "${H[@]}" -d '{"resourceType": "Organization", "active": true, "name": "Clinica Cardio Nord",
"identifier": [{"system": "https://clinic.example/org", "value": "CCN"}]}'
curl -X POST $BASE/Practitioner "${H[@]}" -d '{"resourceType": "Practitioner", "active": true,
"name": [{"family": "Popescu", "given": ["Ana"], "prefix": ["Dr."]}]}'
curl -X POST $BASE/PractitionerRole "${H[@]}" -d '{"resourceType": "PractitionerRole", "active": true,
"practitioner": {"reference": "Practitioner/'$PRACTITIONER'"},
"organization": {"reference": "Organization/'$ORG'"},
"code": [{"text": "Cardiologist"}]}'
将返回的 ID 保存在您的员工记录旁边。当某人离职时,将其 PractitionerRole 设置为 "active": false;他们过去的写入记录将保留其姓名,并且他们将无法再通过您的系统进行操作。
步骤 2:匹配患者
对于诊所注册的患者,请创建 Patient,并将诊所的记录编号作为标识符:
curl -X POST $BASE/Patient "${H[@]}" -d '{"resourceType": "Patient",
"identifier": [{"system": "https://clinic.example/mrn", "value": "MRN-20981"}],
"name": [{"family": "Dinu", "given": ["Andrei"]}], "gender": "male", "birthDate": "1968-11-05"}'
此后,请使用该编号查找患者,切勿使用姓名和出生日期:
curl "$BASE/Patient?identifier=https://clinic.example/mrn|MRN-20981" -H "Authorization: Bearer $KEY"
当该人员已拥有 Anpheros 记录时,无论是来自其自己的应用程序还是其他提供商,诊所均不创建第二个记录。诊所会请求该人员通过 OAuth 授权访问,可以在接待处使用平板电脑进行授权,或在就诊前发送链接进行授权,使用一个机密应用程序(诊所服务器会保管密钥)。该人员会选择其记录以及诊所可访问的时长。具体步骤请参见 如何使用 SMART on FHIR 实现患者同意;令牌的 patient 字段是您应存储在文件中的 ID。
步骤 3:将一次就诊作为一个事务写入
一次就诊会产生多个属于同一整体的资源。将它们作为一个 transaction 发送,以便它们要么全部存储,要么都不存储,并指明谁在工作:X-Anpheros-Acting-As 命名了医生的角色。该角色将成为 Provenance 中的作者,写入访问日志,并以姓名显示给患者。
curl -X POST $BASE "${H[@]}" \
-H "X-Anpheros-Acting-As: PractitionerRole/$ROLE" \
-H "X-Anpheros-Author-Type: practitioner" \
-H "X-Anpheros-Source-System: ccn-emr" -d '{
"resourceType": "Bundle", "type": "transaction",
"entry": [
{"fullUrl": "urn:uuid:aa000000-0000-4000-8000-000000000001",
"resource": {"resourceType": "Encounter", "status": "finished",
"class": {"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "AMB", "display": "ambulatory"},
"subject": {"reference": "Patient/'$PID'"},
"serviceProvider": {"reference": "Organization/'$ORG'"},
"participant": [{"individual": {"reference": "PractitionerRole/'$ROLE'"}}],
"period": {"start": "2026-10-09T10:00:00Z", "end": "2026-10-09T10:30:00Z"}},
"request": {"method": "POST", "url": "Encounter"}},
{"resource": {"resourceType": "Observation", "status": "final",
"category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
"code": {"coding": [{"system": "http://loinc.org", "code": "8867-4", "display": "Heart rate"}]},
"subject": {"reference": "Patient/'$PID'"},
"encounter": {"reference": "urn:uuid:aa000000-0000-4000-8000-000000000001"},
"effectiveDateTime": "2026-10-09T10:10:00Z",
"valueQuantity": {"value": 92, "unit": "/min", "system": "http://unitsofmeasure.org", "code": "/min"}},
"request": {"method": "POST", "url": "Observation"}},
{"resource": {"resourceType": "Condition",
"subject": {"reference": "Patient/'$PID'"},
"encounter": {"reference": "urn:uuid:aa000000-0000-4000-8000-000000000001"},
"clinicalStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "active"}]},
"verificationStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status", "code": "provisional"}]},
"code": {"coding": [{"system": "http://hl7.org/fhir/sid/icd-10", "code": "I48.0", "display": "Paroxysmal atrial fibrillation"}]}},
"request": {"method": "POST", "url": "Condition"}}
]}'
transaction-response 包含 Encounter、Observation 和 Condition 的 201 Created。Observation 和 Condition 现在指向真实的 Encounter/0ca25459-…。每个资源的 Provenance 都命名了医生的角色、诊所和源系统:
"agent": [{"who": {"reference": "PractitionerRole/e6d8c227-…",
"identifier": {"system": "https://anpheros.com/fhir/CodeSystem/author-type", "value": "practitioner"}},
"onBehalfOf": {"reference": "Organization/c3a56a4b-…", "display": "Clinica Cardio Nord"}}],
"entity": [{"role": "source", "what": {"identifier": {"system": "ccn-emr"}}}]
诊断在确认之前是 provisional。稍后将其更新为 confirmed,历史记录将保留两者。每个字段的含义在 Medical data provenance explained 中进行了解释。
第 4 步:实验室结果和文档
来自诊所自有实验室的结果,或患者带来的报告,通过实验室连接器以每个报告一次请求的方式处理:
curl -X POST "https://platform.anpheros.com/v1/patients/$PID/labs/import" -H "Authorization: Bearer $KEY" \
-H "Content-Type: x-application/hl7-v2+er7" -H "X-Anpheros-Source-System: ccn-lab" --data-binary @oru.hl7
信函和出院小结属于文档:创建一个 DocumentReference 通过 /v1/patients/{id}/documents 并上传 PDF。原始文件永远不会被修改,从中提取的值会指向它。请参阅 如何将实验室结果导入 FHIR 记录 和 医疗数据 API。
步骤 5:阅读其他提供者撰写的内容,并坚持自己的职责范围
在获得患者同意后,诊所将在其权限范围内读取整个记录,包括其他诊所、实验室和患者添加的内容。它只能更改自己编写的内容。更新或删除其他组织的资源将得到 403 的响应,并且原始记录将保持不变。要更正其他提供者编写的内容,请编写您自己的资源(例如,包含您评估的新 Condition),让记录同时显示两者,并注明各自的作者。
就诊前,GET $BASE/Patient/$PID/$summary 会提供患者的国际患者摘要(International Patient Summary),其中包含来自所有来源的病症、药物、过敏史和近期生命体征。
步骤 6:接收新数据通知
为诊所的项目注册一个 webhook:
curl -X POST https://platform.anpheros.com/v1/webhooks -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"url": "https://ccn.example/anpheros/hook", "events": ["resource.created", "resource.updated", "consent.revoked"]}'
当另一个项目写入您的诊所可以访问的记录时,事件会通过 data.external: true 和来源进行通知,以便您的 EMR 可以显示“来自另一个实验室的新结果”,而无需轮询。 consent.revoked 事件表示该人员已撤销诊所的访问权限:停止同步该记录。签名、重试和负载在 Webhooks 中进行了介绍。
患者所见
患者在其记录中可以看到就诊信息、心率和初步诊断,这些信息均标记为由 Clinica Cardio Nord 的 Ana Popescu 医生添加。在其连接中,诊所的应用程序会列出每一次访问,当执业医师在执行操作时会显示其姓名。正是这种透明度促使患者愿意授予下次就诊的访问权限。
上线检查清单
- [ ] 已注册组织、执业人员和执业人员角色;离职人员设置为非活动状态
- [ ] 患者通过诊所的标识符匹配,绝不通过姓名匹配
- [ ] 通过 OAuth 同意访问现有记录,不重复创建
- [ ] 临床工作人员的每次请求都携带
X-Anpheros-Acting-As - [ ] 就诊记录以事务形式写入;诊断记录具有正确的验证状态
- [ ] 每次写入时都设置源系统;实验室报告通过连接器处理
- [ ] 验证签名的 Webhook 端点;处理
consent.revoked - [ ] 生产项目已签署 DPA(
sk_live_…密钥);请参阅 定价
常见问题解答
Anpheros 是否有现成的 EMR 连接器?
否。没有针对特定 EMR 或实验室系统的现成连接器;集成是针对 FHIR R4 和 REST API 构建的,通常作为 EMR 旁边的一个小型服务。HL7 v2 实验室消息按原样接收。
医生可以为两个诊所工作吗?
可以。一个 Practitioner 可以在每个组织拥有一个 PractitionerRole。X-Anpheros-Acting-As 中命名的角色决定了每次写入记录的是哪个诊所。
当患者撤销诊所访问权限时会发生什么?
诊所对该记录的调用将返回 401,并发送一个 consent.revoked 类型的 webhook。诊所写入的内容会保留在患者记录中,并附有其来源;诊所只是无法再读取或更改它。
相关
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card