Files
hms/wiki/index.md

165 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HMS 健康管理平台 — 知识库
> **Health Management System (HMS)** — 面向体检中心/医疗机构的综合健康管理平台。从 ERP 底座分叉,继承身份权限/工作流/消息/配置等基础能力,`erp-health` 原生模块承载医疗业务。
## 关键数字
> 最后更新: 2026-05-16 | 数据截止: feat/media-library-banner 分支
| 指标 | 值 |
|------|-----|
| Rust crate | 17 个erp-core + 5 基础业务 + erp-health + erp-ai + erp-dialysis + erp-plugin + 7 插件/原型) |
| Rust 源文件 | **649 个** |
| 数据库表 | 30 基础表 + 49 健康业务表 + 9 AI 表 + 3 媒体库/轮播图表 |
| 数据库迁移 | **146 个**(最新 m20260515_000146 |
| 后端路由 | 260+ 个11 公开 + 14 FHIR + 2 网关 + ~240 受保护) |
| 核心模块 | 5 基础 (auth/config/workflow/message/plugin) + 3 业务 (health + ai + dialysis) |
| erp-health 实体 | **57 个** Entity31 handler / 36 service / 21 DTO189 文件) |
| erp-ai 实体 | 9 个 Entity45 文件4 AI Provider |
| Web 前端 | 332 个 TS/TSX 文件29 活跃路由 + 6 冻结路由52 API 模块) |
| 微信小程序 | Taro 4.2 + React 18163 个 TS/TSX 文件 / 66 页面 / 4 TabBar + 医生端分包统一组件库PageShell/ContentCard/StatusTag/SectionTitle/LoadingCard + SearchSection/CardList/PaginationBar + useListPage Hook |
| 前端单元测试 | 88 个测试文件472 Web 断言 + 39 MP 断言)+ 13 E2E spec124 断言) |
| 后端测试 | **943 个函数**762 同步 + 181 异步79 个文件含内联测试 |
| 事件系统 | 31 事件类型health 模块内)/ 23 幂等消费者 / Outbox + LISTEN/NOTIFY |
| 权限码 | **132 个**health 59 + auth 17 + ai 9 + workflow 8 + dialysis 6 + plugin 2 + config 13 + message 5 + Copilot 5 |
| 生产 unwrap | **24 处**(从 514 降至 24全为安全解包 |
| utoipa 注解 | 88 个文件含注解 |
| Clippy | **全 workspace 0 警告**2026-05-07 清零) |
| 依赖版本 | 全部最新主版本线Rust edition 2024 |
| API 文档 | `http://localhost:3000/api/docs/openapi.json` |
| Git 提交 | **800+ 次** |
| 系统分析评分 | **6.9/10 (B)**六维度全面均衡分析2026-05-11 |
| 审计状态 | V1: 83% → V2: 85%P0 安全修复已完成V2 CRITICAL 全清零 |
| 角色测试 | R01-R05 全角色验证完成86.5% 通过率5 个 BUG 已修复;小程序 MP 多角色 96.2% 通过率 |
| Design Token | 11 级字号(含 `--tk-font-display`+ 12 结构 tokencard/gap/page/tag/touch68 SCSS 文件全面接入,关怀模式 CSS 变量级联自动生效 |
| 长者模式 | 58/58 页面 100% 覆盖 |
| UI 合规审计 | T40: 60 页面全覆盖PASS 24 / PASS_WITH_ISSUES 36 / NEEDS_WORK 0HIGH×2 + MEDIUM×6 + LOW×67 全部修复,评分 95/10066 页面全部迁移到统一组件库 |
| 项目阶段 | **功能完善**(媒体库+轮播图+文章编辑器上线6 模块冻结待解冻) |
## 症状导航
| 症状 | 先查 | 再查 | 常见根因 |
|------|------|------|----------|
| API 返回 403 | 权限码检查 | [[wasm-plugin]] 权限系统 | 权限码不匹配 / 缺少 .list 权限 |
| API 返回 500 无日志 | [[erp-core]] 错误链 | 后端 tracing 输出 | AppError::Internal 静默 |
| 数据库连接失败 | [[infrastructure]] | PostgreSQL 服务状态 | 服务未启动 / 环境变量未设置 |
| 前端 401 刷新时 | [[frontend]] auth store | API client token 刷新 | token 过期未主动刷新 |
| 迁移执行失败 | [[database]] | PostgreSQL 日志 | 表冲突 / 唯一索引 + 软删除 / 缺失迁移文件 |
| 端口被占用 | [[infrastructure]] dev.ps1 | 端口 5174-5189 进程 | 残留 Vite 进程 |
| 预约创建 400 doctor_id is required | [[erp-health]] 预约并发控制 | AppointmentList.tsx | 医生字段为必填(后端 CAS 要求) |
| 预约超额 | [[erp-health]] 排班并发 | appointment CAS 操作 | 并发控制未走原子 CAS |
| 患者创建 422 birth_date trailing input | [[frontend]] 日期序列化 | DatePicker dayjs 对象 | 未格式化为 YYYY-MM-DD 字符串 |
| 跨租户数据泄漏 | [[architecture]] 多租户策略 | [[database]] tenant_id | 查询缺少 tenant_id 过滤 |
| 小程序页面空白 | [[miniprogram]] defineConstants | `process.env` 未替换 | 编译时未注入环境变量 |
| 小程序登录失败 `btoa is not defined` | [[miniprogram]] secure-storage | Web API 不可用 | 使用 `Taro.arrayBufferToBase64` 替代 |
| 微信登录 500 | [[database]] wechat_users 表结构 | Entity 字段与表不匹配 | 补 `created_by/updated_by/version` 列 |
| 迁移文件缺失报错 | [[database]] 迁移注册 | migration/src/lib.rs | 已应用的迁移文件被删除,需创建 stub |
| MCP 连接失败 `split` error | [[miniprogram]] MCP 联调 | project.config.json | 未开启 `automationAudits` |
| MCP mp_screenshot 超时 | [[miniprogram]] MCP 联调 | automator 已知 bug | 用 `page_getElement` 替代截图 |
| MCP 导航后跳回登录页 | [[miniprogram]] MCP 联调 §6.4 | storage 被清空 | 明文 token 写入后立即 reLaunch |
| MCP token 注入后仍 401 | [[miniprogram]] MCP 联调 §6.1 | 用了生产构建 | dev 构建(`NODE_ENV=development`+ 空密钥 |
| MCP App 级命令全部超时 | [[miniprogram]] MCP 联调 §6.2 | 多 DevTools 实例冲突 | `taskkill /F /IM wechatdevtools.exe` 后重开 |
| MCP CLI 报"需要重新登录" | [[miniprogram]] MCP 联调 §6.2 | DevTools 未扫码 | 在 DevTools 中先扫码登录 |
| 积分商城 Tab 页空白 | [[miniprogram]] 待优化 | 未关联患者档案 | 需增加降级 UI 引导建档 |
| MCP 批量审计页面栈溢出 | [[miniprogram]] MCP 联调 §6.6 | `navigateTo` 超 10 层 | 改用 `reLaunch` 逐页测试 |
| 告警管理按钮不显示 | [[frontend]] 权限码拼写 | AlertList.tsx | `health.alert.manage``health.alerts.manage`(缺 s |
| 小程序晚间血压丢失 | [[miniprogram]] 体征录入 | indicator_type 映射 | **已修复:** 新增 `blood_pressure_evening` 类型,录入页+日常监测页+后端+测试全覆盖 |
| 咨询页长轮询 CPU 飙升 | [[miniprogram]] §5 审查 | longPoll delay=0 递归 | **已修复:** 成功路径加 3s 间隔 + 连续失败上限 50 次 |
| 小程序 DevTools 卡死(所有 API ERR_SSL_PROTOCOL_ERROR | [[miniprogram]] request.ts | `process.env.NODE_ENV === 'production'` 时 http→https 自动转换 | **已修复:** 移除 `getHeaders` 中自动 http→https 升级URL 以 `.env` 为唯一来源 |
| 小程序 Tab 切换卡死(并发请求阻塞 30s | [[miniprogram]] request.ts | `getHeaders()``await tryRefreshToken()` 预检查 | **已修复:** 移除 getHeaders 中的同步 Token 刷新预检查,仅依赖 401 重试路径 |
| 小程序患者端登录后卡死Tab 切换频繁卡死) | [[miniprogram]] §5 审查 | 并发请求超微信 10 限制排队 + 长轮询重叠 + 防重入缺失 | **已修复:** 全局并发限制 MAX_CONCURRENT=8 + generation counter 长轮询 + loadingRef 防重入 |
| 小程序咨询页闭会话崩溃pollingRef is not defined | [[miniprogram]] 审计第二轮 | generation counter 重构后 loadData 残留 pollingRef 引用 | **已修复:** 移除 loadData 中 `pollingRef.current = false` 残余行 |
| 小程序深层页面导航失败(页栈超 10 层) | [[miniprogram]] navigate.ts | `navigateTo` 超微信 10 层限制 | **已修复:** 新增 `safeNavigateTo`栈≥9 自动降级为 `redirectTo` |
| 小程序登录卡死getPhoneNumber 无响应) | [[miniprogram]] login 页 | DevTools 中 `openType='getPhoneNumber'` 不弹窗 | **已修复:** dev 模式新增"开发模式快速登录"按钮绕过手机号授权 |
| 轮播图图片 500 | [[erp-health]] banner_handler | 媒体文件不在磁盘上 | 测试数据问题,生产环境不影响 |
| 设备同步内存无限增长 | [[miniprogram]] §5 审查 | BLE 模块单例 + readings 无上限 | **已修复:** useRef 懒初始化 + MAX_LIVE_READINGS=200 |
| 医生端日期选择器不可用 | [[miniprogram]] §5 审查 | 原生 `<input type='date'>` | **已修复:** 替换为 `<Picker mode='date'>` |
| 透析记录列表过滤不准 | [[miniprogram]] §5 审查 | 客户端过滤代替服务端过滤 | **已修复:** 传 status 参数给后端 |
| 告警详情加载失败 | [[miniprogram]] §5 审查 | 列表加载 100 条客户端过滤 | **已修复:** 新增 `getAlert(id)` 单条查询 |
| AI 分析 SSE 无 UI 入口 | [[erp-health]] AI 分析 | 前端未调用 | 4 个 SSE 端点无管理界面触发 |
| AI 分析返回对话式回复 | [[erp-ai]] prompt 模板 | 迁移 000123 | system_prompt 未加非对话指令 / 数据为空 |
| AI 分析结果显示原始 JSON | [[erp-ai]] 缓存回放 | `replay_cached` | 迁移 000123 前的嵌套 JSON bug前端 `extractPlainText` 兼容 |
| AI 分析输出全空SSE content="" | [[erp-ai]] qwen3 thinking | `strip_think_block` | qwen3 流式 API content 为空,改非流式 + 剥离 think 块 |
| Ollama 内存不足 `memory layout` | [[infrastructure]] Ollama 配置 | `OLLAMA_CONTEXT_LENGTH` | 默认 262144 导致 35GB KV cache设为 4096 |
| Ollama 暴露到局域网 | [[infrastructure]] Ollama 安全 | `OLLAMA_HOST` | 默认 `0.0.0.0`,必须设 `127.0.0.1` |
| AI 趋势/报告分析 500 模板渲染失败 | [[erp-ai]] Handlebars 模板 | `anomalies.length` | `.length` 不是有效 Handlebars 语法,改为 `{{#if anomalies}}` |
| AI 分析 400 缺少数据 | 后端预校验 | handler 层 | 化验报告 items 为空 / 趋势数据 metrics 为空 |
| 患者创建空名称成功 | [[erp-health]] patient_handler | `name.trim().is_empty()` | **已修复:** 后端添加空名称校验返回 Validation 错误 |
| 仪表盘统计 500 | [[erp-health]] stats_handler | 单个查询异常导致整接口崩溃 | **已修复:** 容错处理,单个查询失败返回零值 |
| FHIR 端点全部 404 | [[erp-server]] main.rs | 路由注册在 `/fhir``/api/v1/fhir` | **已修复:** 移到 `/api/v1/fhir` |
| 冻结模块 API 可绕过 | [[erp-server]] frozen_module | 后端无拦截中间件 | **已修复:** 新增 `frozen_module_middleware` |
| 积分端点 403 权限码错 | [[erp-health]] points_handler | 患者端用了 `health.health-data.list` | **已修复:** 改为 `health.points.list` |
| MCP 审计大量 LOGIN_REDIRECT | [[miniprogram]] §6.8 审计脚本 | 测试用户密码配置错误 | **已修复:** 所有测试用户密码均为 `Admin@2026`(不是 `Test@2026` |
| 小程序访客轮播图不显示 | [[miniprogram]] 访客首页 | `TARO_APP_DEFAULT_TENANT_ID` 未配置 | **已修复:** `.env` 添加默认 tenant_id空字符串时跳过 API 调用 |
| 小程序轮播图图片 404 | [[erp-health]] 公开端点 | Axum 路由参数 `:id``{id}` 语法变更 + URL 拼接缺失 `/api/v1` | **已修复:** 路由改用 `{banner_id}`,新增 `/public/banner-image/{id}` 图片服务端点 |
| 前端媒体库图片 401 | [[frontend]] MediaLibrary | `/uploads` 路径需要 JWT 认证 | **已修复:** 新增 `resolveMediaUrl()` 工具函数自动拼接 `?token=`Vite 代理 `/uploads` |
| 后端启动 panic "Path segments must not start with `:`" | [[erp-health]] module.rs | Axum v0.8+ 路由参数语法变更 | 路由定义使用 `{param}` 而非 `:param` |
## 模块导航
### 基础层(继承自 ERP 底座)
- [[erp-core]] — 错误体系 · 事件总线 · 模块 trait · 共享类型
- [[architecture]] — 架构决策 · 设计原则 · 技术选型
### 业务层(继承自 ERP 底座)
- erp-auth — 用户/角色/权限/组织/部门/岗位 · JWT · RBAC · 行级数据权限
- erp-config — 字典/菜单/设置/编号规则/主题/语言
- erp-workflow — BPMN 解析 · Token 驱动 · 任务分配
- erp-message — 消息 CRUD · 模板 · 订阅 · 通知面板
- erp-plugin — WASM 运行时 · 动态表 · 热更新HMS 保留但非主要扩展方式)
### 核心业务层HMS 专属)
- [[erp-health]] — **患者管理 · 健康数据 · 预约排班 · 随访管理 · 咨询管理 · 内容管理 · 媒体库 · 轮播图管理 · 积分商城 · 透析管理 · 线下活动 · 日常监测 · 告警系统**(原生 Rust 模块57 实体 / 31 handler / 36 service已实现
- [[erp-ai]] — **AI 智能分析 · 化验单解读 · 趋势分析 · 报告摘要**(原生 Rust 模块9 实体 / 45 文件 / 4 AI ProviderPhase 1 MVP
### 组装层
- [[erp-server]] — Axum 入口 · AppState · 7+ 模块注册 · 后台任务 · 优雅关闭
### 患者端
- [[miniprogram]] — **微信小程序** · Taro 4.2 · 微信登录 · 手机绑定 · 健康数据查看
### 基础设施
- [[infrastructure]] — 连接信息 · 环境变量 · 一键启动 (**单一真相源**)
- [[database]] — SeaORM 迁移 · 多租户表结构145 迁移)
- [[frontend]] — React 19 SPA · 健康管理页面29 活跃路由 + 6 冻结 + 工作台组件)
- [[testing]] — 验证清单 · 测试分布 · 性能基准
## 核心架构问答
**为什么 erp-health 用原生模块而非 WASM 插件?** 医疗业务需要 18 强类型实体、自定义 API趋势分析/统计报表)、文件上传(化验单/体检报告)、未来 AI 集成,超出 WASM 插件能力范围。详见 [[erp-health]]。
**模块间如何通信?** [[erp-core]] EventBus 发布/订阅 DomainEvent。erp-health 发布 `patient.created``appointment.confirmed` 等事件,订阅 `workflow.task.completed` 等。详见 [[architecture]]。
**多租户怎么隔离?** 共享数据库 + `tenant_id` 列过滤,中间件从 JWT 注入。详见 [[database]] [[architecture]]。
**患者/医护与 erp-auth 的关系?** 账号走 `users`erp-health 通过 `user_id` 外键关联扩展字段(科室、职称、档案等)。患者可先建档后绑定账号。
## 文档索引
| 类型 | 位置 |
|------|------|
| 健康模块设计规格 | `docs/superpowers/specs/2026-04-23-health-management-module-design.md`(已归档到 `archive/superpowers-completed/` |
| AI 模块设计规格 | `docs/superpowers/specs/2026-04-25-erp-ai-module-design.md` |
| 内容管理设计规格 | `docs/superpowers/specs/2026-04-26-content-management-design.md` |
| 媒体库+轮播图设计规格 | `docs/superpowers/specs/2026-05-10-media-library-banner-design.md` |
| Copilot 基因化设计 | `docs/superpowers/specs/2026-05-11-copilot-gene-design.md` |
| 六维度全面均衡分析 | `docs/superpowers/specs/2026-05-11-system-comprehensive-analysis-design.md`6.9/10 B六维度评估 |
| PII 加密扩展规格 | `docs/superpowers/specs/2026-04-26-pii-encryption-expansion-design.md` |
| 设计规格(活跃) | `docs/superpowers/specs/` (32 份) |
| 实施计划(活跃) | `docs/superpowers/plans/` (30 份) |
| UI/UX 重构设计规格 | `docs/superpowers/specs/2026-04-28-ui-ux-overhaul-design.md` |
| UI/UX 重构实施计划 | `docs/superpowers/plans/2026-04-28-ui-ux-overhaul-plan.md` |
| 全系统审计报告V1 | `docs/archive/audits-v1/08-audit-report-2026-04-30.md`(已归档) |
| 全系统审计报告V2 | `docs/audits/v2/13-final-report.md`85% 总体完成度P0 安全修复已完成) |
| 讨论记录 | `docs/discussions/` (41 份) |
| 事件注册表 | `docs/event-registry.md` |
| 角色测试计划(全量) | `docs/qa/role-test-plans/` (R01-R05) |
| 角色测试结果 | `docs/qa/role-test-results/` (R01 100% / R02 100% / R03 90.9% / R04 90.0% / R05 72.7% → 修复后待复测) |
| 协作规则 | `CLAUDE.md` |
| 插件制作指南 | `.claude/skills/plugin-development/SKILL.md` |
| **归档** | |
| 早期 CRM/插件设计 | `docs/archive/superpowers-early/` (13 份4月13-20日早期迭代) |
| 已完成设计/计划 | `docs/archive/superpowers-completed/` (28 份,已实施完成) |
| V1 审计报告 | `docs/archive/audits-v1/` (13 份,已被 V2 取代) |
| 早期讨论/测试报告 | `docs/archive/discussions-early/` + `docs/archive/test-reports-early/` |