[M-AI-07-04] 实现 Quiz Projector、题目产物与数据库级幂等 #323

Closed
opened 2026-06-22 20:23:23 +08:00 by wangdl · 1 comment
Owner

类型 / 标签

  • backend / quiz / projector / idempotency

风险等级

P0 — 非原子写入会导致部分题目残留;幂等失效会导致重复 Quiz

依赖

  • M-AI-07-03

目标

将验证后的 Quiz 输出原子写入现有 Quiz 数据模型,并建立 Artifact。

Projector

新增 QuizGenerationProjector。同一事务完成:Quiz、QuizQuestion × N、QuizOption / 题目结构、AiJobArtifact、validatedOutput、outputHash、Job succeeded、finishedAt。具体实体以审计为准。

Deterministic ID

如果主键支持显式写入:quizId = deterministic(jobId)、questionId = deterministic(jobId + ordinal)、optionId = deterministic(questionId + ordinal)。要求:同一 Job 重复执行相同实体、不同 Job 不冲突、题目顺序稳定、不使用题干作为全局唯一键。

Artifact

至少创建 artifactType = quiz、artifactId = Quiz.id。可根据需要为 Question 建立 metadata,不为每个 Option 创建无意义 Artifact。

原子回滚

必须验证:Quiz 创建失败、第一个 Question 失败、中间 Question 失败、Option 写入失败、Artifact 失败、Job succeeded 更新失败。任何一步失败:Quiz/Question/Artifact count = 0,Job 不得 succeeded。

幂等

串行重复:同一 Projector 执行两次,Quiz 和题目数量不变。并发重复:两个执行者并发投影同一 Job,最终只有一个 Quiz。失败重试:第一次失败完整回滚,第二次成功,不产生重复题目。

答案安全

Projector 可保存正确答案,但必须确认:正确答案不通过不应暴露的查询 DTO 提前返回、日志不记录完整答案集、Artifact metadata 不泄漏答案。

验收标准

  • 原子写入
  • 数据库级幂等
  • 失败无部分 Quiz
  • Artifact 完整
  • 正确答案安全
  • 旧 Quiz 查询可读取
  • 真实 MySQL 集成测试通过

建议执行顺序

第 4 个执行

## 类型 / 标签 - backend / quiz / projector / idempotency ## 风险等级 P0 — 非原子写入会导致部分题目残留;幂等失效会导致重复 Quiz ## 依赖 - M-AI-07-03 ## 目标 将验证后的 Quiz 输出原子写入现有 Quiz 数据模型,并建立 Artifact。 ## Projector 新增 `QuizGenerationProjector`。同一事务完成:Quiz、QuizQuestion × N、QuizOption / 题目结构、AiJobArtifact、validatedOutput、outputHash、Job succeeded、finishedAt。具体实体以审计为准。 ## Deterministic ID 如果主键支持显式写入:quizId = deterministic(jobId)、questionId = deterministic(jobId + ordinal)、optionId = deterministic(questionId + ordinal)。要求:同一 Job 重复执行相同实体、不同 Job 不冲突、题目顺序稳定、不使用题干作为全局唯一键。 ## Artifact 至少创建 artifactType = quiz、artifactId = Quiz.id。可根据需要为 Question 建立 metadata,不为每个 Option 创建无意义 Artifact。 ## 原子回滚 必须验证:Quiz 创建失败、第一个 Question 失败、中间 Question 失败、Option 写入失败、Artifact 失败、Job succeeded 更新失败。任何一步失败:Quiz/Question/Artifact count = 0,Job 不得 succeeded。 ## 幂等 串行重复:同一 Projector 执行两次,Quiz 和题目数量不变。并发重复:两个执行者并发投影同一 Job,最终只有一个 Quiz。失败重试:第一次失败完整回滚,第二次成功,不产生重复题目。 ## 答案安全 Projector 可保存正确答案,但必须确认:正确答案不通过不应暴露的查询 DTO 提前返回、日志不记录完整答案集、Artifact metadata 不泄漏答案。 ## 验收标准 - [ ] 原子写入 - [ ] 数据库级幂等 - [ ] 失败无部分 Quiz - [ ] Artifact 完整 - [ ] 正确答案安全 - [ ] 旧 Quiz 查询可读取 - [ ] 真实 MySQL 集成测试通过 ## 建议执行顺序 第 4 个执行
wangdl added this to the M-AI-07 Quiz 生成与题目产物统一引擎迁移 milestone 2026-06-22 20:23:23 +08:00
Author
Owner

开发完成评论

完成内容

  • QuizGenerationProjector: 原子写入 Quiz + QuizQuestion x N + AiJobArtifact
  • 入口幂等: Artifact 检查
  • P2002 catch 回退
  • 无效题目过滤 (missing stem/answer)
  • 注册到 RESULT_PROJECTORS factory

修改文件

  • src/modules/ai-job/quiz-generation-projector.ts — new (135 lines)
  • src/modules/ai-job/quiz-generation-projector.spec.ts — new (165 lines, 7 tests)
  • src/modules/ai-job/ai-job.module.ts — modified (+3 lines)

测试情况

  • 7 passed (new) + 533 passed (regression) = 0 failed

是否建议进入 Review

  • 是 — 建议进入 M-AI-07-05
## 开发完成评论 ### 完成内容 - QuizGenerationProjector: 原子写入 Quiz + QuizQuestion x N + AiJobArtifact - 入口幂等: Artifact 检查 - P2002 catch 回退 - 无效题目过滤 (missing stem/answer) - 注册到 RESULT_PROJECTORS factory ### 修改文件 - src/modules/ai-job/quiz-generation-projector.ts — new (135 lines) - src/modules/ai-job/quiz-generation-projector.spec.ts — new (165 lines, 7 tests) - src/modules/ai-job/ai-job.module.ts — modified (+3 lines) ### 测试情况 - 7 passed (new) + 533 passed (regression) = 0 failed ### 是否建议进入 Review - 是 — 建议进入 M-AI-07-05
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wangdl/api-server#323
No description provided.