Files
hms/docs/discussions/2026-05-20-v1-release-strategy-brainstorming.md

422 lines
21 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.
# V1 发布策略多专家组辩论 — 会议记录
> 日期: 2026-05-20 | 参与者: 安全工程师、SRE、产品经理、架构师、测试工程师、前端专家
> 主持人: Claude (AI 顾问) | 基于: 六维度全面均衡分析 (6.8/10 B)
---
## 背景
系统经过 862 次提交、17 个 crate、652 个 Rust 源文件、307 个前端文件的开发V1 全面端到端测试已完成。原 2 CRITICAL + 7 HIGH 全部解决,综合评分 6.2/10 B-,当前在 `feat/media-library-banner` 分支。
六维度分析显示:架构 8.5、安全 7.5、前端 7.2、产品 8.0 表现良好;测试 5.5、DevOps 3.8 是短板。本次会议目标:确定 V1 发布的 GO/NO-GO 标准和行动清单。
---
## 议题 1: V1 发布范围 — 大而稳 vs 小而快
### 安全工程师(正方:先修完安全问题再发布)
> "医疗数据泄漏的法律后果是毁灭性的。我们目前的隐患:
> 1. Analytics 端点缺权限校验 — 任何认证用户都能访问全租户分析数据
> 2. 缺 HSTS 和 CSP — 中间人攻击可以注入恶意脚本
> 3. 日志中 PII 脱敏不完整 — 开发日志可能泄漏患者姓名、身份证号
> 4. 没有生产环境 TLS — 所有数据在网络上明文传输
>
> 这些问题修起来都不难1-2 天总量),但不修就发布等于知道有洞还跳。医疗行业合规要求我们至少做到传输加密和访问控制。"
### SRE正方先建立运维基础设施再发布
> "我同意安全问题要修,但我想强调运维视角:没有监控、没有告警、没有备份策略就上线,等于盲飞。
>
> 具体风险:
> 1. 数据库没有加密备份和异地副本 — 医疗法规要求 7 年数据保留,磁盘坏了数据就没了
> 2. 没有 Prometheus/Grafana — 我们不知道 API 响应时间、错误率、资源使用情况
> 3. 迁移在启动时自动执行 — 156 个迁移,任何一个失败就起不来
> 4. 没有 CD 流水线 — 手动部署意味着每次发布都是冒险
>
> 建议监控和备份可以跟安全修复并行做3-5 天搞定。"
### 产品经理(反方:核心功能验证通过即可发布)
> "我理解安全和运维的顾虑,但请注意几个事实:
>
> 1. **发布不等于面向公众开放** — V1 是给首批试点客户1-2 家体检中心)使用的,内网环境部署
> 2. **核心功能已经过充分验证** — E2E 覆盖 157 个端点5 角色测试通过率 86.5%,小程序多角色 96.2%
> 3. **冻结 6 个模块不影响核心流程** — 患者管理、预约、随访、咨询、健康数据这 5 个核心流程都是完整的
> 4. **竞争对手不会等我们** — 每 delay 一周,就可能失去试点窗口
>
> 我的提案:把安全问题分两类 — 阻塞性的Analytics 权限、TLSV1 必修非阻塞性的日志脱敏、CSP可以 V1.1。运维同理 — 备份策略必修CD 可以 V1.1。"
### 架构师(关注架构债务)
> "从架构角度,我比较关心两个问题:
>
> 1. **事件消费者幂等性不统一** — 如果同一个 `patient.created` 事件被投递两次,有的消费者会创建重复数据。这在启动时 outbox replay 的场景下一定会发生。但好消息是:我们有 dead-letter 存储,而且启动 replay 频率很低。
>
> 2. **缓存层薄弱** — 没有 Redis每次请求都打数据库。在试点阶段几十个用户不是问题但要注意。
>
> 我的判断:架构层面没有阻塞性问题。事件幂等性是 P1 级别V1 阶段靠 dead-letter 兜底即可。缓存层 V1.1 再加。"
### 辩论交锋
**安全工程师**: "内网环境不代表没有风险。内部员工越权访问分析数据、开发人员电脑被入侵通过日志获取 PII — 这些都是实际威胁。"
**产品经理**: "我同意 Analytics 权限必须修1 小时的工作量不应该成为阻塞项。但 TLS 在内网部署场景下实际上是反向代理层Nginx做的不是应用层的责任。"
**SRE**: "Nginx 做 TLS 终止是标准做法,但我需要确保我们提供配置模板和文档。另外,备份策略真的不能拖 — 医疗数据的合规要求不是'建议'。"
**架构师**: "折中方案 — V1 发布附带一份'部署检查清单',列出 TLS、备份等运维要求。应用层修 Analytics 权限和安全头HSTS/CSP基础设施层由部署文档覆盖。"
### 议题 1 共识
**结论:有条件 GO — "核心安全必修,基础设施文档化"**
| 项目 | 决定 | 理由 |
|------|------|------|
| Analytics 权限校验 | V1 必修 | 1 小时工作量,风险高 |
| HSTS + CSP 安全头 | V1 必修 | 2 小时工作量,标准化做法 |
| TLS 终止 | V1 通过部署文档覆盖 | 内网由 Nginx 处理,不是应用层责任 |
| 日志 PII 脱敏 | V1.1 | 不阻塞试点,但 V1.1 必修 |
| 备份加密+异地 | V1 必修 | 医疗合规硬要求 |
| Prometheus+Grafana | V1.1 | 试点阶段可人工巡检V1.1 正式监控 |
| CD 流水线 | V1.1 | 手动部署在试点阶段可接受 |
| 事件幂等性 | V1.1 | Dead-letter 兜底,非阻塞 |
| 缓存层 | V1.1+ | 试点用户量不需要 |
---
## 议题 2: 测试策略 — 广度优先 vs 深度优先
### 测试工程师正方Handler 测试优先)
> "当前测试数据943 个后端测试,但 Handler 层 0% 覆盖。这意味着:
>
> 1. API 参数校验完全没有自动化验证
> 2. 错误响应格式、HTTP 状态码没有测试
> 3. 权限守卫是否生效没有测试
> 4. 分页、排序、过滤逻辑没有测试
>
> 我们有 47 个 Handler如果每个核心 Handler 只测 CRUD + 权限校验5 个用例),就是 235 个测试。这比小程序测试(影响面小)优先级更高。
>
> 但我也要诚实2.5 天写 235 个测试不现实。务实方案是只覆盖高风险 Handler — health 模块的核心实体(患者、预约、咨询、健康数据)约 10 个 Handler50 个测试。"
### 安全工程师(正方:安全中间件测试优先)
> "我不同意。安全中间件 0% 测试覆盖意味着:
>
> 1. 多租户隔离可能被绕过 — 我们没有测试跨租户访问
> 2. 权限守卫可能失效 — 我们没有测试 require_permission 的拒绝路径
> 3. JWT 过期/刷新逻辑没有测试 — 生产环境 token 异常无法预测
>
> 安全中间件是所有 Handler 的前提。如果中间件有漏洞,所有 Handler 的权限检查都形同虚设。而且中间件测试数量少(约 15-20 个1.5 天足够。"
### 前端专家(正方:小程序测试优先)
> "小程序 60 个页面0 个单元测试。而且小程序已经经历了至少 15 个 bug fix
>
> - 长轮询 CPU 飙升
> - 并发请求阻塞 30s
> - 页栈超 10 层导航失败
> - 登录卡死
> - DevTools 卡死
>
> 这些都是运行时才发现的问题。如果有单元测试,至少并发控制和导航逻辑可以在 CI 中捕获。小程序是患者直接使用的入口,它的稳定性直接影响用户信任。
>
> 但我承认60 个页面全部写测试不现实。核心层测试request.ts、navigate.ts、auth 相关)约 20-30 个测试2 天可以完成。"
### 产品经理(按用户影响排序)
> "三方都有道理但资源有限V1 只有 5-7 天),我们需要按实际影响排序:
>
> 1. **安全中间件测试** — 影响:全系统。如果多租户隔离有问题,所有数据都暴露。优先级最高。
> 2. **核心 Handler 测试** — 影响:核心业务流程。患者 CRUD + 预约 CRUD 是最高频操作。
> 3. **小程序核心层测试** — 影响:患者端用户体验。但小程序已经有 96.2% 的角色测试通过率。
>
> 测试投入顺序:中间件(1.5d) > 核心Handler(1.5d,精简版) > 小程序核心(1d最精简版)。"
### 辩论交锋
**测试工程师**: "产品经理的排序合理,但我想补充一点 — Handler 测试不只要测 happy path还要测 unhappy path。权限拒绝、参数校验失败、并发冲突 — 这些 unhappy path 是 bug 高发区。"
**安全工程师**: "同意。中间件测试也以 unhappy path 为主 — 跨租户访问、过期 token、无权限访问。这些才是安全测试的价值。"
**前端专家**: "小程序测试我接受精简到 1 天。request.ts 的并发控制和重试逻辑是最高优先 — 这是我们修了 3 次 bug 的地方。"
### 议题 2 共识
**结论:分层递进 — "中间件 → 核心Handler → 小程序核心"**
| 层级 | 测试范围 | 预估时间 | 优先级 |
|------|---------|---------|--------|
| 安全中间件 | 多租户隔离、权限拒绝、JWT 异常(~15 个 unhappy path 测试) | 1.5 天 | V1 必须 |
| 核心 Handler | 患者CRUD + 预约CRUD + 咨询CRUD + 健康数据查询(~40 个测试happy+unhappy | 1.5 天 | V1 必须 |
| 小程序核心层 | request.ts 并发控制 + navigate.ts 安全导航 + auth 存储管理(~15 个测试) | 1 天 | V1.1 |
| E2E CI 集成 | 现有 17 个 E2E spec 接入 CI | 0.5 天 | V1.1 |
---
## 议题 3: DevOps 优先级 — 备份 vs 监控 vs CD
### SRE正方备份加密优先
> "医疗数据备份不是'nice to have',是法律要求。《医疗机构管理条例》和等保三级都要求:
>
> 1. 数据至少 3 份副本(生产 + 本地备份 + 异地备份)
> 2. 备份必须加密存储
> 3. 定期恢复演练
>
> 当前状态pg_dump 手动执行,无加密,无异地。磁盘坏了 = 数据没了。
>
> 工作量:写一个备份脚本 + cron job + 加密配置3 天足够。这是 V1 的硬门槛。"
### 安全工程师正方TLS 终止优先)
> "在议题 1 中我们达成了 TLS 由 Nginx 处理的共识,但我要强调 — 如果部署时没人配置 TLS所有数据在网络上是明文的。
>
> 我同意这不是应用层的代码问题,但 V1 发布包必须包含:
> 1. Nginx TLS 配置模板
> 2. 自签名证书生成脚本(开发/测试用)
> 3. 部署文档中明确标注 TLS 为必配项
>
> 这不是代码工作是文档工作。1-2 小时。"
### 架构师(正方:监控优先)
> "我理解备份和 TLS 的重要性,但从运维实践看,没有监控的系统上线后:
>
> 1. 你不知道它慢 — API 响应从 50ms 退化到 500ms用户先感受到你才知道
> 2. 你不知道它挂了 — 直到用户投诉
> 3. 你不知道资源耗尽 — 直到 OOM 崩溃
>
> Prometheus + Grafana 的最小配置 3 天可以搞定。但考虑到试点阶段(内网、几十用户、专人值守),监控可以降级到 '人工巡检 + 日志告警'。
>
> 折中V1 先用简单的 health check + 日志级别告警V1.1 上 Prometheus。"
### 产品经理(用户体验视角)
> "从用户(体检中心)角度看,他们最关心的是:
> 1. 系统能不能用 — 功能完整性(已满足)
> 2. 数据丢不丢 — 备份(合规+信任)
> 3. 出了问题能不能恢复 — 迁移回滚策略
>
> 监控是'我们的问题',不是'用户的问题'。备份是'用户的问题'。
>
> 我的排序:备份(3d) > 部署文档+TLS模板(0.5d) > 迁移策略(1d) > 监控(V1.1)。"
### 议题 3 共识
**结论:备份+部署文档必修,监控 V1.1**
| 项目 | 决定 | 工作量 | 理由 |
|------|------|--------|------|
| 数据库加密备份+异地脚本 | V1 必修 | 3 天 | 医疗合规硬要求 |
| Nginx TLS 配置模板 | V1 必修 | 0.5 天 | 部署必需 |
| 生产迁移策略(回滚方案) | V1 必修 | 1 天 | 防止迁移失败导致不可恢复 |
| Prometheus+Grafana | V1.1 | 3 天 | 试点阶段人工巡检替代 |
| CD 流水线 | V1.1 | 2 天 | 手动部署试点阶段可接受 |
---
## 议题 4: 技术债务取舍 — 哪些可以接受
### 架构师(事件消费者幂等性)
> "当前 12 个消费者模块中,部分消费者(约 4-5 个)没有幂等检查。风险场景:
>
> 1. Outbox replay 时重复投递 — 概率:每次重启都会发生
> 2. 消费者处理成功但确认失败 — 概率:网络抖动时
>
> 影响评估:
> - 重复创建通知消息 → 用户收到重复通知LOW
> - 重复创建随访任务 → 可能创建重复任务MEDIUM
> - 重复更新统计数据 → 幂等(无影响)
>
> V1 结论:可接受。理由:(1) dead-letter 会捕获异常 (2) 试点阶段重启频率低 (3) 最坏情况是重复通知不是数据损坏。V1.1 统一修复。"
### 前端专家i18n 硬编码中文)
> "当前前端所有文案都硬编码中文i18n key 一个没用。但现实是:
>
> 1. 目标用户 100% 中文 — 体检中心在中国
> 2. 短期内没有国际化需求
> 3. i18n 改造工作量巨大 — 307 个 TS/TSX 文件
>
> V1 完全可以接受硬编码。但有两个前提:
> 1. 不能用中文字符串做逻辑判断(比如 `if (status === '已完成')`
> 2. V1.1 要启动 i18n 改造,至少覆盖公共组件和导航
>
> 结论V1 接受V1.1 启动渐进式改造。"
### 测试工程师CI 不覆盖 E2E
> "17 个 E2E spec但 CI 不跑。这意味着:
>
> 1. 每次 push 只跑单元测试
> 2. 回归问题只能在手动测试时发现
> 3. 小程序 E2E 依赖 MCP 连接,更难自动化
>
> 但接入 CI 有实际困难:
> - E2E 需要 PostgreSQL 实例 — 可以用 GitHub Actions service container
> - 需要 Rust 编译 — 编译时间 10-15 分钟
> - 小程序 E2E 需要微信开发者工具 — 无法在 CI 中运行
>
> V1 折中:只接 Web E2E13 个 spec跑在 CI 上。小程序 E2E 继续手动。V1.1 再优化。
>
> 等等,我重新考虑 — V1 时间紧张CI 接入可以 V1.1。试点阶段开发人员手动跑 E2E 是可控的。"
### SRE迁移自动执行
> "156 个迁移在启动时自动执行。风险:
>
> 1. 迁移失败 = 服务启动失败
> 2. 迁移冲突 = 数据库锁死
> 3. 大表迁移 = 启动耗时数分钟
>
> 但实际上:
> 1. 所有迁移都经过本地验证 — cargo test 覆盖
> 2. 启动时只执行新迁移 — 已执行的会跳过
> 3. 试点阶段数据量小 — 迁移速度不是问题
>
> V1 可接受。但 V1.1 需要改进:
> 1. 生产环境迁移改为手动执行 + pre-check
> 2. 添加迁移回滚策略"
### 议题 4 共识
**结论V1 技术债务全面可接受,但需文档化风险**
| 债务 | V1 决定 | V1.1 计划 | 风险等级 |
|------|---------|----------|---------|
| 事件消费者非幂等 | 接受dead-letter 兜底 | 统一幂等修复 | LOW |
| i18n 硬编码中文 | 接受,目标用户全中文 | 渐进式改造,公共组件优先 | NONE |
| CI 不覆盖 E2E | 接受,手动 E2E | Web E2E 接入 CI | MEDIUM |
| 迁移自动执行 | 接受,试点可控 | 手动迁移+pre-check+回滚 | LOW |
| 缓存层缺失 | 接受,试点用户量小 | Redis 热点查询缓存 | LOW |
| main.rs 未拆分 | 接受 | 模块化重构 | NONE |
---
## 修订后的 V1 行动清单
> 基于 4 个议题的辩论共识V1 工作量总计约 **8.5 天**。
### P0 — V1 发布阻塞项(必修,约 4 天)
| # | 项目 | 工作量 | 负责 | 验收标准 |
|---|------|--------|------|---------|
| V1-1 | Analytics 端点权限校验 | 1h | 安全工程师 | 无权限返回 403有权限返回数据 |
| V1-2 | HSTS + CSP + X-Frame-Options 安全头 | 2h | 安全工程师 | 响应头包含安全策略 |
| V1-3 | 数据库加密备份脚本 + 异地同步 cron | 3d | SRE | 每日自动备份 + AES-256 加密 + 异地 rsync |
| V1-4 | Nginx TLS 终止配置模板 + 部署文档 | 0.5d | SRE | 提供可用的 Nginx 配置 + 自签名证书脚本 |
| V1-5 | 生产迁移策略pre-check + 回滚方案) | 1d | SRE + 架构师 | 迁移前检查 + 失败回滚步骤文档化 |
### P1 — V1 发布质量提升(强烈建议,约 3 天)
| # | 项目 | 工作量 | 负责 | 验收标准 |
|---|------|--------|------|---------|
| V1-6 | 安全中间件 unhappy path 测试 | 1.5d | 测试工程师 + 安全工程师 | ~15 个测试多租户隔离、权限拒绝、JWT 异常 |
| V1-7 | 核心 Handler 测试(患者/预约/咨询/健康数据) | 1.5d | 测试工程师 | ~40 个测试CRUD happy + unhappy path |
### V1 可选优化(时间允许时做)
| # | 项目 | 工作量 | 负责 |
|---|------|--------|------|
| V1-8 | 部署检查清单文档(安全+运维+迁移) | 0.5d | SRE |
| V1-9 | 健康检查端点增强(数据库连接+迁移状态) | 0.5d | SRE |
---
## V1.1 行动清单(发布后 2 周内)
| # | 项目 | 工作量 | 优先级 |
|---|------|--------|--------|
| V1.1-1 | Prometheus + Grafana 最小可观测性 | 3d | P0 |
| V1.1-2 | 小程序核心层单元测试request/navigate/auth | 1d | P0 |
| V1.1-3 | Web E2E 接入 CI | 0.5d | P0 |
| V1.1-4 | 日志 PII 脱敏 | 4h | P0 |
| V1.1-5 | 事件消费者幂等统一修复 | 2d | P1 |
| V1.1-6 | CD 流水线GitHub Actions | 2d | P1 |
| V1.1-7 | i18n 渐进式改造(公共组件+导航) | 3d | P1 |
| V1.1-8 | Redis 热点查询缓存 | 2d | P1 |
| V1.1-9 | main.rs 拆分重构 | 2d | P2 |
| V1.1-10 | OpenAPI 自动生成 TS 类型 | 3d | P2 |
| V1.1-11 | 生产迁移改为手动执行 + pre-check | 1d | P1 |
| V1.1-12 | Handler 测试扩展到全部 47 个 | 2d | P1 |
---
## 最终 GO/NO-GO 判定标准
### GO 条件(全部满足才可发布)
| # | 检查项 | 验证方式 | 负责人 |
|---|--------|---------|--------|
| G1 | `cargo check` 全 workspace 通过 | CI 自动 | 开发 |
| G2 | `cargo test --workspace` 全部通过 | CI 自动 | 开发 |
| G3 | Analytics 端点有权限守卫 | 手动验证:无权限用户返回 403 | 安全工程师 |
| G4 | 安全头 (HSTS/CSP/X-Frame-Options) 存在 | `curl -I` 检查响应头 | 安全工程师 |
| G5 | 数据库备份脚本可运行 | 执行备份脚本,验证加密文件生成 | SRE |
| G6 | Nginx TLS 配置模板可用 | `nginx -t` 验证配置正确 | SRE |
| G7 | 迁移 pre-check 和回滚方案已文档化 | 评审文档 | SRE + 架构师 |
| G8 | 安全中间件 unhappy path 测试通过 | CI 自动(~15 个测试) | 测试工程师 |
| G9 | 核心 Handler 测试通过(患者/预约/咨询/健康数据) | CI 自动(~40 个测试) | 测试工程师 |
| G10 | 浏览器手动验证核心流程患者CRUD + 预约 + 随访) | 手动测试 | 产品经理 |
| G11 | 小程序手动验证核心流程(登录 + 健康数据 + 咨询) | 手动测试 | 产品经理 |
| G12 | 部署文档完整TLS/备份/迁移/检查清单) | 评审文档 | SRE |
### NO-GO 触发条件(任一即阻塞)
| # | 条件 | 理由 |
|---|------|------|
| N1 | 多租户数据隔离被突破 | 安全底线 |
| N2 | 核心业务流程(患者/预约/咨询)无法完成 | 产品底线 |
| N3 | 数据库备份无法执行或无法恢复 | 合规底线 |
| N4 | P0 安全漏洞未修复Analytics 越权) | 安全底线 |
| N5 | 迁移在目标环境执行失败且无回滚方案 | 运维底线 |
### 条件说明
- **GO**: 全部 G1-G12 满足 → V1 可发布到试点环境
- **CONDITIONAL GO**: G1-G7 + G10-G12 满足G8-G9 部分完成 → V1 可发布,但需在 V1.1 首批补全测试
- **NO-GO**: 任一 N1-N5 触发 → 回到开发,修复后重新评估
### 预计时间线
| 阶段 | 时间 | 内容 |
|------|------|------|
| P0 修复 | Day 1-4 | V1-1 到 V1-5安全+运维+迁移) |
| P1 测试 | Day 3-6 | V1-6 到 V1-7与 P0 并行启动) |
| 验收 | Day 7 | G1-G12 全项检查 |
| 发布 | Day 8 | 部署到试点环境 |
| V1.1 启动 | Day 15 | 监控 + 小程序测试 + 日志脱敏 |
---
## 附录:专家组成员与立场总结
| 专家 | 核心立场 | 最大让步 |
|------|---------|---------|
| 安全工程师 | 安全问题必须全部修复才发布 | 日志脱敏和 CSP 可 V1.1,但 Analytics 权限和 TLS 不可妥协 |
| SRE | 备份+监控缺一不可 | 监控可降级为人工巡检,但备份不可妥协 |
| 产品经理 | 核心功能通过即可发布 | 安全硬伤必须修,但非阻塞性问题可推迟 |
| 架构师 | 架构债务可管理即可 | 幂等性和缓存可推迟,但 dead-letter 兜底必须有 |
| 测试工程师 | Handler 测试覆盖是底线 | 可精简到 10 个核心 Handler但中间件测试不可妥协 |
| 前端专家 | 小程序测试是定时炸弹 | 核心层测试可推迟到 V1.1,但需文档化风险 |
---
## 结论
> **最终判定: CONDITIONAL GO**
>
> V1 发布到试点环境是可行的,但需要满足 P0 阻塞项(安全+备份+迁移策略。P1 测试(中间件+核心Handler建议在发布前完成但如果时间紧张可以 CONDITIONAL GO — 在 V1.1 首批补全。
>
> 关键共识:
> 1. 发布不等于公开上线 — 试点环境内网部署,风险可控
> 2. 安全底线不可妥协 — Analytics 权限 + TLS + 备份必须到位
> 3. 测试是信心问题不是功能问题 — 中间件 unhappy path 测试是最低要求
> 4. 运维文档与代码同等重要 — 部署检查清单是 V1 的一部分
>
> 总工作量P0 约 4 天 + P1 约 3 天 = **7 天可达 GO8-9 天可达充分 GO**。