当前位置: 首页 > news >正文

[开源] 电子健康档案访问透明时间线:面向患者知情权与信息科合规管理的审计可视化系统

本项目是一个专为区域健康信息平台设计的电子健康档案(EHR)访问行为透明化工具,核心是把原本分散、隐晦、难以追溯的审计日志,转化为患者可查、信息科可管、监管可验的结构化轨迹。它不替代原有HIS或EMR系统,而是作为独立审计层,读取平台级审计日志(JSON/CSV格式),经解析、建模、评分、渲染后,提供CLI命令行查询、Web可视化看板、多格式合规导出三大交付形态。面向两类核心用户:一是需要确认“我的病历被谁看了、为什么看”的患者;二是需常态化生成《个人信息保护法》响应材料、应对等保测评与卫健监管检查的信息科工程师。技术上采用TypeScript+Node.js构建主引擎,Python辅助模拟真实多源日志数据,内存时序数据库支撑实时查询,SVG原生渲染高保真时间线,Socket.IO保障新记录毫秒级推送。

定位与能力范围

我们不做日志采集代理,也不改写医院原有系统接口。我们专注解决一个明确断点:审计日志有了,但没人能快速读懂、没人能按需验证、没人能向患者解释清楚。因此全部能力围绕「可解释性」展开,不是堆指标,而是让每一条访问记录都带上下文:哪家机构、哪位操作员(脱敏)、什么时间、调用哪个系统模块、填写了什么业务原因(如“门诊接诊”“转诊审核”“科研授权”)。完整度评分机制进一步把“查得全不全”量化为三个维度:时间覆盖度(是否跨年度连续)、机构多样性(是否含基层/三甲/公卫等不同层级)、类型多样性(是否含查询/下载/打印/共享等不同动作)。这既不是宽泛的安全态势感知,也不是粗粒度的访问统计大屏,而是落到每个患者ID、每条原始日志、每次人工可复核的透明呈现。

核心功能

所有功能均以“患者为中心、以合规为标尺”对齐。我们把能力分为三类交付面:命令行(供信息科批量处理与脚本集成)、Web看板(供窗口人员演示与患者自助)、导出报告(供归档与迎检)。

功能类别

具体能力

使用场景说明

CLI 查询工具

按患者ID查访问记录,支持时间范围、机构名称、操作员角色过滤

信息科日常核查某患者历史访问;配合脚本做月度异常访问扫描

全局统计

各机构访问量TOP10、访问类型分布饼图、业务原因热力排序

快速识别高频访问机构、常见用途偏差、潜在非必要调用

Web 可视化看板

SVG原生渲染时间线,支持缩放/平移/悬停查看详情,实时Socket.IO推送新记录

窗口人员向患者现场演示;安全审计员动态追踪当日访问流

患者自助查询

患者凭身份证号(前端校验)访问/patient.html,仅显示本人记录,操作员姓名脱敏为“张医生(XX医院)”

满足《个保法》第45条“个人有权查阅、复制其个人信息”要求

多格式导出

HTML交互报告、PDF合规报告(含法律依据标注)、JSON原始数据、CSV结构化表格

迎检提交PDF版《患者档案访问合规说明》;科研团队导入CSV做访问模式分析

特别说明:合规报告(compliance-report.ejs)模板已内嵌《个人信息保护法》第十三条、第二十一条、第三十条等条款原文及对应字段映射,非简单套话,而是每项导出数据均标注“此处满足法条X款Y项”。

使用与配置

部署极简,无外部数据库依赖。整个系统启动只需两步:

npm install npm run web

访问http://localhost:3000即进入主看板;http://localhost:3000/patient.html为患者入口。首次运行前建议先生成模拟数据验证流程:

python data/simulator.py

该脚本会按真实区域平台逻辑生成含12家机构、8类业务系统、5种访问原因的审计日志,覆盖门诊、住院、公卫、检验、影像等典型场景。

CLI是信息科主力工具,常用指令如下:

# 查某患者全量访问记录(默认最近90天) ts-node src/cli.ts query PATIENT_001 # 精确到某日,且限定某机构 ts-node src/cli.ts query PATIENT_001 --date-from 2024-06-01 --date-to 2024-06-01 --institution "市一院" # 直接输出完整度评分(含三项子分与总分) ts-node src/cli.ts query PATIENT_001 --completeness # 一键生成合规PDF报告(需本地安装puppeteer) ts-node src/cli.ts export PATIENT_001 --compliance --output ./report.pdf

所有CLI参数含义在SETUP.md(信息科部署指南)中有逐项说明,包括环境变量AUDIT_LOG_PATH指定日志源路径、COMPLIANCE_ORG_NAME注入本单位名称等关键配置。

工程结构

代码组织严格按职责分层,便于信息科二次开发或对接自有日志格式:

src/ ├── parser.ts # 审计日志解析引擎:统一输入(JSON/CSV),标准输出(AccessRecord[]) ├── database.ts # 内存时序数据库:基于Map+Array实现,支持按患者ID/Org/TimeRange高效检索 ├── completeness.ts # 完整度评分引擎:纯函数式计算,输入记录数组,输出{timeCoverage: 0.87, orgDiversity: 0.62, ...} ├── web/ │ ├── server.ts # Express服务器:提供/api/records、/api/stats等REST端点 │ └── timeline-renderer.ts # SVG时间线渲染器:不依赖D3,手写path生成,兼容低配终端机 ├── cli.ts # CLI主入口:封装parser/database/completeness,提供一致命令体验 └── adapters/ # 预留目录:未来接入医院HIS审计日志、省级平台API时,只在此写适配器

types.ts中定义了核心类型AccessRecord,强制包含patientIdinstitutionoperatorRoleaccessReasonaccessTimesystemModule六项必填字段,确保任何日志源接入后语义不丢失。

数据与扩展

数据来源完全开放。当前内置Python模拟器(data/simulator.py)生成的数据,字段设计严格对照国家《医疗卫生机构网络安全管理办法》附录B“审计日志字段要求”,包含:

  • patientId

    : 患者唯一标识(支持身份证号、医保卡号、平台ID)

  • institution

    : 机构全称(非缩写,如“XX市第一人民医院”)

  • accessReason

    : 业务原因(枚举值:门诊接诊、住院查房、转诊审核、公卫随访、检验申请、影像调阅、科研授权、其他)

  • systemModule

    : 调用系统模块(HIS、EMR、LIS、PACS、公卫系统、区域健康档案平台)

若需对接真实日志,只需编写adapters/下的新适配器,实现parse(rawLog: string): AccessRecord方法即可。所有导出格式(HTML/PDF/JSON/CSV)均基于同一份AccessRecord[]数据源,保证结果一致性。

限制与说明

本系统有明确边界,我们不承诺也不支持以下场景:

  • 不替代医院原有审计日志采集系统,不提供网络探针或数据库触发器;

  • 不存储患者敏感身份信息(如完整身份证号、手机号),患者自助页仅校验,不落库;

  • 不提供用户权限管理系统(RBAC),CLI与Web均默认开放只读访问,生产环境需由信息科前置Nginx做IP白名单或反向代理鉴权;

  • 内存数据库设计为单机轻量级方案,适用于日均审计日志<50万条的区域平台;超大规模需自行替换为TimescaleDB等时序数据库(接口已预留)。

所有限制均在README.mdSETUP.md中坦诚说明,无隐藏前提。我们相信,透明的系统边界,才是可信赖的起点。

项目地址:
https://github.com/nexorin9/ehr-access-timeline

http://www.jsqmd.com/news/943033/

相关文章:

  • DeepSeek-Coder-V2技术深度解析:如何实现开源代码智能的突破性性能
  • 抖音下载器:如何轻松批量保存你喜欢的短视频与直播回放
  • 基于Wio Terminal的双频WiFi分析仪:从硬件选型到可视化实现
  • 别再手动算料了!用简道云BOM模板,5分钟搞定生产物料清单(附免费模板链接)
  • 露天矿车辆管理平台物联网方案
  • R语言可视化进阶:如何用bayesplot和ggplot2定制出版级贝叶斯分析报告?
  • IOTA 学习笔记(九):最小 Counter 合约在 Localnet 上的完整演示
  • C语言基础入门到进阶:变量、函数、指针与内存管理一文讲透
  • 通达信缠论插件:3分钟实现自动画中枢的终极解决方案
  • 绕过小米社区5级限制:一个Python脚本+替换系统App的BL解锁思路拆解
  • 3串锂电池保护芯片PW7126搭配四颗PW4406A构成6A方案
  • 通达信缠论插件终极指南:5分钟让复杂技术分析变简单
  • 自己动手丰衣足食-自己动手修改GBA ROM游戏文件
  • OData 入门与详解:从基础到企业
  • PostgreSQL 中 now() 函数事务内行为异常,clock_timestamp() 成解决方案
  • 如何在10分钟内构建专业级Arduino音频应用:终极嵌入式音频库指南
  • IOTA 学习笔记(十):交易与 PTB,可编程交易块怎么理解?
  • 别再让单例坑了你!深入理解Unity中MonoBehaviour单例的销毁时机与内存管理
  • 某汽车品牌自燃事件的危机公关全程
  • 深度解析:CloudBeaver云数据库管理平台架构设计与生产部署实战
  • Honey Select 2终极汉化优化补丁:三步搞定完整游戏体验升级
  • 基于ESP8266与GPS模块的宠物追踪器:物联网全栈开发实践
  • 如何用Unlock-Music免费解锁音乐文件:浏览器端解密完整指南
  • Arduino DS1307 RTC与OLED时钟项目:从I2C通信到时间显示全解析
  • Joy-Con Toolkit:5大核心功能解锁任天堂Switch手柄的隐藏潜力
  • 从Macvlan到Ipvlan:在K8s和Docker里选对虚拟网络模式的避坑指南
  • OData V4.01 完整查询语法速查表
  • 15|测试用例与代码映射:平台怎么知道哪个用例测过哪段代码?
  • ZYNQ-7020软硬协同电磁超声测厚方案:含伪随机编码激励、匹配滤波压缩与微伏级回波时延提取
  • 告别盲操作!手把手教你用AutoSar Dcm配置UDS 0x31例程控制(附RID参数详解)