跳到主要内容

8.5 WiNEX产品基于FHIR标准系统集成


8.5.1 背景

卫宁健康科技集团股份有限公司(以下简称卫宁健康)是在数字健康领域拥有二十多年深耕底蕴的行业领先者之一,旗下新一代产品WiNEX是基于中台思想构建的新一代医疗健康科技产品,是由业务中台、数据中台和技术中台组成的医疗数字化转型平台。以实现企业的1+X战略,即1个中台,X个场景解决方案。

WiNEX项目启动于2018年底,首批产品面向临床医生工作站、医院运营管理、主数据管理等核心要素构建。WiNEX中台作为数字化转型的“新基建”,其数据底座的发展首先是从元数据切入的,旨在引导整个产品的上层设计是基于元数据驱动的数据标准,及遵循领域驱动设计思想的数据模型这两个方面的。在产品研发过程中强调元数据管理先行,通过模型驱动服务和模块设计,使得系统开发和数据治理同步开展、双向赋能,并最终使得上游取得的治理成果得以在与异构系统互操作的场景中发挥作用。

WiNEX的数据标准及数据治理项目实际早于产品研发一年启动,以提供产研所需的治理体系要件,这包括一个可以承载受控数据元和值域的完整元模型,并通过对它的扩展,建立数据的统一术语和统一标识。2019年底,相对成型的新产品在技术架构上需要考虑与医院内其它外部系统的集成问题,鉴于此时FHIR第一个正式版本 R4版本已发布近一年(R4于2018年12月发布),架构团队决定尝试采用FHIR作为新一代产品与公司其它前代产品之间集成的互操作标准。最初的应用场景围绕门诊医生工作站与既有HIS核心产品之间的互操作展开,这通常涵盖了临床与费用两个主要业务域之间的大部分协同工作场景,包括患者建档、挂号与预约、临床医嘱的开立、住院的入出转、医技报告同步、收费与退费、药房发退药,及其它患者健康及临床信息同步等主要业务场景。

项目使用Simplifier作为规范发布平台,使用Forge作为规范设计工具。项目主要发布的是Profile和Extension,由于术语集在实际项目实施时可能存在不同客户医院之间的较大差异,目前尚未直接发布到平台上。可通过https://simplifier.net/winningtest 访问该规范项目。

项目在2020年间先后成功上线了上海市第六人民医院临港分院和山西医科大学第二医院,并在此之后在多家三甲医院和具有一定规模的私立医院集团成功上线。

HL7 China

图8.5.1 Simplifier上的卫宁健康WiNEX规范项目

8.5.2 业务需求与场景

使用FHIR标准覆盖的互操作场景主要存在于门诊和住院医生工作站CIS,护士工作站NIS,与核心HIS系统、医技系统之间的交互。WiNEX产品将中台分为几个主要的核心业务/域,包含患者域、就诊域、临床域、执行域、物品域、费用域、记录域。

患者域负责记录患者的个人社会统计学信息及健康史信息,承担患者主索引的作用,常见应用场景是患者建档。

就诊域负责医患交互过程管理,常见应用场景是挂号、预约、入院出院转院等。

临床域负责临床医生在诊疗过程中发生的与临床决策行为相关的场景,包括诊断书写、医嘱开立、检查结果调阅等。

执行域负责在诊疗过程在执行侧发生的有关辅助诊断、护理、治疗等行为的任务管理、过程跟踪、结果反馈等。

物品域负责医院内物资资源的管理和调度,例如药品、耗材的供应管理等。

费用域负责各类医疗服务的计费、结算、支付和账户相关的财务类业务。

记录域负责医疗记录、文书、档案相关的结构化业务实体的应用和管理等。

由于业务需求发生在一个固定的、封闭式的院内环境,因此多个业务域之间的交互是事件驱动的,且存在明确的业务上下文信息。同时较多事件需要采用异步消息传递以保证前端及时响应,因而适合使用消息机制来封装需要传递的资源。下表摘取了不同业务域中部分具有代表性的业务事件的定义,及其相关消息所使用的Resource和Profile。读者可以通过一下Profile部分的超链接,直接访问相关规范定义。

业务域事件EventCodingResources/Profiles
患者域患者登记PatientRegisteredPatient/Patient
Account/Account
Flag/PatientOrigin
患者域健康摘要更新/生命体征信息同步VitalSignsPanelUpdatedObservation/VitalsPanel
Encounter/OutpatientEncounter
Condition/PhysiologicalState
Condition/PathologicalState
Condition/IllnessSeverityLevel
患者域过敏信息同步AllergyUpdatedPatient/Patient
Encounter/OutpatientEncounter
Encounter/InpatientEncounter
PractitionerRole/PractitionerRole
Practitioner/Practitioner
Organization/Department
AllergyIntolerance/Allergy
就诊域挂号OutpatientRegisteredAppointment/OutpatientAppointment
Encounter/OutpatientEncounter
Encounter/HomeHealthEncounter
Encounter/InternetEncounter
Flag/PatientFlag
Flag/ClinicalTrialFlag
Flag/CharityFlag
Flag/SelfPay
Flag/MajorPyschosis
Flag/PatientBlacklistFlag
Flag/EmergencyGreenChannel
Patient/Patient
RelatedPerson/PrescriptionCollector
Account/Account
Coverage/MedicalInsurance
Coverage/CriticalIllnessInsurance
Slot/OutpatientSlot
PractitionerRole/PractitionerRole
就诊域住院单开立InpatientRegisteredServiceRequest/HospitalAdmissionRequest
Appointment/InpatientAppointment
Encounter/InpatientEncounter
Condition/Diagnosis
Condition/ChiefCompliant
Condition/PresentIllnessHistory
Patient/Patient
PractitionerRole/PractitionerRole
Practitioner/Practitioner
Organization/Department
Location/Ward
Location/Bed
Encounter/PreAdmissionEncounter
Condition/HealthCode
Procedure/SurgicalProcedure
CarePlan
Flag/EpidemicStrickenRegionTraveled
Observation/TransmissionMode
就诊域入院登记InpatientAdmittedAppointment/InpatientAppointment
Encounter/OutpatientEncounter
Location/Ward
Location/Room
Location/Bed
Encounter/InpatientEncounter
Condition/Diagnosis
Patient/Patient
Account/Account
Coverage/MedicalInsurance
就诊域转院申请InpatientWardTransferSubmittedEncounter/InpatientEncounter
Patient/Patient
Organization/Department
Location/Ward
Location/Room
Location/Bed
就诊域患者出院InpatientDischargedEncounter/InpatientEncounter
Practitioner/Practitioner
临床域医嘱签署ClinicalOrderSubmittedPatient/Patient
PractitionerRole/PractitionerRole
Practitioner/Practitioner
Organization/Department
Encounter/OutpatientEncounter
Medication/Medication
临床域手术申请SurgicalProcedureRequestedPatient/Patient
PractitionerRole/PractitionerRole
Practitioner/Practitioner
Encounter/OutpatientEncounter
Encounter/InpatientEncounter
ServiceRequest/SurgicalProcedureRequest
Procedure/SurgicalProcedure
Condition/Diagnosis
Location/Room
费用域医嘱缴费ClinicalOrderPaidPaymentNotice/PaymentNotice
PractitionerRole/PractitionerRole
Practitioner/Practitioner
Organization/Department
Encounter/OutpatientEncounter
Account/Account
执行域医技报告同步DiagnosticReportUpdatedDiagnosticReport/DiagnosticReport
Observation/ImagingResult
Observation/LaboratoryResult
Observation/Culture
Observation/MicroorganismIdentification
Observation/SusceptibilityMeasurement
Encounter/OutpatientEncounter
Encounter/InpatientEncounter
Task/ExecutionPlan
ServiceRequest/ImagingServiceRequest
ServiceRequest/LaboratoryServiceRequest
物品域住院发药InpatientMedicationDispensedMedicationDispense/InpatientMedicationDispense
MedicationRequest/InpatientMedicationRequest
Medication/Medication
Medication/TraditionalChineseMedication
MedicationKnowledge/MedicationKnowledge
Invoice/MedicationInvoice
ChargeItem/MedicationChargeItem
记录域诊断同步DiagnosisUpdatedCondition/Diagnosis
Condition/TCMDiagnosis
Condition/TumorDiagnosis
Condition/StomatologyDiagnosis
Encounter/OutpatientEncounter
Patient/Patient
PractitionerRole/PractitionerRole
Practitioner/Practitioner
Organization/Department

限于篇幅,表格省略了作为互操作双方的系统身份和交互关系的相关信息,但交互双方主要是来自于临床、护理、医技、收费与管理为代表的几个核心医院系统。大部分事件都存在明确的上下游关系,但部分事件事实上也可双向传递。例如患者的部分信息可以同时在患者登记时和在临床科室中进行编辑,一些临床信息也可在多个系统之间进行同步。

通过FHIR标准明确与业务场景相关的资源并作为设计依据,为本业务场景获得了良好的业务上下文参考,以便为未来所需的扩展提供了良好的设计基础,同时也帮助到我们对一些实体间业务关系的正确理解。这些理解因为基于FHIR这样的行业国际共识,而更具权威性和说服力。例如,在MedicationRequest资源下的dosageInstruction通过Dosage类型和Timing类型,展现了良好的用药剂量和用药时机的明细属性和关系设计,相比简单的剂量和频次代码设计,提供了更为详尽的设计参考和依据,足以应对更为多样化的临床场景需要。另一方面,引用(Reference)的引入也帮助在规范实施时,将关注点聚焦在资源的职责本身,以为设计带来更好的内聚性。

8.5.3 实现方法

  1. 团队协作

在项目初期对标准的探索阶段,FHIR设计者与开发团队需要更紧密地协作。规范的设计人员根据产品的数据模型及元数据所能提供的信息,结合互操作场景,选择适用的资源并决定资源之间的关系以及选择合适的标识设计。同时,互操作应用的实现人员则需要快速了解一种FHIR实现框架,以便结合现有技术栈与架构设计,形成与当前技术环境相一致的可实施方案。

  1. 框架与架构

产品采用了Java技术栈和微服务架构,因此选择HAPI FHIR作为标准的实现框架。建议考虑使用目前已开发成熟的框架,而不是从头开始自主开发框架,互操作的双方采用相同的或者是主流的框架往往能够减少互操作带来的隐性成本。基于此类成熟框架可以快速得到完善的FHIR代码模型,我们通常称之为DTO(数据传输对象),同时也会提供符合FHIR标准一致性的客户端与服务端技术。

对于一个完成与其它异构系统对接的典型互操作场景而言,通常会在架构图中的横向位置增加一个交换网关组件,通过它统一建立与其它系统的往来,这也被称为外观模式(Facade)。构建一个标准化交换网关的好处是,只需要发布标准规范,异构系统可以自主完成快速对接,其中涉及的调整通常是单方面的。

根据本身系统所处的地位不同,这一交换网关的角色可能不同。如果用于向外开放数据访问,则倾向于构建标准化数据服务,提供RESTful接口,因为面向资源的细粒度接口复用度更高;如果交互是由来自系统内部的业务事件天然驱动的,那么使用Messaging接口更利于实现。在WiNEX中构建的FHIR标准交换网关就属于后者。

下图中,作为产品内部的业务中台服务产生了业务事件,并通过一组消息中间件构成的消息机制,最终将封装了消息上下文的事件传递给关注这些事件的其它业务系统。

HL7 China

图8.5.2. WiNEX事件驱动的异步消息架构组件

  1. 交换范式

尽管RESTful接口也可用于系统之间的协同交互,但面向资源的接口颗粒度太细,往往完成一个事务操作需要经过多次调用。而使用消息封装的信息传递要高效一些,但是相应地,接口的复用性会更低。需要注意的是,对等系统之间的协作往往都具有上下游关系的特征,而在这种情况下,协作的发起通常都源自上游系统内部产生的事件。一部分事件是来自于具有明确业务内涵的业务事件,而另一部分事件则来自于操作事件,它们最终变成了命令和查询。不论哪一种,都可以通过FHIR为这些事件建模,并赋予它们一个事件代码。

WiNEX中的每一个事件以英文名称作为事件代码,用于在消息头中表示该消息的事件(参见MessageHeader.eventCoding)。在此需要说明,事件本身具有瞬时性质,且表示的是与过去所发生的事实有关的信息。因此WiNEX中遵循的事件命名法,都以名词开头,以动词的过去分词形式或是形容词结尾,用以描述对名词指代的对象所发生的操作或是其状态发生的改变。例如,前文事件表中ClinicalOrderSubmitted是一个事件代码,临床医嘱签署是这个事件的中文名称。消息定义也可使用资源MessageDefinition存放,可在其中给出事件代码、允许的资源、Profile以及应答。

  1. 规范发布

WiNEX使用了Simplifier的Profile设计工具Forge进行Profile和Extension的设计,并且设计好的Profile和Extension也能通过Forge发布到Simplifier平台上。由于是首个FHIR项目,并且创建之初是为了试点使用,因此目前发布并且在用的所有一致性资源的状态都是草稿(Draft)而非活动(Active)。之后会提到为什么保留这一状态的一些考量。

将所有的设计制品发布到一个允许公开访问的在线平台是非常重要的,区别于过去将规范仅以离线电子文档的形式发布和传播,如今大部分开放平台的技术文档均是具有良好技术支撑的在线文档。例如Swagger Doc可以根据发布代码动态生成文档。因此,将规范及其用法以在线方式发布并保持更新是确保一项标准持续发挥作用的基础。

FHIR官方也提供了实施指南模板,用于快速构建实施指南在线文档并发布成网站。WiNEX使用了Simplifier作为Profile的注册系统,主要是这是一套完整的工具链,对于小型设计团队来说是友好的。但有条件的团队可能会选择使用官方模板或者自建网站,来构建与自身组织的可视化风格保持一致的在线文档网站(NHS Digit与UK Core就是属于这一类)。

WiNEX并未使用Simplifier自带的实施指南文档功能,而是在自己的企业知识库中编写指南。但是这里需要指出,当一项规范被当作开放标准时,封闭式的文档是无法满足需要的。大量需要提供的结构定义、术语、示例、使用说明等,都需要通过超文本方式来形成一个有机的整体,并集中开放出来,因此在线发布平台才是优先选择。

  1. 规范设计

在WiNEX项目持续数年的FHIR规范设计过程中也获得了不少经验,在此简要介绍其中的一些。

Profile在设计过程中需要注意,资源的结构(Schema)是静态的,即使允许扩展,这也并不意味着资源的结构会因此改变。扩展本身是基于FHIR已经提供的机制,它是资源结构的一部分。因此不要试图在设计或实现的过程中随意修改结构,这也包括那些采用更高绑定级别的值集。设计相同资源类型的不同Profile时,应当考虑哪些元素可作为资源在不同场景下使用的辨别字段(Discriminator),例如,当Encounter资源需要根据门急诊和住院场景分别定义不同的Profile时,此时Encounter.class就可以作为此辨别字段。

在WiNEX项目中,对于资源用法不确定或没有合适资源时,此时可以考虑通过Parameters资源来传递信息。Parameters资源表达难以在概念上聚类的信息是推荐的做法,它经常被用在参数复杂查询参数的传递时。考虑到本地化应用场景的复杂性,FHIR目前提供的资源有可能无法覆盖到一个大型项目的所有可能场景。因此具备一定后备方案是必要的。

在WiNEX中一些场景的规范设计尽可能采用了FHIR官方提供的设计方案,例如生命体征(Vital Signs),FHIR给出了多个具体的生命体征的profile,因此WiNEX在之后多种类似生命体征也采用了同样的单独给出具体profile的设计。如果设计者不希望枚举所有生命体征,可以只给出一个profile涵盖所有可能。然而从业务约束上看,设计单独的profile有其必要性,因为每一种具体的生命体征的观察类型的术语值可能是不同的,这需要单独定义。因此WiNEX遵循了和FHIR官方一致的设计方式。

在WiNEX中,考虑创建一个新的Profile依据几个因素:具有相对独立的业务场景,具有可以预见的设计互斥性,具有需要取消的歧义或需要显式指定的约束。满足这些特征通常就意味着有必要创建新的Profile,然而在实战中贯彻这些规则常常也会带来Profile“爆炸”,使得设计和维护大量Profile成为一种挑战。有时候利用Profile可以基于另一个Profile的特性(Re-profiling),创建几个相同资源的Profile的公共“基类”可以帮助在需要对这些Profile进行统一修改时,仅需修改一个“基类”Profile就行。

8.5.4 应用效果

尽管早期尝试的FHIR项目仍然面临着一些体系不兼容问题,说明文档缺乏本地化问题,以及配套设施不完备问题(例如很难找到用于编辑消息定义及术语相关的定义资源的工具)。但是总体上,实施一项FHIR项目对团队资源提出的要求仍然要比前代标准小很多。并且通过几年发展,越来越多的开发人员对于FHIR的资源定义已经具备了初步的理解,知道如何在实现中避免犯错。同时,开源社区对FHIR的支持越来越大,以及像Simplifier和Forge这样的商用软件,在早期存在一定的不足,如今也变得成熟了。这为本地化规范本身的迭代提供了便利。

WiNEX在多家医院上线FHIR项目后,FHIR资源对于需求分析与设计中模棱两可的地带提供了良好的决策依据,帮助设计者和实现者精准把握互操作场景的本质。并通过快速建立共识,提高了短时间内实现大量互操作场景的效率。同时,FHIR在一致性上覆盖得更为全面,也使得在项目落地过程中总是可以找到对应的规范定义,从技术到业务,从交换方式、模型定义到术语定义,都有详尽的说明,较为全面的可参考要素在可行性上为互操作场景的研发节省了不小的时间成本。模块化的资源,使得在新项目中对不同本地化需求的适应性更强,可易于调整所需的资源类型数量和关系定义。这为项目实施时面对一些不确定因素时,提供了更好的扩展空间和回旋余地。通过FHIR还可以进一步提高在语法和语义一致性上的收益,使得FHIR相关的生态成为团队多种角色共同建设的基础,以为规范本身贡献更多的领域知识,形成有效沉淀,并逐渐探索到一种更可持续的互操作领域的发展路径。因此,这也是符合中台战略的理念的。