23 files (+4676/-10): - Contract: m-ai-05-feynman-migration-contract.md (737 lines) - Gate audit: m-ai-05-gate-audit.md (318 lines) - Job Definition + Snapshot Builder + Registration - Executor + BusinessValidator + ReferenceValidator - Projector (atomic transaction + 3-layer idempotency) - ExecutionRouter (FeatureFlag + idempotencyKey) - ObservabilityService (structured logging + counters) - Engine: feynman_evaluation execution branch - AiJobCreationService: feynman_evaluation safety branch - Controller/Module: Router injection - CI: path detection for m-ai-05 - E2E: 8 HTTP-layer scenarios (14 total) - Unit tests: 104 new tests (5 spec files) Co-Authored-By: Claude <noreply@anthropic.com>
43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
|
||
import { JobDefinitionRegistry, DuplicateJobTypeError } from './job-definition-registry';
|
||
import { FEYNMAN_JOB_DEFINITION } from './feynman-job-definition';
|
||
|
||
/**
|
||
* M-AI-05-02: Feynman Job Definition 注册服务
|
||
*
|
||
* 在模块初始化(onModuleInit)时向 JobDefinitionRegistry 注册
|
||
* FeynmanEvaluation JobDefinition。
|
||
*
|
||
* 容忍重复注册:API 进程和 Worker 进程各自独立启动,均导入
|
||
* AiJobModule,因此同一 Definition 会被注册两次。第二次注册的
|
||
* DuplicateJobTypeError 被安全捕获,不阻止进程启动。
|
||
*/
|
||
@Injectable()
|
||
export class FeynmanRegistrationService implements OnModuleInit {
|
||
private readonly logger = new Logger(FeynmanRegistrationService.name);
|
||
|
||
constructor(private readonly registry: JobDefinitionRegistry) {}
|
||
|
||
onModuleInit(): void {
|
||
try {
|
||
this.registry.register(FEYNMAN_JOB_DEFINITION);
|
||
this.logger.log(
|
||
`Feynman Job Definition registered: ` +
|
||
`jobType="${FEYNMAN_JOB_DEFINITION.jobType}" ` +
|
||
`queue="${FEYNMAN_JOB_DEFINITION.queue.queueName}" ` +
|
||
`timeout=${FEYNMAN_JOB_DEFINITION.execution.timeoutMs}ms ` +
|
||
`retries=${FEYNMAN_JOB_DEFINITION.execution.maxRetries}`,
|
||
);
|
||
} catch (err: unknown) {
|
||
if (err instanceof DuplicateJobTypeError) {
|
||
this.logger.log(
|
||
`Feynman Job Definition already registered ` +
|
||
`(by another process — e.g. API + Worker both import AiJobModule)`,
|
||
);
|
||
} else {
|
||
throw err;
|
||
}
|
||
}
|
||
}
|
||
}
|