refactor(cron): rename scheduler feature to cron

Rename the recurring-jobs feature scheduler->cron to disambiguate from the
legacy ScheduledRun system (/api/scheduled), which is left untouched:

- ScheduledJob->CronJob, SchedulerService->CronService
- /api/scheduler/jobs -> /api/cron/jobs; SSE scheduler:* -> cron:*
- state keys cronJobs/cronJobRuns
- files moved to src/cron/, cron-routes.ts, cron-port.ts, types/cron.ts
- frontend cron-ui.js, #cronModal, menu "Cron"
- docs moved to docs/cron-discovery.md + docs/cron-build-brief.md, README guides
- new tests: cron-service.test.ts, cron-time.test.ts

Green: tsc, lint, frontend-syntax, format, 30 cron + 9 legacy scheduled-runs tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmvZR12aX2v8K7YhqxPUAU
This commit is contained in:
Kris
2026-06-29 11:35:56 +05:30
co-authored by Claude Opus 4.8
parent 2d2f4e592b
commit 9feaa0d6e5
27 changed files with 1383 additions and 370 deletions
+23 -23
View File
@@ -272,11 +272,11 @@ export class StateStore {
if (this.state.tokenStats) {
parts.push(`"tokenStats":${JSON.stringify(this.state.tokenStats)}`);
}
if (this.state.scheduledJobs) {
parts.push(`"scheduledJobs":${JSON.stringify(this.state.scheduledJobs)}`);
if (this.state.cronJobs) {
parts.push(`"cronJobs":${JSON.stringify(this.state.cronJobs)}`);
}
if (this.state.scheduledJobRuns) {
parts.push(`"scheduledJobRuns":${JSON.stringify(this.state.scheduledJobRuns)}`);
if (this.state.cronJobRuns) {
parts.push(`"cronJobRuns":${JSON.stringify(this.state.cronJobRuns)}`);
}
return `{${parts.join(',')}}`;
@@ -574,48 +574,48 @@ export class StateStore {
this.save();
}
// ========== Scheduled Job Methods (cron-style scheduler) ==========
// ========== Cron Job Methods ==========
/** Returns all scheduled jobs keyed by job ID. */
getScheduledJobs(): Record<string, import('./types/scheduler.js').ScheduledJob> {
if (!this.state.scheduledJobs) this.state.scheduledJobs = {};
return this.state.scheduledJobs;
getCronJobs(): Record<string, import('./types/cron.js').CronJob> {
if (!this.state.cronJobs) this.state.cronJobs = {};
return this.state.cronJobs;
}
/** Returns a scheduled job by ID, or null if not found. */
getScheduledJob(id: string): import('./types/scheduler.js').ScheduledJob | null {
return this.state.scheduledJobs?.[id] ?? null;
getCronJob(id: string): import('./types/cron.js').CronJob | null {
return this.state.cronJobs?.[id] ?? null;
}
/** Sets a scheduled job and triggers a debounced save. */
setScheduledJob(id: string, job: import('./types/scheduler.js').ScheduledJob): void {
if (!this.state.scheduledJobs) this.state.scheduledJobs = {};
this.state.scheduledJobs[id] = job;
setCronJob(id: string, job: import('./types/cron.js').CronJob): void {
if (!this.state.cronJobs) this.state.cronJobs = {};
this.state.cronJobs[id] = job;
this.save();
}
/** Removes a scheduled job and triggers a debounced save. */
removeScheduledJob(id: string): void {
if (this.state.scheduledJobs) delete this.state.scheduledJobs[id];
removeCronJob(id: string): void {
if (this.state.cronJobs) delete this.state.cronJobs[id];
this.save();
}
/** Returns all scheduled job runs keyed by run ID. */
getScheduledJobRuns(): Record<string, import('./types/scheduler.js').ScheduledJobRun> {
if (!this.state.scheduledJobRuns) this.state.scheduledJobRuns = {};
return this.state.scheduledJobRuns;
getCronJobRuns(): Record<string, import('./types/cron.js').CronJobRun> {
if (!this.state.cronJobRuns) this.state.cronJobRuns = {};
return this.state.cronJobRuns;
}
/** Sets a scheduled job run (history record) and triggers a debounced save. */
setScheduledJobRun(id: string, run: import('./types/scheduler.js').ScheduledJobRun): void {
if (!this.state.scheduledJobRuns) this.state.scheduledJobRuns = {};
this.state.scheduledJobRuns[id] = run;
setCronJobRun(id: string, run: import('./types/cron.js').CronJobRun): void {
if (!this.state.cronJobRuns) this.state.cronJobRuns = {};
this.state.cronJobRuns[id] = run;
this.save();
}
/** Removes a scheduled job run and triggers a debounced save. */
removeScheduledJobRun(id: string): void {
if (this.state.scheduledJobRuns) delete this.state.scheduledJobRuns[id];
removeCronJobRun(id: string): void {
if (this.state.cronJobRuns) delete this.state.cronJobRuns[id];
this.save();
}