[M-AI-04-05] 将 Active Recall 提交入口接入统一 AiJob CreationService #300
Closed
opened 2026-06-21 12:48:14 +08:00 by wangdl
·
3 comments
Labels
Clear labels
adr
Area: adr
architecture
Area: architecture
area:activity
活动/统计
area:admin
管理后台
area:admin-api
area:ai
AI/RAG
area:ai-runtime
AI Runtime / AI 分析体系相关
area:analytics
area:api
API 接口
area:auth
认证与授权
area:cos
对象存储
area:database
数据库/Migration
area:import
文件导入/解析
area:knowledge
知识库/知识点
area:learning-info
area:learning-session
area:quiz
测验/自测
area:reading-event
area:reading-progress
area:review
复习系统
area:security
安全相关
audit
Area: audit
audit:api-admin-info
audit:api-info
audit:planned
已完成宏观规划,尚未代码审查
audit:reviewed
backend
Area: backend
billing
Area: billing
blocked-by:api-info-aggregation
blocked-by:api-info-core
blocked-by:api-info-ops
blocked-by:api-info-schema
blocked-by:processor
blocked-by:schema
compatibility
Area: compatibility
gate
Area: gate
infrastructure
Area: infrastructure
priority:p0
最高优先级,阻塞发布
priority:p1
高优先级,里程碑必需
priority:p2
中优先级,后续版本
prisma
Area: prisma
release
Area: release
repo:api
API 仓库 Issue
status:blocked
被阻塞
status:done
已完成
status:partial
status:todo
type:aggregation
type:bug
缺陷修复
type:design
设计
type:docs
文档
type:feature
新功能
type:migration
type:refactor
重构
type:test
work:admin-api
work:aggregation
work:api
work:artifact
题目/卡片产物
work:audit
work:circuit-breaker
熔断
work:contract
work:design
架构/协议设计工作
work:docs
work:export
work:extend-existing
work:internal-api
Runtime 内部接口
work:job
Job 调度相关
work:new-module
work:new-table
work:ops
work:query
work:quota
额度/限流
work:schema
Prisma Schema 设计
work:security
work:service
Service 层实现
work:snapshot
Snapshot 构建
work:test
No Label
Milestone
No items
No Milestone
M-AI-04 Active Recall 端到端迁移
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: wangdl/api-server#300
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
类型 / 标签
风险等级
P0
依赖
背景
在保持现有 HTTP 契约的前提下,为 Active Recall 增加 Unified 执行分支。通过 Feature Flag 控制走 Legacy 路径还是新 Unified 路径,由单一 Router/Strategy 决定分支。
目标
非目标
影响范围
入口
保持:
POST /api/active-recalls/:id/submit分支逻辑
应由单一 Router/Strategy 决定(ActiveRecallExecutionRouter),不得把迁移判断散落在 Controller、Service 和 Worker 多处。
允许增加用户白名单或测试用户开关。
Unified 流程
幂等
重复提交相同业务版本时:返回同一 Job、不创建第二个 Snapshot/Outbox、不重复消费用户额度、不重复创建分析结果
用户修改答案后重新提交的语义,由 01 迁移契约决定。
错误处理
CreationService 事务失败时:请求失败、不得直接调用 Legacy、不得产生半条业务记录、日志包含 requestId/userId/activeRecallId、不得记录完整用户答案
验收标准
建议执行顺序
第 5 个执行(依赖 M-AI-04-02/03/04 全部完成)
开发完成评论
完成内容
ActiveRecallExecutionRouter— Feature FlagACTIVE_RECALL_ENGINE_MODE分流,支持白名单,Flag 查询失败 → 安全回退 legacyActiveRecallService.submit()增加 Unified 分支 — 通过AiJobCreationService创建 Job(targetType=active_recall_answer, targetId=answerId, idempotencyKey=active-recall:<answerId>)AiJobCreationService增加active_recalljobType 分派 →ActiveRecallSnapshotBuilder.buildSnapshot()AiJobExecutionEngineEXECUTE 阶段增加active_recall分派 →ActiveRecallExecutor.execute()ActiveRecallProjector(M-AI-04-04 注册在 RESULT_PROJECTORS)— 无需修改修改/新增文件
src/modules/ai-job/active-recall-execution-router.ts— 新增, Feature Flag 分流 Routersrc/modules/ai-job/ai-job-creation.service.ts— 修改, +ActiveRecallSnapshotBuilder 注入 + active_recall 分支src/modules/ai-job/ai-job-execution-engine.ts— 修改, +ActiveRecallExecutor 注入 + active_recall 执行分派src/modules/ai-job/ai-job.module.ts— 修改, +AppConfigModule import, +ActiveRecallExecutionRouter provider/exportsrc/modules/active-recall/active-recall.service.ts— 修改, 重写 submit() 增加 Unified 分支src/modules/active-recall/active-recall.module.ts— 修改, +AiJobModule + AppConfigModule importssrc/modules/ai-job/ai-job-execution-engine.spec.ts— 修改, +ActiveRecallExecutor mocksrc/modules/ai-job/ai-job-creation.service.spec.ts— 修改, +ActiveRecallSnapshotBuilder mock代码证据
active-recall-execution-router.ts:29-42:FeatureFlag 查询 + 安全回退 legacyactive-recall.service.ts:36-64:Unified 路径 — createJob(targetType='active_recall_answer', idempotencyKey='active-recall:')active-recall.service.ts:47-48:幂等键构造active-recall:${answer.id}ai-job-creation.service.ts:78-84:active_recall 分支 → ActiveRecallSnapshotBuilder.buildSnapshot()ai-job-execution-engine.ts:167-178:active_recall 分支 → ActiveRecallExecutor.execute()ai-job-execution-engine.ts:167:EXECUTE → PROJECT 管线不变,ActiveRecallProjector 自动匹配测试情况
npm run buildnpx jest --testPathPatterns="ai-job|active-recall"验收标准对照
submit()Legacy 分支代码未修改active-recall.service.ts:38-53AiJobCreationService.createJob()不变active-recall:<answerId>AiJobCreationService不变{ ...answer, jobId, engine: 'unified' }未完成 / 风险
ACTIVE_RECALL_ENGINE_MODE默认不存在于 DB,Router 安全回退 legacy{ error: 'AI analysis queuing failed' }连锁修复(本 Issue 发现)
是否建议进入 Review
Blocking 问题修复
1. P0 跨用户 question 所有权校验缺失 ✅ 已修复
攻击路径: 用户 A 提交用户 B 的 questionId →
createAnswer成功(answer 属于 A)→SnapshotBuilder通过(answer 确实属于 A)→ AI 分析用户 B 的问题 → 结果写入 A 名下。根因: M-AI-04-01 关键发现 #2 —
ActiveRecallService.submit()不校验question.userId === userId。修复:
active-recall.service.ts:28-30— 在createAnswer()之前增加:修改:
active-recall.service.ts:+ForbiddenException import, +3 行所有权校验测试: 242/242 passed(无回归)
Non-blocking 问题修复
2. ActiveRecallModule 冗余导入 AppConfigModule ✅ 已修复
import { AppConfigModule }和imports: [..., AppConfigModule]3. engine 字段暴露内部实现细节 ✅ 已修复(对称化)
{ ...answer, jobId, engine: "unified" }{ ...answer, jobId, engine: "legacy" }← 新增, 形状对称engine字段,iOS 端无需判断响应 shape 差异AiAnalysisService.analyze()返回值中提取jobId4. 错误消息泛化 ✅ 已确认
"AI analysis queuing failed"是安全设计 — 不泄露内部故障细节修改
active-recall.module.ts:移除 AppConfigModule importactive-recall.service.ts:Legacy 路径返回{ ...answer, jobId, engine: "legacy" }对称 Unified测试