Skip to main content

Scheduler

The scheduler (lib/scheduler.ts) provides cron-based job automation. Jobs are stored in the database and execute registered actions on a schedule.

How It Works

Boot

scheduler.start()

Load enabled jobs from DB

For each job:
Schedule with node-cron

On cron trigger:
Create jobRun record (status: running)

actionRegistry.execute(actionType, actionPayload)

Update jobRun (status: success/error)
Update job.lastRunAt, job.nextRunAt

Scheduler API

import { scheduler } from "@/lib/scheduler";

// Start the scheduler (load and schedule all enabled jobs)
await scheduler.start();

// Stop all scheduled jobs
scheduler.stop();

// Schedule a new job
scheduler.scheduleJob(jobId, cronExpression, actionType, actionPayload);

// Execute a job immediately (bypasses cron schedule)
await scheduler.executeJob(jobId);

// Pause a specific job
scheduler.pauseJob(jobId);

// Resume a paused job
scheduler.resumeJob(jobId);

Cron Expressions

Standard cron syntax with 5 fields:

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *

Examples:

ExpressionDescription
0 * * * *Every hour
*/5 * * * *Every 5 minutes
0 6 * * *Daily at 6 AM
0 0 * * 1Every Monday at midnight
0 8,20 * * *At 8 AM and 8 PM

Job Run Tracking

Every execution creates a jobRuns record:

{
jobId: "uuid",
status: "success", // "running" | "success" | "error"
output: { ... }, // Action result (JSON)
error: null, // Error message if failed
startedAt: "2024-01-15T06:00:00Z",
finishedAt: "2024-01-15T06:00:02Z"
}

REST API

MethodPathDescription
GET/api/jobsList all cron jobs
POST/api/jobsCreate a new job
PATCH/api/jobs/[id]Enable/disable a job
POST/api/jobs/[id]/runExecute job immediately
GET/api/jobs/[id]/runsGet execution history

Create a Job

curl -X POST http://localhost:3000/api/jobs \
-H "Content-Type: application/json" \
-d '{
"name": "Morning Weather",
"schedule": "0 6 * * *",
"actionType": "get_weather",
"actionPayload": { "location": "San Francisco" },
"enabled": true
}'

Execute Immediately

curl -X POST http://localhost:3000/api/jobs/{id}/run