AFAQ 医疗套件
在沙特阿拉伯 Prince Sultan 心脏中心落地的全院级 EHR/EMR 平台,由 Mo 带领 12 人团队从 2014 年做到 2017 年--从联创到 CTO 到主力工程师,一人集齐所有头衔。
2014 年 8 月,我 27 岁,干了一件所有理智的人都会劝你别干的事:在安曼联合创办了一家医疗软件公司。不是有 runway 计划和 pivot 选项的 SaaS side project,而是一家顾问公司,要在沙特阿拉伯的一家真实心脏病医院里交付完整的电子病历系统—有真实的患者、真实的临床工作流,以及搞砸了的真实后果。
我们叫它 AFAQ。十二名工程师。我同时是联创、CTO、主力工程师、产品经理、代理 CEO、IT 经理和开发总监—全在同一张名片上,第一年薪水实际上是零。没人提前告诉我「首席什么都管官」会让你以狗年的速度衰老。
这套系统到底是什么
AFAQ 的核心产品是一个覆盖全院的 EHR/EMR 平台:临床、行政和财务模块,加上完整的 ERP 能力。卖点是一致性—医院不应该为七个不同系统找七个不同的供应商。我们要交付一个平台,约旦制造,面向正从纸质和遗留系统向现代化升级的海湾医疗机构。
技术栈不简洁。Java EE。Spring Boot、Spring MVC、Spring Security、Spring WS。Hibernate 配 JPA。AngularJS 和 Bootstrap 做管理界面。Talend ETL 做数据转换。Tomcat 和 WildFly 做应用服务器。PHP 配 Symfony 和 Yii 做集成层。MySQL 和 Oracle 做主数据库。HL7 和 FHIR 做互操作性。还有 GT.M—后面我会讲。
对 12 人团队来说太多了?是的。我们还是交付了,因为签了合同的人没资格抱怨范围。
那个没人在写的 GT.M 连接器
这是十年之后我还为之骄傲的那块。
GT.M 是一个层次型 NoSQL 数据库—VistA 的存储引擎,VistA 是美国退伍军人事务部的开源 EHR,从 1980 年代起就在美国退伍军人医院里跑着。它运行在 MUMPS(后来叫 M)上。它的工具链稀少,文档假设你了解四十年前的背景知识。
2015 年,没人在为 GT.M 写现代数据库连接器。我们不得不写,因为 AFAQ 需要和那些把药房和账单数据放在 GT.M 基础设施里的医院系统对接—而「绕过它」在你的客户是心脏病中心、数据是临床上有分量的情况下根本不是选项。
所以我读了 GT.M 程序员手册,读了 MUMPS 规范,写了让 GT.M 能被现代 Java 服务调用的连接器。大多数工程师一辈子写零个数据库连接器。写了一个的人基本都是给 Postgres 或 MySQL 写,那种每个问题都有 Stack Overflow 答案的。2015 年写 GT.M 连接器意味着读那些从我出生之前就在做这件事的人写的源代码和邮件列表。每小时都值。
Prince Sultan 心脏中心
旗舰部署是沙特阿拉伯艾哈萨的 Prince Sultan 心脏中心—一家专科心脏机构,KPI 不是季度增长数字,而是门球时间(door-to-balloon time,患者出现胸痛到开始干预之间的时间间隔)、用药核对错误率、重复检验单量。
这些是生命安全 KPI。上线前,AFAQ 团队对中心的临床工作流做了 KPI 分析—绘制了纸质和遗留流程的地图,找出哪些数字最关键,然后在 EHR 内部建立了在正确位置展示正确数据的报告流水线。Talend ETL 承担转换负载,HL7 消息处理系统间的互操作层。
上线是个周二。几个护士问了一个按钮移到哪里了。这就是进展顺利的样子。
十二名工程师,每月一个架构决策
在同一个产品上同时管十二名工程师和担任主力工程师,是一个没有干净答案的协调问题。你应该委派技术决策,但你也应该比团队里任何人决策得更快,因为你是对合同负责的人。这两件事每周都在互相打架。
奏效的:极度具体的所有权划分。每名工程师拥有一件事。账单工程师拥有账单。药房工程师拥有药房。跨域决策走我这里,我每月最多做两个—因为每个横切的决策都是对所有其他人的上下文切换税。
我们在「领域驱动的精益所有权」成为博客概念之前就在跑它了。这不是什么原创想法,只是在范围宽、团队小的小型咨询公司里保持一致性的东西。
「已归档」在这里是什么意思
AFAQ 从 2014 年 8 月跑到 2017 年 1 月。两年半。我在 2017 年初离开,那套系统当时在生产环境中运行。它是否还在 Prince Sultan 心脏中心以某种形式运行—我真的不知道。医疗软件往往比原作者活得长很多。GT.M 连接器尤其如此:那种基础设施不会按任何人的期望时间线被替换。
这家公司与其说是一家公司,不如说是一座熔炉。十二名工程师进来的时候懂 Java 或 PHP,出去的时候懂医疗数据模型是如何工作的、HL7 为什么存在、怎么和有十二层采购审批的医院 IT 部门谈合同,以及当你的生产数据库是 Oracle 而你的客户运营着心脏重症监护室时,在数据模型层猜错一个假设要付出什么代价。
我也带着同样的知识出来了,加上一套非常具体的关于医疗软件为什么难的观点—而那几乎和代码没什么关系。