- result-projector.interface.ts: ResultProjector 接口冻结(ADR-003 §6.1) project(tx, context) → ArtifactReference[] - synthetic-result-projector.ts: 测试用 Synthetic Projector 幂等:已有 Artifact 时直接返回 - projection-executor.service.ts: ProjectionExecutor 事务内:projector.project(tx) + markSucceeded(tx) 原子提交 幂等检查:Job 已终态 → 跳过 NestJS multi-provider 注入 RESULT_PROJECTORS - ai-job-execution-engine.ts: PROJECT 阶段改为调用 ProjectionExecutor - ai-job.module.ts: 注册 ProjectionExecutor + SyntheticResultProjector Co-Authored-By: Claude <noreply@anthropic.com>
47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import type { Prisma } from '@prisma/client';
|
||
|
||
/**
|
||
* M-AI-03-09: Result Projector 接口(ADR-003 §6.1 冻结)
|
||
*
|
||
* 每个 Projector 负责将 validatedOutput 投影到具体业务实体。
|
||
* 在 Prisma Transaction 内执行,与 AiJobArtifact + markSucceeded 共享事务。
|
||
*/
|
||
|
||
export interface ArtifactReference {
|
||
artifactType: string;
|
||
artifactId: string;
|
||
ordinal: number;
|
||
}
|
||
|
||
export interface ProjectionContext {
|
||
job: {
|
||
id: string;
|
||
userId: string;
|
||
jobType: string;
|
||
targetType: string | null;
|
||
targetId: string | null;
|
||
snapshotId: string | null;
|
||
promptVersion: string | null;
|
||
outputSchemaVersion: string | null;
|
||
};
|
||
snapshot: any;
|
||
validatedOutput: Record<string, any>;
|
||
}
|
||
|
||
export interface ResultProjector {
|
||
/** 全局唯一 key,对应 JobDefinition.projectorKey */
|
||
readonly key: string;
|
||
|
||
/**
|
||
* 在 Prisma Transaction 内执行投影。
|
||
* 如果业务实体已存在(幂等),返回已有 Artifact 引用。
|
||
*/
|
||
project(
|
||
tx: Prisma.TransactionClient,
|
||
context: ProjectionContext,
|
||
): Promise<ArtifactReference[]>;
|
||
}
|
||
|
||
/** NestJS 注入 Token */
|
||
export const RESULT_PROJECTORS = 'RESULT_PROJECTORS';
|