diff --git a/docs/architecture/m-ai-07-gate-audit.md b/docs/architecture/m-ai-07-gate-audit.md new file mode 100644 index 0000000..f171c15 --- /dev/null +++ b/docs/architecture/m-ai-07-gate-audit.md @@ -0,0 +1,143 @@ +# M-AI-07-GATE:Quiz 生成统一引擎迁移验收 + +> 审核日期:2026-06-22 +> HEAD:`24f9098` +> 基线:M-AI-06 PASS + +--- + +## 一、完成标准逐条验证 + +### 1. 原 Quiz 生成接口兼容 ✅ + +`POST /api/ai/jobs` 保持不变。Controller 路由:`quiz_generation` → `QuizExecutionRouter`,其他 → `UserAiService`。 + +- `user-ai.controller.ts:68-73` — Controller 路由 + +### 2. Legacy 模式仍可执行 ✅ + +Flag 关闭时走 `UserAiService.createAnalysisJob()` 原路径。 + +- `quiz-execution-router.ts:43-45` — Legacy 委托 + +### 3. Unified 模式经过 AiJobCreationService ✅ + +- `quiz-execution-router.ts:59-72` — SnapshotBuilder → CreationService.createJob() + +### 4. Job、Snapshot、Outbox 原子创建 ✅ + +- `ai-job-creation.service.ts:158` — `$transaction(createFn)` + +### 5. Definition 正确注册 ✅ + +`quiz_generation` 已注册:ai-interactive, primary tier, 180s timeout + +- `quiz-generation-job-definition.ts` +- `quiz-generation-registration.service.spec.ts` — 注册测试通过 + +### 6. Executor 仅通过 AiGateway ✅ + +- `quiz-generation-executor.ts:40` — 只注入 `AiGatewayService` +- 无 Prisma/Provider SDK 注入 + +### 7. 输出验证完整 ✅ + +3 题型验证(choice/judge/fill),12 条规则 + +- `quiz-generation-validator.ts` — choice options/index, judge true/false, fill answer, 重复, 模型指令 + +### 8. Quiz 和 Questions 原子写入 ✅ + +- `quiz-generation-projector.ts:77-111` — 同一 tx 内 quiz.create + quizQuestion.create × N + +### 9. 重复请求不重复 Quiz ✅ + +- `quiz-execution-router.ts:65` — `idempotencyKey` +- `ai-job-creation.service.ts:143-155` — check-before-create + +### 10. 重复消费不重复 Questions ✅ + +- `quiz-generation-projector.ts:51-65` — 入口 Artifact 检查 +- P2002 catch on Artifact create + +### 11. 跨用户内容不可访问 ✅ + +- `quiz-generation-snapshot-builder.ts:108-117` — KB 所有权验证 + +### 12. 正确答案不提前泄漏 ✅ + +- `user-ai.service.ts:549-552` — 仅在 hasAttempt 后返回 answer +- `quiz.service.ts:83-86` — 移除 questions include + +### 13. Unified 失败不自动执行 Legacy ✅ + +- `quiz-execution-router.ts:43-45` — 互斥路由 + +### 14. Feature Flag 可快速回滚 ✅ + +- `quiz-execution-router.ts:82-87` — Flag 查询失败 → legacy 回退 +- E2E 场景 14 验证 + +### 15. 真实 E2E 与 CI 通过 ✅ + +- `test/m-ai-07-quiz-generation.e2e-spec.ts` +- CI: `.gitea/workflows/deploy.yml` 含 `test/m-ai-07` + +### 16. M-AI-07-GATE 为 PASS ✅ + +全部 16 条通过。 + +--- + +## 二、问题分级 + +### P0:无 + +### P1:无 + +### P2 +- Quiz 主键 CUID 自动生成,不支持 deterministic ID(与 ReviewCard 相同模式,入口幂等 + P2002 足够) +- Engine 分派硬编码 `if (jobType === 'quiz_generation')`(与 review_card_generation 一致) + +### P3(不阻塞) +- 压力测试、Worker SIGKILL、Legacy Runtime 清理 + +--- + +## 三、文件清单 + +| 文件 | Issue | +|------|-------| +| `docs/architecture/m-ai-07-quiz-generation-migration-contract.md` | 01 | +| `src/modules/ai-job/quiz-generation-job-definition.ts` | 02 | +| `src/modules/ai-job/quiz-generation-snapshot-builder.ts` | 02 | +| `src/modules/ai-job/quiz-generation-registration.service.ts` | 02 | +| `src/modules/ai-job/quiz-generation-registration.service.spec.ts` | 02 | +| `src/modules/ai/prompts/quiz-generation.prompt.ts` | 03 | +| `src/modules/ai/prompts/schemas/quiz-generation.schema.ts` | 03 | +| `src/modules/ai/prompts/prompt-template.service.ts` | 03 | +| `src/modules/ai-job/quiz-generation-executor.ts` | 03 | +| `src/modules/ai-job/quiz-generation-validator.ts` | 03 | +| `src/modules/ai-job/quiz-generation-executor.spec.ts` | 03 | +| `src/modules/ai-job/quiz-generation-projector.ts` | 04 | +| `src/modules/ai-job/quiz-generation-projector.spec.ts` | 04 | +| `src/modules/ai-runtime/quiz-execution-router.ts` | 05 | +| `src/modules/ai-runtime/user-ai.controller.ts` | 05 | +| `src/modules/ai-runtime/ai-runtime.module.ts` | 05 | +| `src/modules/ai-runtime/user-ai.service.ts` | 06 | +| `src/modules/quiz/quiz.service.ts` | 06 | +| `src/modules/ai-job/ai-job-execution-engine.ts` | 03 | +| `src/modules/ai-job/ai-job.module.ts` | 02-04 | +| `test/m-ai-07-quiz-generation.e2e-spec.ts` | 07 | +| `.gitea/workflows/deploy.yml` | 07 | + +--- + +## 四、最终结论 + +``` +M-AI-07-GATE:PASS +是否允许进入下一里程碑:是 +是否允许生产白名单 Quiz Unified:是 +是否允许删除 Legacy:否 +```