Files
yidaima/RuoYi-Vue/docs/superpowers/specs/2026-07-11-one-click-generation-history-recovery-design.md

117 lines
6.3 KiB
Markdown
Raw Normal View History

# 项目一键生成历史与阶段恢复设计
**状态:** 已实施并通过回归验证
## 1. 背景
项目工厂已经保存一键生成任务、逐阶段执行记录和不可变检查点,失败任务也可以通过原任务重试。但是这些能力主要存在于后端:用户只能看到当前任务,无法查看历次生成,也不知道失败发生在哪个阶段、重试会保留哪些结果。
现有 `front_project_generation` 更接近模型调用审计记录,包含请求和响应 Payload缺少任务阶段、尝试次数和检查点语义不适合作为用户历史列表。
## 2. 方案选择
### 方案 A直接展示 Generation Record
优点是已有查询接口。缺点是记录包含大字段,一个一键任务还可能关联多种模型调用语义,不能可靠表达失败阶段和恢复位置,因此不采用。
### 方案 B任务历史 + 阶段账本 + 检查点
每个 `one_click_project` 任务是一条生成历史;任务内的多次重试用尝试次数表达。历史摘要从任务表、阶段表和检查点表只读计算,继续操作复用现有 `retryTask`。该方案不新增表,和当前执行内核一致,采用此方案。
### 方案 C新增独立 Generation Attempt 聚合表
可以提供更强的报表能力,但需要迁移、双写和历史回填,当前用户主流程不需要这层复杂度,因此暂不采用。
## 3. 用户目标
- 从“我的项目”和一键生成工作台打开项目生成记录。
- 每条记录能看懂状态、时间、尝试次数、失败阶段和最后完成阶段。
- 失败记录明确说明继续生成会从哪个阶段开始,以及是否复用检查点。
- 用户确认后可直接从历史记录继续生成,不需要先寻找当前失败任务。
- 查看任意历史任务时,地址栏写入对应 `taskId`,刷新后仍显示同一任务。
## 4. 历史模型
历史摘要最多返回最近 20 个一键生成任务,字段如下:
| 字段 | 用途 |
| --- | --- |
| `taskId` / `projectId` | 任务定位与用户隔离 |
| `status` / `progress` / `currentStep` | 当前或最终状态 |
| `errorMessage` | 脱敏失败摘要 |
| `attempts` / `maxAttempts` | 尝试信息 |
| `latestAttemptNo` | 阶段账本中的最近尝试 |
| `failedStage` | 最近一次失败阶段 |
| `lastCompletedStage` | 最近完成阶段 |
| `resumeStage` | 再次执行时的起点 |
| `resumeFromCheckpoint` | 是否复用不可变检查点 |
| `canRetry` | 当前状态是否允许继续 |
| `createTime` / `updateTime` | 历史排序与展示 |
响应不得包含 `requestPayload``resultPayload`、Checkpoint Payload、Prompt、模型凭据或完整异常堆栈。
## 5. 恢复规则
恢复规则必须与 `OneClickProjectGenerationServiceImpl` 的真实行为一致:
1. 存在 `SOURCE_PREVIEW` 检查点时,从 `RUN_PREVIEW` 继续,保留已生成源码。
2. 否则存在 `DATABASE_LOOP_AUDIT` 检查点时,从 `BUSINESS_BLUEPRINT` 继续,保留应用蓝图、闭环计划和数据库设计。
3. 没有可用检查点时,从 `PROJECT_PREPARE` 重新开始。
4. 只有 `FAILED``RETRY_WAITING` 状态允许人工继续。
5. 同项目已有另一个同类型活动任务时,服务端拒绝重试旧任务,避免两个任务并发修改同一项目。
## 6. API
新增:
```http
GET /front/project/{projectId}/ai-tasks/one-click-history
```
接口使用当前登录用户身份,先验证项目所有权,再返回最近 20 条轻量摘要。
继续生成复用现有接口:
```http
POST /front/project/{projectId}/ai-tasks/{taskId}/retry
```
不新增“指定阶段重试”参数。恢复起点由服务器根据可信检查点计算,浏览器不能伪造。
## 7. 前端交互
- 项目列表的一键生成单元格增加“生成记录”时钟图标,打开生成工作台并携带 `history=1`
- 一键生成主按钮区域增加“生成记录”入口。
- 历史使用独立 Drawer 组件,按时间倒序展示,不把更多逻辑继续堆进 `GenerateView.vue` 模板。
- “查看任务”加载完整任务并同步路由 `taskId`
- “从最近阶段继续”先显示恢复位置和额度提示,确认后调用现有重试接口。
- 当前项目有活动任务时,历史中的继续按钮禁用;服务端仍执行最终并发校验。
## 8. 错误与并发
- 历史接口失败只影响 Drawer不影响项目工作台和当前任务。
- 历史为空时显示明确空状态。
- 选择另一个历史任务前使旧轮询失效,避免旧任务覆盖当前任务。
- 重试成功但历史刷新失败时,保留“任务已开始”的成功事实,只提示历史刷新失败。
- 项目切换或 Drawer 关闭时清理 `history` 路由参数,不删除任务状态。
## 9. 验收标准
- 历史接口只查询当前用户拥有的项目,最多返回 20 条。
- 历史列表不读取或返回请求、结果和检查点 Payload。
- 失败阶段、最后完成阶段和恢复位置与阶段/检查点账本一致。
- 从历史继续时复用原任务和原请求,服务器决定恢复起点。
- 同项目存在另一个活动一键任务时,重试被拒绝。
- 项目列表和生成工作台均可打开历史;查看任务和继续生成均可跨刷新恢复。
- 后端聚焦测试、前端契约测试、管理端测试和生产构建通过。
## 10. 实施结果
- 新增最近 20 条一键生成任务历史接口,仅返回轻量任务、阶段和恢复摘要。
- 项目列表和一键生成工作台均已接入“生成记录”入口,历史抽屉支持刷新、空状态、失败诊断、查看指定任务和继续生成。
- 恢复提示严格对应现有检查点规则:源码检查点继续运行预览,数据库闭环检查点继续业务蓝图,否则重新准备项目。
- 历史重试复用原任务与原请求,浏览器不传恢复阶段;同项目存在另一个活动任务时,服务端在额度预留前拒绝冲突重试。
- 成功或活动任务不会展示旧失败阶段与恢复提示,避免把前一次尝试的失败误报为当前状态。
- 验证通过:后端聚焦 19 项、控制器聚焦 13 项、管理端全量 40 项、前端主流程 53 项EasyCode 生产构建通过。
- 本轮没有新增数据库表或迁移,也没有修改开发阶段暂缓处理的明文凭据与 TLS 校验配置。