From 0ed61b31a5fa5cf5ee7073aa7f800839091eda79 Mon Sep 17 00:00:00 2001 From: Feelw00 Date: Wed, 8 Apr 2026 19:59:34 +0900 Subject: [PATCH] =?UTF-8?q?fix(cron):=20address=20PR=20review=20=E2=80=94?= =?UTF-8?q?=20path=20guard,=20updatedAtMs=20backfill,=20remove=20redundant?= =?UTF-8?q?=20chmod?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - resolveStatePath: handle storePath not ending in .json - loadCronStore: backfill updatedAtMs from createdAtMs for jobs missing state entry - atomicWrite: remove redundant setSecureFileMode on tmp (writeFile mode already sets it) Co-Authored-By: Claude Opus 4.6 (1M context) --- src/cron/store.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cron/store.ts b/src/cron/store.ts index 80cdc1c8ad6..369fd8c5c70 100644 --- a/src/cron/store.ts +++ b/src/cron/store.ts @@ -17,7 +17,10 @@ function resolveDefaultCronStorePath(): string { } function resolveStatePath(storePath: string): string { - return storePath.replace(/\.json$/, "-state.json"); + if (storePath.endsWith(".json")) { + return storePath.replace(/\.json$/, "-state.json"); + } + return `${storePath}-state.json`; } type CronStateFileEntry = { @@ -130,6 +133,10 @@ export async function loadCronStore(storePath: string): Promise { if (!job.state || typeof job.state !== "object") { job.state = {} as never; } + // Backfill updatedAtMs for manually-added jobs that have no state entry yet. + if (typeof job.updatedAtMs !== "number") { + job.updatedAtMs = typeof job.createdAtMs === "number" ? job.createdAtMs : Date.now(); + } } } } else if (!hasInlineState(jobs as unknown as Array>)) { @@ -178,7 +185,6 @@ async function atomicWrite(filePath: string, content: string, dirMode = 0o700): await fs.promises.chmod(dir, dirMode).catch(() => undefined); const tmp = `${filePath}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`; await fs.promises.writeFile(tmp, content, { encoding: "utf-8", mode: 0o600 }); - await setSecureFileMode(tmp); await renameWithRetry(tmp, filePath); await setSecureFileMode(filePath); }