Files
ruoyi-vue-pro/docs/education/pilot-acceptance-runbook.md

7.7 KiB
Raw Blame History

Education Pilot 验收与回滚手册

1. 范围

本文覆盖学生核心学习闭环后端的 Pilot 发布、验证、监控和应用回滚。完整 Student Web/H5 源码当前不在本工作区,因此浏览器 E2E、桌面/H5 截图和前端构建验收仍是明确阻塞项,不能以 HTTP 或单元测试替代。

2. Pilot 配置

yudao:
  education:
    enabled: true
    catalog-read-enabled: true
    practice-write-enabled: true
    pilot-tenant-ids: [<pilot-tenant-id>]
    catalog-mode: JAVA_READ
    scalar:
      enabled: false
      owner: <required-only-when-scalar-read>
      exit-date: <yyyy-MM-dd>

要求:

  • pilot-tenant-ids 在 Pilot 环境必须显式配置,不能使用空列表。
  • Pilot 默认以 JAVA_READ 启动,只依赖目标 PostgreSQL不得启动旧 NestJS API、旧 Worker、Supabase 或旧资产扫描服务作为前置条件。
  • 仅在有明确负责人、告警、故障策略和退出日期的兼容窗口内切换 SCALAR_READ。Scalar token 只能通过密钥管理或环境变量注入。
  • 发布前调用管理端 /admin-api/education/capability/admin-api/education/operations/health;后者必须显示 java-read-postgresql=UPscalar-catalog=NOT_SELECTED

3. 发布步骤

  1. 备份 Education 相关表,并记录应用版本与 flyway_schema_history
  2. 由数据库管理员预置彼此独立的 Flyway owner LOGIN role 与 runtime LOGIN role。Flyway role 拥有目标 schemaruntime role 只获得业务表所需权限,且不得拥有、继承所有者角色或写入 education_question_lifecycle_transition_tokeneducation_content_node_lifecycle_transition_tokeneducation_question_collection_lifecycle_transition_tokeneducation_question_collection_membership_token。角色/密码不由 migration 创建。
  3. 显式注入 FLYWAY_USERFLYWAY_PASSWORD(不得回退到 master datasource 账号),使用 Server 配置的 PostgreSQL Flyway 执行 migrate 和 validate检查版本、脚本、checksum、success 以及四张 token 表 owner 均为 Flyway role。
  4. 以 runtime datasource 账号验证四张 token 表均无 INSERT/UPDATE/DELETE/TRUNCATE随后启动应用同角色、继承 owner 或可写授权会导致 Education 启动检查 fail closed。
  5. 先以 catalog-read-enabled=falsepractice-write-enabled=false 部署应用。
  6. 验证 System、Infra、Member 基础 smoke。
  7. 仅对 Pilot 租户开启题库读取,完成 JAVA_READ 只读 smoke并运行 tools/education-target-smoke/java-read-readiness.sh
  8. 对 Pilot 租户开启练习写入,完成会话、答案、交卷、报告、错题和收藏 smoke。
  9. 若部署 Worker 或 Scanner先确认其持续写入 education_operational_component,且 /admin-api/education/operations/healthDOWN 组件和未处理死信。
  10. 观察错误率、延迟和数据库写入后再扩大租户列表。

4. Smoke 清单

基础与身份

  • 非 Pilot 租户访问题库和练习写入被拒绝。
  • Pilot 租户可完成 tenant resolve、Member 登录、refresh、logout 和 Education context。
  • 错误 tenant-id 被租户安全过滤器拒绝。

核心闭环

  • 目录及题目只经 RuoYi API 返回,响应不含答案或解析。
  • 创建练习后刷新可恢复相同会话、题序和已保存答案。
  • 相同答案幂等键重试返回首次结果;旧版本和旧序号被拒绝。
  • 交卷只生成一个报告,交卷后答案不可修改。
  • 错题投影、错题复习和收藏操作仅对当前学生可见。

隔离

  • tenant A / student A 不能读取或修改 tenant A / student B 的记录。
  • tenant A 不能读取或修改 tenant B 的记录,即使资源 ID 被猜中。
  • 对 session、report、wrong question、favorite 分别留存拒绝结果证据。

5. 故障与回滚

JAVA_READ / PostgreSQL 故障

  1. 设置 catalog-read-enabled=false,停止新的目录和题目读取;不得静默切回 Scalar。
  2. 保持 enabled=true,使已有会话、报告、错题和收藏仍可访问。
  3. 检查 /admin-api/education/operations/healthjava-read-postgresql 结果和 Flyway 历史。
  4. 如需冻结新写入,再设置 practice-write-enabled=false
  5. 通过应用回滚或更高版本 Flyway 前滚修复,不执行 flyway clean 或手工回滚 SQL。

Scalar 兼容窗口故障

仅当部署明确选择 SCALAR_READ 时适用:

  1. 设置 catalog-read-enabled=false,停止新的 Scalar 读取。
  2. 保持 enabled=true,使已有会话、报告、错题和收藏仍可访问。
  3. 如需冻结新写入,再设置 practice-write-enabled=false
  4. 验证 Education PostgreSQL 表行数和历史查询均未减少。

练习写入熔断

设置 practice-write-enabled=false 后:

  • 新建练习、保存答案和交卷必须被拒绝;
  • 当前会话恢复、指定会话读取、报告和报告历史仍应可读;
  • 不执行清理、归档或 rollback SQL。

应用回滚

  1. 将应用回滚到上一已验证版本。
  2. 保留所有 Education 表和数据,不执行 flyway clean、手工删除或任何 *-rollback.sql
  3. 若旧版本与新 schema 不兼容,保持功能关闭并通过更高版本 Flyway migration 前滚修复;不得通过删表恢复服务。
  4. 重新验证 Member 登录、System 租户和 Infra 日志功能。

历史 *-rollback.sql 是数据销毁工具且不属于当前交付机制,不是常规应用版本回滚步骤。

6. 可观测性

发布窗口至少观察:

  • /admin-api/education/operations/health 的必需依赖、Worker/Scanner 心跳和 open dead-letter 数;
  • education_operational_componentlast_heartbeat_at、最后成功/失败和 backlog
  • education_dead_letter 仅保留负载指纹与脱敏错误分类,不得保存业务 payload、凭据或个人数据
  • Scalar 兼容模式请求成功率、4xx/5xx/timeout、P95/P99 延迟;
  • 练习创建成功/冲突数;
  • 答案保存成功、幂等重放、版本冲突和旧序号拒绝数;
  • 交卷成功、并发冲突和事务失败数;
  • Pilot 租户拒绝数;
  • JVM、数据库连接池、HTTP 错误率和接口延迟。

Scalar 日志只能记录脱敏路径、tenant ID、上游 request ID、状态、耗时和错误分类不得记录 Authorization、Scalar token、学生答案、正确答案或完整响应体。RuoYi access/error log 中的 trace ID 用于关联入口请求;验收时需保存一条从入口日志到 Scalar request ID 的关联证据。

Worker、Scanner 与死信处置

  1. Worker/Scanner 每次心跳使用固定 component_key upsert部署实例变化写入 instance_id
  2. 心跳状态只能为 STARTING/UP/DEGRADED/DOWNdetail 必须脱敏且有界。
  3. 重试耗尽后写入 education_dead_letter同一租户、组件、workload 只允许一个 OPEN 记录。
  4. 排障后先把原 OPEN 记录标记为 REQUEUED 并填写 resolved_at/resolution_note,再通过所属业务服务重入队;禁止直接修改业务结果或把原 payload 写入死信表。
  5. 未部署对应 Worker/Scanner 时不得伪造 UP 心跳;能力清单应保持未交付状态。

7. 验证命令

mvn -pl yudao-module-education -am test
mvn -pl yudao-server -am package -DskipTests

前端源码归位后还必须执行其 lint、类型检查、测试、生产构建及浏览器 E2E。

8. 已知限制

  • 当前工作区缺少完整 Student Web/H5 前端源码。
  • 尚不能在本仓库完成浏览器 Network 无直连 Scalar 断言。
  • 尚不能完成桌面和 H5 视觉截图对比。
  • 真实 Scalar smoke 依赖部署环境、固定上游版本和有效只读凭据。
  • Pilot 租户列表属于部署配置,修改后需要按配置刷新机制重新加载或重启应用。