# 项目持久化 Quality Run 设计 **状态:** 已实施并验证(P1-L,2026-07-12) ## 1. 目标 把“运行预览成功”升级为可追溯的项目质量运行。每次 Quality Run 必须绑定当前用户、项目、Generation Run 和源码聚合哈希,并持久化 Java 测试、前端生产构建、SQL 隔离导入、API 冒烟四项结果。只有当前源码对应的最新 Quality Run 全部通过,才允许 `CERTIFIED` 下载。 ## 2. 边界 - 本轮不冻结 ZIP 字节;认证制品固化属于 P1-M。 - 本轮复用现有运行预览,不建设 Docker/Preview Worker;容器隔离属于 P1-N。 - 不把 Plugin 交付演练、目标库脚本或菜单 SQL 混入项目质量运行。 - 不修改开发阶段暂缓处理的模型凭据和 TLS 配置。 - Quality Run 不保存密码、数据库 URL、完整命令或无限日志,只保存脱敏摘要和有界日志片段。 ## 3. 持久化模型 新增 `factory_project_quality_run`: - 绑定 `project_id`、`user_id`、`generation_run_id`、`source_aggregate_hash`。 - 状态为 `QUEUED`、`RUNNING`、`PASSED`、`FAILED`、`INTERRUPTED`。 - 保存检查总数、通过数、失败数、开始/结束时间、耗时、尝试号和脱敏失败摘要。 - 保存 Worker、租约截止时间和更新时间。服务重启后,过期运行关闭为 `INTERRUPTED`,用户创建新运行,不恢复原外部进程。 新增 `factory_project_quality_check`: - 每个 Run 固定四条:`JAVA_TEST`、`FRONTEND_BUILD`、`SQL_IMPORT`、`API_SMOKE`。 - 保存固定顺序、状态、摘要、有界日志、时间和耗时。 - 同一 Run 的检查 code 和顺序分别唯一。 升级脚本同时写入 `sql/factory_project_quality_run.sql`、`sql/front_workbench.sql` 和 `sql/db.sql`,确保升级库和新库结构一致。 ## 4. 执行流程 1. 用户创建质量运行。 2. 服务端读取交付就绪度,要求当前源码、一键任务成功、完整 Generation Run 和运行预览证据均有效。 3. 若项目已有 `QUEUED` 或 `RUNNING` 质量运行,直接返回该运行,不重复入队。 4. 在一个事务内写入 Run 和四条 `PENDING` Check。 5. Worker 条件认领 Run,创建独立质量工作区并依次执行四项检查。 6. 每项检查在开始和结束时持久化状态;单项失败不阻止其他可独立执行的检查。 7. 四项全部通过时 Run 为 `PASSED`,否则为 `FAILED`;清理临时数据库、预览进程和工作区。 8. 交付就绪度只接受与当前 Generation Run ID 和聚合哈希都匹配的最新 `PASSED` Run。 ## 5. 四项检查 ### Java Test - 定位生成后端的 `pom.xml`。 - 执行 `mvn test`,使用独立 Maven 本地缓存和配置超时。 - 缺少后端工程或命令超时均失败。 ### Frontend Build - 定位所有启用且包含 `package.json` 的前端目录。 - 有 lockfile 时执行 `npm ci`,否则执行 `npm install`,随后执行 `npm run build`。 - 所有启用前端都必须通过;项目明确未启用用户前台时不要求该目标,但管理端仍必须构建。 ### SQL Import - 复用 `RunPreviewDatabaseInitializer`,创建名称受限的独立 MySQL 数据库。 - 导入生成 SQL 后立即删除数据库;清理失败写入摘要并使检查失败。 - 不连接 Plugin 目标库,也不把目标库 bootstrap 合并到控制库。 ### API Smoke - 复用 `IFrontProjectRunPreviewService` 启动当前项目运行预览。 - 轮询到 `RUNNING` 才通过;`FAILED`、超时或进程提前退出均失败。 - 无论结果如何都调用 stop,避免遗留进程和预览数据库。 ## 6. API 与前端 新增: ```http POST /front/project/{projectId}/quality-runs GET /front/project/{projectId}/quality-runs GET /front/project/{projectId}/quality-runs/latest ``` - 所有接口使用当前登录用户,不能从请求体指定 userId、Generation Run 或源码哈希。 - 一键生成结果区展示四项技术检查、运行状态、耗时和失败摘要。 - 基线证据齐全但没有通过的质量运行时显示“开始质量验收”;失败后显示“重新质量验收”;运行中禁用重复提交并轮询。 - `CERTIFIED` 按钮只由服务端返回的 `certifiedDownloadAllowed` 控制。 ## 7. 验收标准 - 质量运行和四项检查可以在服务重启后查询。 - 旧 Generation Run 的成功质量记录不能认证当前源码。 - `RUNNING`、`FAILED`、`INTERRUPTED` 或检查不完整的 Run 不能认证下载。 - 四项检查全部通过后,交付摘要进入 `ACCEPTED` 并允许 `CERTIFIED`。 - 项目编辑或数据库同步使当前源码身份变化后,旧 Quality Run 自动失效。 - 新增 SQL 同时存在于升级脚本、`front_workbench.sql` 和 `db.sql`。 ## 8. 实施结果 - Quality Run、四项 Check、条件认领、租约和中断状态均已持久化;最终写入同样受 Worker owner 条件保护,丢失租约不会误报处理成功。 - Java 测试、前端构建、SQL 隔离导入和 API 冒烟已接入真实执行器,并复用运行预览的 MySQL 配置和预览服务。 - 交付摘要只在当前 Generation Run、源码聚合哈希和四项通过证据完全匹配时进入 `ACCEPTED`;旧 Run、失败 Run 和不完整 Run 均不能开放认证下载。 - EasyCode 已提供开始、重试、运行中禁用、四项结果展示和终态轮询刷新。 - 聚焦后端 50 项、`ruoyi-admin` 全量 43 项、EasyCode 主流程 73 项和生产构建均通过;Mapper XML 解析通过,开发服务返回 HTTP 200。 - 未连接或迁移外部数据库。部署前必须应用 Quality Run 表结构。 下一轮 P1-M 固化通过质量检查的 ZIP 字节、哈希和质量报告;在此之前,`CERTIFIED` 下载仍会按请求重新打包,不具备不可变制品语义。