Files
UHD_Media_Tool/packages/tasks/src/definitions.ts
T
rootandClaude Fable 5.1 304feea141 chore(deno): migrate toolchain from Node 24 + pnpm to Deno 2.9.7 + TypeScript 7.0.2 (W1.5)
- root deno.json workspace (nodeModulesDir auto), npm versions registered once in imports, deno.lock;
  remove pnpm-lock/pnpm-workspace/root package.json; members keep minimal package.json (name/type/exports)
- tasks: dev, typecheck (tsc 7.0.2 per member + deno check), lint/fmt (biome, useImportExtensions),
  test (vitest via deno), check:tokens, build (web + deno compile), ci, db:migrate/reset, gen:types
- tsconfig base moved to config/ (no root tsconfig.json); deno types -> types/deno.d.ts; web drops baseUrl
- server: Deno.serve entry with graceful shutdown, --role migrate|preflight|probe, WEB_ROOT static SPA hosting;
  drop @hono/node-server, tsx, esbuild build.mjs
- logger: redact child() bindings and serialize err by message/stack; sync stdout destination; tests
- relative imports get explicit extensions (sites/mp-sync paths left for follow-up)
- crash-recovery tests spawn `deno run -A`; tasks tests use unique per-file schemas
- single-container Dockerfile + entrypoint (migrate -> preflight -> api+worker watchdog), docker-compose.yml
- docs: README, runbook, ADR-001 superseded, plan §1 validation row

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-27 18:53:06 +08:00

136 lines
3.8 KiB
TypeScript

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<I>(name: string) {
return async (ctx: { input: I; logger: { info(msg: string, f?: Record<string, unknown>): 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,
);
}