


























@@ -223,6 +223,82 @@ describe("cron service store seam coverage", () => {
223223]);
224224});
225225226+it("skips preserved unsupported rows that collide with supported jobs by canonical id", async () => {
227+const { storePath } = await makeStorePath();
228+229+await writeJobStore(storePath, [
230+{
231+id: "trimmed-collision",
232+name: "supported trimmed collision",
233+enabled: true,
234+createdAtMs: STORE_TEST_NOW - 60_000,
235+updatedAtMs: STORE_TEST_NOW - 60_000,
236+schedule: { kind: "every", everyMs: 60_000 },
237+sessionTarget: "main",
238+wakeMode: "now",
239+payload: { kind: "systemEvent", text: "tick" },
240+state: {},
241+},
242+{
243+id: " trimmed-collision ",
244+name: "stale unsupported padded id",
245+enabled: true,
246+createdAtMs: STORE_TEST_NOW - 60_000,
247+schedule: { kind: "cron", expr: "0 8 * * *", tz: "UTC" },
248+sessionTarget: "main",
249+wakeMode: "now",
250+payload: { kind: "command", command: "echo stale" },
251+},
252+{
253+id: "legacy-jobid-collision",
254+name: "supported legacy jobId collision",
255+enabled: true,
256+createdAtMs: STORE_TEST_NOW - 60_000,
257+updatedAtMs: STORE_TEST_NOW - 60_000,
258+schedule: { kind: "every", everyMs: 120_000 },
259+sessionTarget: "main",
260+wakeMode: "now",
261+payload: { kind: "systemEvent", text: "tick legacy" },
262+state: {},
263+},
264+{
265+jobId: " legacy-jobid-collision ",
266+name: "stale unsupported legacy jobId",
267+enabled: true,
268+createdAtMs: STORE_TEST_NOW - 60_000,
269+schedule: { kind: "cron", expr: "0 9 * * *", tz: "UTC" },
270+sessionTarget: "main",
271+wakeMode: "now",
272+payload: { kind: "agentmessage", message: "summarize stale" },
273+},
274+]);
275+276+const state = createStoreTestState(storePath);
277+await ensureLoaded(state, { skipRecompute: true });
278+279+expect(state.store?.jobs.map((job) => job.id)).toEqual([
280+"trimmed-collision",
281+"legacy-jobid-collision",
282+]);
283+284+await persist(state);
285+286+const config = JSON.parse(await fs.readFile(storePath, "utf8")) as {
287+jobs: Array<Record<string, unknown>>;
288+};
289+expect(config.jobs.map((job) => job.id)).toEqual([
290+"trimmed-collision",
291+"legacy-jobid-collision",
292+]);
293+expect(config.jobs.map((job) => job.name)).toEqual([
294+"supported trimmed collision",
295+"supported legacy jobId collision",
296+]);
297+expect(config.jobs.some((job) => job.jobId === " legacy-jobid-collision ")).toBe(false);
298+expect(config.jobs.some((job) => job.name === "stale unsupported padded id")).toBe(false);
299+expect(config.jobs.some((job) => job.name === "stale unsupported legacy jobId")).toBe(false);
300+});
301+226302it("normalizes jobId-only jobs in memory so scheduler lookups resolve by stable id", async () => {
227303const { storePath } = await makeStorePath();
228304此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。