HAKEEM 国家电子病历系统
约旦国家 EHR 基于 VistA/GT.M 构建,已落地四家医院。Mo 作为开发者和系统分析师,写 MUMPS 例程、C# GUI,以及 2012 年就在跑的移动端客户端--那是一段让你明白「能用的软件」和「国家依赖的基础设施」之间真正差距的三年。
2010 年,Node.js v0.4 发布,互联网花了整整一年争论服务器上的 JavaScript 是不是个笑话。与此同时,22 岁的我,在电子健康解决方案(EHS)—约旦政府与医疗提供商联合体之间的公私合营机构—的团队里,正在为一个将最终服务约旦四家医院的国家 EHR 的药房配药模块写 MUMPS 例程。
那就是 HAKEEM。团队角色:开发者兼系统分析师,2010 年到 2013 年。三年,四家医院,建在一个会让现代工程师皱眉的技术栈上—而那个技术栈,事实证明,正是为接下来十年做的最好准备。
HAKEEM 建在什么上
HAKEEM 建在 VistA 上—美国退伍军人事务部开发的退伍军人信息系统和技术架构。VistA 是地球上运行时间最长的 EHR 系统之一,从 1980 年代起就在美国退伍军人医院里部署。它运行在 MUMPS(后来叫 M)上,一个和你写过的任何东西都不一样的层次型数据库与语言组合。
这个决策是合理的。VistA 经过了商业 EHR 难以比拟的实战检验:药房模块、临床决策支持、排班、账单,全部在一个连贯的数据模型下。开源意味着约旦不需要为国家级部署授权商业软件。它运行在 GT.M(一个层次型 NoSQL 数据库)上,这意味着你需要能读 MUMPS 且不怕四十年老技术栈的工程师。
工作实际上是什么样的
头衔是开发者/系统分析师。实际上是三条同时并行的工作流。
MUMPS 例程。 团队在三个包里写 M 例程:药房、账单和 HL7 消息。MUMPS 里的药房配药逻辑是那种会冒犯你审美感受、然后正确运行四十年的东西。变量默认是全局的。数据库就是语言—全局变量(MUMPS 对持久变量的叫法)直接映射到层次型数据库结构。一个例程就是一个文件。现代意义上的函数不存在,有标签和 GOTO 等价物让结构化编程的人不舒服。然而:为 HAKEEM 药房模块写的配药逻辑,很可能今天还以某种形式在约旦医院里跑着。你不能对大多数 JavaScript 框架说这句话。
C# GUI 应用。 两个主要的:患者信息管理 GUI 和排班 GUI,两者都通过 VistA 的 RPC Broker 协议与 VistA 后端通信。这听起来无聊,不是。国家 EHR 里的患者信息管理意味着挂号护士的界面是数据流入每个下游系统的入口—药房、实验室、账单、报告。让垃圾进得去,你就要在上线六个月后在 Prince Hamza 医院调试患者 ID 不匹配。排班 GUI 有同样的分量:安曼综合门诊的门诊排班意味着跨多个科室的预约槽、取消处理和排班报告。无聊但一旦坏掉就极其重要的软件。
移动端 GUI。 2012 年。为一个医疗 EHR。Android 用 Java,iOS 用 Objective-C。2012 年的移动医疗不是一个成熟的领域—Android 在版本 4.0,iOS 6 还有几个月,临床医生在移动设备上访问患者记录的 UX 惯例还不存在。团队在一个移动设备上读错患者记录会有患者安全影响而非读错推文的约束下,摸索着弄清楚。
Bash 备份脚本。 也是工作的一部分。GT.M 数据库在 Linux 服务器上跑,需要可靠的备份和任务管理。不光鲜,完全是承重的。丢数据的医院会因为错误的原因上新闻。
四家医院,四个部署故事
HAKEEM 落地了四个机构,每一个都是自己的项目。
Prince Hamza 医院是大型综合医院—高容量、多专科、EHR 能力的全部广度。在你有每天数百次门诊的情况下,发现患者挂号和排班是否能扩展的地方。
安曼综合门诊是门诊模式。住院轻,预约管理和慢病随访重。排班 GUI 在这里赚到了它的存在价值。
Prince Hussein 医院有不能整洁映射到默认 VistA 配置的临床工作流需求。在 MUMPS 层定制,那种你在读一个 1993 年的例程然后决定改哪些行而不破坏所有下游的工作。
King Hussein 癌症中心是集成项目—KHCC 有自己的 EHR、自己的患者记录、自己的工作流,需要通过 HL7 v2 与 HAKEEM 连接。那个集成由团队构建,单独记录在别处;简短版本是跨两个 MRN 空间的患者身份解析、事件排序,以及竖线分隔消息的解析和转换。
国家级基础设施教给你什么
三年的 HAKEEM 教了一件此后带进每个项目的东西:「能用的软件」和「国家依赖的基础设施」之间的差距,是组织问题,不是技术问题。
代码是难的。MUMPS 的难是合理的,不只是审美上的。HL7 是难的。在没有人有剧本的情况下在 2012 年写移动 EHR GUI,是难的。
但最难的问题没有调试器。哪家医院得到下一次定制化 sprint?当两家医院对同一个 MUMPS 例程需要互相冲突的修改时,谁做决定?当你正在一个明天早上还要接诊患者的机构中途部署时,回滚意味着什么?
那三年的技术技能是有价值的。对复杂系统如何在组织层面失败的理解,价值更大。用 MUMPS 写药房逻辑,结果是一种同时学习两者的相当好的方式。