From 9bd2d4c2e688e93abc48d228f0fd3a136eb37678 Mon Sep 17 00:00:00 2001 From: iven Date: Fri, 15 May 2026 08:05:47 +0800 Subject: [PATCH] =?UTF-8?q?docs(mp):=20=E4=BA=94=E4=B8=93=E5=AE=B6?= =?UTF-8?q?=E7=BB=84=E6=9C=80=E7=BB=88=E5=AE=A1=E6=9F=A5=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=20=E2=80=94=20=E7=BB=BC=E5=90=88=207.4/10(B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 架构 7.5 + 性能 8.0 + 安全 7.5 + 工程 7.5 + UX 6.5 发现 HIGH×15 + MEDIUM×25 核心问题:隐私政策合规、patientId 架构绕过、测试覆盖不足、触摸反馈缺失 --- ...15-miniprogram-final-audit-five-experts.md | 122 ++++++++++++++++++ wiki/miniprogram.md | 2 +- 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 docs/discussions/2026-05-15-miniprogram-final-audit-five-experts.md diff --git a/docs/discussions/2026-05-15-miniprogram-final-audit-five-experts.md b/docs/discussions/2026-05-15-miniprogram-final-audit-five-experts.md new file mode 100644 index 0000000..4ac69fe --- /dev/null +++ b/docs/discussions/2026-05-15-miniprogram-final-audit-five-experts.md @@ -0,0 +1,122 @@ +# 小程序架构优化最终审查 — 五专家组汇总 + +> 日期: 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 | + +### 五、UX(4 项) + +| # | 问题 | 影响 | 建议 | +|---|------|------|------| +| 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. 全量表单 maxlength(U-2)+ ErrorState 接入(U-1) +7. batch 添加 hover-class(U-3) + +### 中期行动(技术债清理) +8. codemod 统一 import 路径为 @/(M-7) +9. 患者端/医生端 service 函数去重(M-8) +10. edit_patient 改为 API 获取(S-2) +11. daily-monitoring 拆分(Q-4) diff --git a/wiki/miniprogram.md b/wiki/miniprogram.md index 841e804..03ba522 100644 --- a/wiki/miniprogram.md +++ b/wiki/miniprogram.md @@ -907,7 +907,7 @@ node scripts/audit-pages.mjs --role doctor --batch-size 8 | 日期 | 变更 | |------|------| -| 2026-05-15 | **架构重构 P4:分包策略优化**:合并 4 个单页分包(report→pkg-profile/reports、followup→pkg-profile/followups、events→pkg-profile/events、device-sync→pkg-health);consultation/detail 移出主包到 pkg-consultation 分包;doctor 18 页拆分为 pkg-doctor-core(8 页:工作台+患者+咨询+随访)+ pkg-doctor-clinical(10 页:透析+处方+报告+告警);分包 10→8 个,主包页面 13→12 | +| 2026-05-15 | **五专家组最终审查**:架构 7.5 + 性能 8.0 + 安全 7.5 + 工程 7.5 + UX 6.5 = 综合 7.4/10(B);发现 HIGH×15 + MEDIUM×25;核心问题:隐私政策与实际不一致、8 页面绕过 patientId 架构、测试覆盖不足(10 service + 4 store + 8 hook 零测试)、触摸反馈缺失;详细报告见 `docs/discussions/2026-05-15-miniprogram-final-audit-five-experts.md` | | 2026-05-15 | **架构重构 P3:长轮询通用化 useLongPolling**:抽取 `useLongPolling` hook(generation counter + useDidShow/Hide 可见性 + 失败退避 + enabled 守卫);患者端 + 医生端 consultation/detail 接入,删除 ~80 行重复代码;架构建议 #2 全部完成 ✅ | | 2026-05-15 | **架构重构 P2:request.ts 模块级状态收编 + AbortSignal + Analytics 受控**:提取 `ConcurrencyLimiter` 类(并发限制)、`ResponseCache` 类(缓存+去重+patientId 绑定);新增 `resetForTesting()` 测试隔离函数;`api.get/post/put/delete` 支持 `AbortSignal` 请求取消;app.tsx Analytics 定时器改为 `useDidShow`/`useDidHide` 控制后台暂停;构建通过 + 测试 74/75 | | 2026-05-15 | **患者端登录后卡死深度审查(3 专家组)**:根因 — 全局并发请求超微信 10 限制排队阻塞;端点可达性验证 33/33 全部存在;Tab 切换请求链路分析(最坏 13 并发);修复 HIGH×3(doRefresh 状态清理 + 401 跳转登录页 + 全局并发限制 MAX_CONCURRENT=8)+ MEDIUM×3(长轮询 generation counter + 首页/健康页 loadingRef 防重入 + refreshToday 去重) |