Module: scheduler

Cron-based test run scheduler (ENH-006).

Manages one node-cron task per project schedule. Tasks are stored in a process-local Map keyed by projectId. On startup the server calls initScheduler which loads every enabled schedule from the DB and arms each cron task. When a project's schedule is created, updated, or toggled, the caller invokes reloadSchedule to apply the change without a process restart.

Firing logic

When a cron task fires it behaves identically to POST /api/projects/:id/run:

  • Loads the project and its approved tests from the DB.
  • Skips if an active run is already in progress (prevents double-runs).
  • Creates a test_run run record and hands off to runWithAbort.
  • Records lastRunAt / nextRunAt via scheduleRepo.updateRunTimes().
  • Logs a scheduled_run.start activity entry.

Exports

  • initScheduler — Load all enabled schedules at startup.
  • reloadSchedule — Upsert a single project's task (create/update/toggle).
  • stopSchedule — Cancel and remove a task (project deleted).
  • getNextRunAt — Compute the ISO next-fire time for a cron expression.
Source:

Members

(inner) _staleDetectionTask :Object|null

Weekly stale test detection task (AUTO-013).

Type:
  • Object | null
Source:

(inner, constant) _tzFormatters

Extract date/time components from a UTC timestamp in a given IANA timezone.

Uses Intl.DateTimeFormat.formatToParts() — the spec-guaranteed approach for timezone-aware field extraction. Unlike the toLocaleString round-trip (new Date(d.toLocaleString("en-US", { timeZone }))), this does not depend on locale-specific date string formatting or parsing, and handles DST transitions correctly (spring-forward gaps, fall-back overlaps).

Source:

(inner, constant) tasks :Map.<string, Object>

projectId → node-cron ScheduledTask

Type:
  • Map.<string, Object>
Source:

Methods

(static) activeTaskCount() → {number}

Return the number of currently active (armed) cron tasks. Exposed for the /api/system health endpoint.

Source:
Returns:
Type
number

(static) getNextRunAt(cronExpr, timezoneopt) → {string|null}

Compute the next fire time for a cron expression in a given timezone. Returns an ISO 8601 string or null if the expression is invalid.

We use a lightweight approach: advance minute-by-minute from now (max 1 year) until the cron fields match. For common schedules this resolves in at most 525,960 steps, typically far fewer. A real cron-parser library would be cleaner but avoids a new dependency.

Timezone conversion uses Intl.DateTimeFormat.formatToParts() — the spec-guaranteed approach that correctly handles DST transitions.

Parameters:
Name Type Attributes Description
cronExpr string

5-field cron expression.

timezone string <optional>

IANA timezone (defaults to "UTC").

Source:
Returns:
Type
string | null

(static) initScheduler()

Load all enabled schedules from the database and arm cron tasks. Also starts the weekly stale test detection job (AUTO-013). Called once from index.js after DB init.

Source:

(static) reloadSchedule(projectId)

Reload a single project's cron task after a schedule create/update/toggle. Fetches the latest schedule from the DB and re-arms the task.

Parameters:
Name Type Description
projectId string
Source:

(static) stopAllTasks()

Stop and remove all active cron tasks. Called during graceful shutdown so no new scheduled runs fire while in-flight work is draining.

Source:

(static) stopSchedule(projectId)

Stop and remove the task for a project. Called when a project is deleted so the cron task doesn't fire against a non-existent project.

Parameters:
Name Type Description
projectId string
Source:

(inner) armTask(schedule)

Arm (or re-arm) a cron task for a project schedule. If the schedule is disabled or has an invalid cron expression, the task is cancelled and removed.

Parameters:
Name Type Description
schedule Object

Schedule row from scheduleRepo

Source:

(inner) cancelTask(projectId)

Cancel and remove an existing task for a project (if any).

Parameters:
Name Type Description
projectId string
Source:

(async, inner) fireScheduledRun(projectId)

Execute a test run for a project as triggered by a cron schedule. Mirrors the logic in POST /api/projects/:id/run.

Parameters:
Name Type Description
projectId string
Source: