Files
hms/docs/discussions/2026-05-15-miniprogram-final-audit-five-experts.md
iven 9bd2d4c2e6 docs(mp): 五专家组最终审查报告 — 综合 7.4/10(B)
架构 7.5 + 性能 8.0 + 安全 7.5 + 工程 7.5 + UX 6.5
发现 HIGH×15 + MEDIUM×25
核心问题:隐私政策合规、patientId 架构绕过、测试覆盖不足、触摸反馈缺失
2026-05-15 08:05:47 +08:00

123 lines
6.3 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.
# 小程序架构优化最终审查 — 五专家组汇总
> 日期: 2026-05-15 | 参与者: 架构专家、性能专家、安全专家、工程质量专家、UX 专家
## 背景
小程序历经 3 轮架构重构P1: usePageData 统一 + Store 解耦、P2: request.ts 收编 + AbortSignal、P3: useLongPolling 通用化、P4: 分包策略优化),组织 5 个并行专家组做最终审查,确认遗漏并评估完成度。
## 综合评分
| 专家组 | 评分 | 一句话总结 |
|--------|------|-----------|
| 架构 | 7.5/10 | 骨架扎实,并发/缓存/生命周期/解耦到位,统一性层面有 3 个 HIGH |
| 性能 | 8.0/10 | 基础设施完善(并发控制、缓存去重、长轮询安全),长对话 DOM 是最大瓶颈 |
| 安全 | 7.5/10 | 认证请求层完善,本地存储"声称加密实际明文"是最大合规差距 |
| 工程质量 | 7.5/10 | 架构模式高水准,但测试覆盖严重不足(仅 5/25+ service接口重复 |
| UX | ~6.5/10 | ErrorState 覆盖不足、触摸反馈缺失、表单验证不完整 |
**综合评分: 7.4/10 (B)**
---
## HIGH 级问题15 项,按影响域分组)
### 一、安全合规2 项)
| # | 问题 | 影响 | 建议 |
|---|------|------|------|
| S-1 | secure-storage 实际明文存储,但隐私政策声称"混淆加密存储" | 合规风险(个保法) | 修正隐私政策描述为"HTTPS 加密传输 + 微信沙箱保护" |
| S-2 | `current_patient`/`edit_patient` 含 PII 明文 Storage 传递 | 数据泄漏 | 改为 URL 传 id + API 获取详情 |
### 二、架构统一性3 项)
| # | 问题 | 影响 | 建议 |
|---|------|------|------|
| A-1 | 8 页面直接 `Taro.getStorageSync('current_patient_id')` 绕过架构层 | 患者切换时数据串号 | 新建 `utils/patient.ts` 统一获取,导出 `getCachedPatientId()` |
| A-2 | `usePageData``loading` 返回值是 ref 快照而非响应式 | 消费者 loading 永远是 false | 改为 `useState` 同步或移除 |
| A-3 | `health.ts` 模块级 `let refreshingToday` 不在 store 管理范围 | resetAllStores 无法重置 + 测试泄漏 | 移入 store state 或提供 resetForTesting |
### 三、性能1 项)
| # | 问题 | 影响 | 建议 |
|---|------|------|------|
| P-1 | 咨询详情页 200 条消息无虚拟化(长轮询持续追加 DOM | 低端机滚动卡顿 | 降低 MAX_RENDER_MESSAGES 到 50-100 + 增量加载 |
### 四、工程质量5 项)
| # | 问题 | 影响 | 建议 |
|---|------|------|------|
| Q-1 | 10 个核心业务 service 无测试alert/followup/dialysis/ai 等) | 重构/回归无保障 | 优先补齐涉及患者安全的 alert/followup/dialysis |
| Q-2 | doctor/ 8 个 service 无测试 | 同上 | 批量补齐 |
| Q-3 | `doctor/appointment.ts` 使用 `data: any[]` | 类型安全丧失 | 从患者端导入 Appointment 类型 |
| Q-4 | `daily-monitoring` 489 行超 400 行阈值 | 可维护性 | 提取常量/工具函数到同目录文件 |
| Q-5 | 4 组接口重复定义ConsultationSession/FollowUpTask/Alert/PaginatedData | DRY 违反 | `services/types.ts` 共享基础接口 + extends |
### 五、UX4 项)
| # | 问题 | 影响 | 建议 |
|---|------|------|------|
| U-1 | ErrorState 仅 2/59 页面使用,错误时可能空白无操作入口 | 用户被困 | 所有 usePageData 页面统一接入 ErrorState |
| U-2 | 所有表单 Input 缺少 maxlength | 无输入长度保护 | 全量表单添加 maxlength |
| U-3 | 零处 hover-class触摸无反馈中老年用户最敏感 | 交互体验差 | 批量添加 hover-class |
| U-4 | 零个 aria-* 或 role 属性 | 屏幕阅读器不可用 | 核心页面添加 ARIA 标注 |
---
## MEDIUM 级问题25 项,精选 Top 10
| # | 域 | 问题 | 建议 |
|---|-----|------|------|
| M-1 | 安全 | auth.ts restore 数据损坏时完全静默 | catch 中清除损坏数据 + 引导重新登录 |
| M-2 | 安全 | console.error/warn 生产构建未移除 | pure_funcs 添加 console.error/warn |
| M-3 | 安全 | analytics 属性无 PII 过滤 | 添加白名单 + 队列过期 |
| M-4 | 安全 | clearCache 后未刷新 request.ts 内存缓存 | 调用 invalidateHeadersCache() |
| M-5 | 工程 | Store 层 4 个 store 零测试 | 补齐 auth/health store 测试 |
| M-6 | 工程 | 8 个自定义 Hook 零测试 | 补齐 useSafeTimeout/useLongPolling 测试 |
| M-7 | 工程 | @/ 别名与相对路径混用 148 处 | codemod 统一为 @/ |
| M-8 | 工程 | 患者端/医生端 4 对 API 函数完全重复 | 基础查询函数共享 |
| M-9 | 架构 | usePagination 未与 usePageData 集成,两套分页模式 | 统一为一套 |
| M-10 | 性能 | useHealthData fetchData 未 useCallback | 显式声明依赖 |
---
## 已验证生效的优化(确认清单)
以下优化经专家组确认在代码中正确实现:
- ✅ 全局并发限制 MAX_CONCURRENT=8 — request.ts
- ✅ GET 请求去重+缓存 ResponseCache — request.ts
- ✅ 长轮询 generation counter — useLongPolling.ts
- ✅ loadingRef 防重入 — usePageData.ts + 所有列表页
- ✅ useSafeTimeout 页面隐藏自动清理 — hooks/useSafeTimeout.ts
- ✅ Store selector 精确订阅 — 全部页面使用 `(s) => s.xxx`
- ✅ Store 变更检测避免无意义 setState — auth.ts
- ✅ 内存缓存避免重复 JSON.parse — auth.ts
- ✅ Analytics 定时器 useDidShow/Hide 控制 — app.tsx
- ✅ 分包优化10→8 个,主包 13→12 页) — app.config.ts
- ✅ React.memo 组件 — TrendChart 等
- ✅ AbortSignal 请求取消 — request.ts
- ✅ resetForTesting 测试隔离 — request.ts
- ✅ Store 解耦 resetAllStores — stores/index.ts
---
## 结论 / 行动建议
### 立即行动(本迭代)
1. **修正隐私政策描述**S-1— 文案修改5 分钟
2. **usePageData loading 改为响应式**A-2— 1 文件修改
3. **getCachedPatientId 统一导出**A-1— request.ts + 8 页面替换
### 短期行动(下一迭代)
4. 补齐 alert/followup/dialysis service 测试Q-1
5. 抽取 services/types.ts 共享接口Q-5
6. 全量表单 maxlengthU-2+ ErrorState 接入U-1
7. batch 添加 hover-classU-3
### 中期行动(技术债清理)
8. codemod 统一 import 路径为 @/M-7
9. 患者端/医生端 service 函数去重M-8
10. edit_patient 改为 API 获取S-2
11. daily-monitoring 拆分Q-4