import { z } from "zod"; import { defineTask, TaskRegistry } from "./registry.ts"; // 任务书 §3.1-8 的九类任务。W1 只落空壳:输入 schema + 回显 handler,W2 填充处理器。 // 填充规则见 README「新增/填充任务」:副作用走 withAttemptToken,外部条件用 step.waitForFact, // 业务状态写业务表,不要放进 handler 返回值。 const id = z.string().min(1); /** 空壳 handler:记录一条日志并回显输入 */ function stub(name: string) { return async (ctx: { input: I; logger: { info(msg: string, f?: Record): void } }) => { // TODO(W2): 实现真实处理器 ctx.logger.info(`${name}: stub handler (TODO W2)`); return { todo: true as const, task: name, input: ctx.input }; }; } const NETWORK_RETRY = { maximumAttempts: 5, initialInterval: "1s", backoffCoefficient: 2, maximumInterval: "60s", } as const; const FILE_RETRY = { maximumAttempts: 3, initialInterval: "2s", backoffCoefficient: 2, maximumInterval: "60s", } as const; const DB_RETRY = { maximumAttempts: 3, initialInterval: "1s", backoffCoefficient: 2, maximumInterval: "30s" } as const; export const ingestFeed = defineTask({ name: "ingestFeed", version: 1, inputSchema: z.object({ feedSourceId: id }), retryPolicy: NETWORK_RETRY, handler: stub("ingestFeed"), }); export const resolveObservation = defineTask({ name: "resolveObservation", version: 1, inputSchema: z.object({ observationId: id }), retryPolicy: NETWORK_RETRY, handler: stub("resolveObservation"), }); export const evaluateAcquisition = defineTask({ name: "evaluateAcquisition", version: 1, inputSchema: z.object({ subscriptionId: id.optional(), acquisitionSlotId: id.optional(), sourceReleaseId: id.optional(), }), retryPolicy: DB_RETRY, handler: stub("evaluateAcquisition"), }); export const submitDownload = defineTask({ name: "submitDownload", version: 1, inputSchema: z.object({ acquisitionPlanId: id }), retryPolicy: NETWORK_RETRY, handler: stub("submitDownload"), }); export const verifyAndImport = defineTask({ name: "verifyAndImport", version: 1, inputSchema: z.object({ downloadTaskId: id }), retryPolicy: FILE_RETRY, handler: stub("verifyAndImport"), }); export const refreshMetadata = defineTask({ name: "refreshMetadata", version: 1, inputSchema: z.object({ mediaEntityId: id }), retryPolicy: NETWORK_RETRY, handler: stub("refreshMetadata"), }); export const reconcileLibrary = defineTask({ name: "reconcileLibrary", version: 1, inputSchema: z.object({ libraryRootId: id.optional(), reconcileRunId: id.optional() }), retryPolicy: FILE_RETRY, handler: stub("reconcileLibrary"), }); export const cleanupDownloadCache = defineTask({ name: "cleanupDownloadCache", version: 1, inputSchema: z.object({ downloaderInstanceId: id.optional() }), retryPolicy: FILE_RETRY, handler: stub("cleanupDownloadCache"), }); export const resolveDecision = defineTask({ name: "resolveDecision", version: 1, inputSchema: z.object({ decisionId: id }), retryPolicy: DB_RETRY, handler: stub("resolveDecision"), }); export const TASK_NAMES = [ "ingestFeed", "resolveObservation", "evaluateAcquisition", "submitDownload", "verifyAndImport", "refreshMetadata", "reconcileLibrary", "cleanupDownloadCache", "resolveDecision", ] as const; export type TaskName = (typeof TASK_NAMES)[number]; /** v0.1 的默认注册表;W2 把真实 handler 换进来(同名同版本替换,或升版本并保留旧版本) */ export function createDefaultRegistry(): TaskRegistry { return new TaskRegistry().register( ingestFeed, resolveObservation, evaluateAcquisition, submitDownload, verifyAndImport, refreshMetadata, reconcileLibrary, cleanupDownloadCache, resolveDecision, ); }