fix(schedules): refresh untouched builtin config so checks get new capabilities

Built-in agent checks kept the config stored at first registration, so
check.pending never received decision.list / subscription.list added in
AG-3 and the patrol could not read pending items (REAL-2 scenario g).
Track config_customized (migration 0045); sync replaces config with the
code default unless the user PATCHed it. Needs image rebuild.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-29 03:06:05 +08:00
1 parent 96fc089f92
commit bd0e011748
6 files changed
+52 -5

No files matched your search

@@ -144,6 +144,22 @@ describe.skipIf(!hasPg)("定时任务注册表(真实 PG)", () => {
expect(new Date(cron.body.data.nextRunAt).getHours()).toBe(4);
});
it("config:没改过的行随代码默认值整体更新;PATCH 过的保留表内值", async () => {
const def = (config: Record<string, unknown>) =>
counting("test.cfg", {
defaults: { name: "c", group: "download", schedule: { type: "interval", everyMs: 60_000 }, config },
});
registerScheduledJob(ctx, def({ list: ["a"] }));
await sched.tick();
registerScheduledJob(ctx, def({ list: ["a", "b"] }));
await sched.tick();
expect((await job("test.cfg")).config).toEqual({ list: ["a", "b"] });
expect((await api("PATCH", "/schedules/test.cfg", { config: { list: ["x"] } })).status).toBe(200);
registerScheduledJob(ctx, def({ list: ["a", "b", "c"], extra: 1 }));
await sched.tick();
expect((await job("test.cfg")).config).toEqual({ list: ["x"], extra: 1 });
});
it("立即执行幂等(合并重复请求)且不改下次运行时间", async () => {
registerScheduledJob(
ctx,