feat: rebuild warm operations workbench

This commit is contained in:
Codex
2026-07-30 14:49:33 +08:00
parent 25c853dea8
commit 570edf6bb2
88 changed files with 13413 additions and 2250 deletions
@@ -0,0 +1,47 @@
import { describe, expect, it } from 'vitest';
import { nextOccurrence, previewCron, reconcileOccurrence } from './schedule-time.js';
describe('schedule time', () => {
it('calculates future occurrences in Beijing time across the UTC day boundary', () => {
expect(previewCron('0 9 * * *', 2, new Date('2026-07-30T00:30:00.000Z'))).toEqual([
'2026-07-30T01:00:00.000Z',
'2026-07-31T01:00:00.000Z',
]);
expect(nextOccurrence('30 0 * * *', new Date('2026-07-30T15:59:00.000Z'))).toBe(
'2026-07-30T16:30:00.000Z',
);
});
it('rejects seconds fields and invalid cron grammar', () => {
expect(() => previewCron('* * * * * *', 1)).toThrow(/five-field/i);
expect(() => previewCron('99 99 * * *', 1)).toThrow(/cron/i);
});
it('reconciles a missed due time according to the per-task policy', () => {
const common = {
cronExpression: '*/10 * * * *',
nextDueAt: '2026-07-30T01:00:00.000Z',
};
expect(
reconcileOccurrence(
{ ...common, misfirePolicy: 'skip' },
new Date('2026-07-30T01:25:00.000Z'),
),
).toEqual({
action: 'skip',
dueAt: '2026-07-30T01:20:00.000Z',
nextDueAt: '2026-07-30T01:30:00.000Z',
});
expect(
reconcileOccurrence(
{ ...common, misfirePolicy: 'catch-up-once' },
new Date('2026-07-30T01:25:00.000Z'),
),
).toEqual({
action: 'run',
dueAt: '2026-07-30T01:20:00.000Z',
nextDueAt: '2026-07-30T01:30:00.000Z',
});
});
});