做 LeebertyPV 时有一个判断,直接决定了整个系统的形态。
触发判断的观察
药物警戒的八个领域 —— ICSR、信号检测、PSUR/PBRER、RMP、文献监测、AEFI、投诉召回、 GVP —— 看起来天差地别,但把它们各自的流程拆开看,是同构的:
一条受控的安全性记录 + 一串有角色与签名门槛的步骤。
快速报告是”记录 → 判定时限 → 提交”,信号评估是”记录 → 汇总证据 → 判定”, 文献筛查是”记录 → 初筛 → 确认”。骨架一样,填进去的字段和阈值不同。
当领域是同构的时,为每个领域写一个代码模块,是在重复表达同一件事。
于是领域变成数据
领域定义(步骤、角色、签名门槛、检查表)下沉成 JSON,加一个新流程只需往
seed/workflows/ 放一个文件。
收益不只是”少写代码”,而是新领域的一致性自动获得:它天然共享同一套合规内核, 不需要谁记得去给新模块补上审计追踪。
这也解释了一件事:LeebertyPV 是从 LeebertyGXP(GMP/GLP/GCP 工作台)架构改造而来的, 领域集合整体替换,合规内核原封保留。同构性被验证过了。
控制做进机制,而不是做进流程
第二条来自合规场景的一般经验:控制在系统里,不在流程文档里。
具体表现为:
- 审计追踪用哈希链实现(只可追加,改库被触发器拦截)
- 电子签名强制两个独立识别要素
- 所有记录修改强制填写理由
- 数据问题的提出人不能自己关闭
这些规则不依赖任何人记得遵守,它们是机制的一部分。这也是为什么 哈希链比日志表更有约束力 —— 日志表可以被有权限的人改, 哈希链不行。
一个反向的诚实标注
LeebertyPV 的 README 里写明了自己不是什么:
- 是技术演示与参考实现,不是经过验证的系统,不可直接用于生产法规申报
- 演示数据是虚构的
- 内置账号共用密码是已标注的风险(21 CFR Part 11.300(a) 要求账号唯一)
- 评分与检查表不构成法规符合性的最终判定
把限制写在项目最显眼的位置,比藏在免责条款里的做法有用得多 —— 因为使用者是要拿 它做真实判断的人,他们需要先知道边界在哪。
延伸:LeebertyPV · LeebertyGXP