Scheduled jobs (/admin/scheduled-jobs) is the maintainer behind FunctionId SCHEDULED_JOBS (53). The page title is Scheduled jobs. It replaces origin HTTP crons as the production control plane: a Node worker (BullMQ) runs the jobs; Kubernetes CronJobs or node dist/cli.js run can still fire the same handlers.
Permissions: menu Admin → Scheduled jobs (function.url = scheduled_jobs). View opens the list. Add creates a job for a handler that does not already have an instance. Edit controls schedule, status, and Run now. Delete is only for custom (non-system) jobs. System rows cannot be deleted.
Screen layout
Figure: FoodHub list — checkboxes, Add job, Search..., Filter, Export, bulk bar (Activate / Pause / Disable / Delete), sortable Name, Handler, Status, Schedule, Last run, row ⋮.
List behavior
- Search matches Name or Handler.
- Filter opens a popover (Apply / Reset) with Status and Handler. Status: Active (automatic + manual), Paused (manual only), Disabled (nothing runs). Handler lists the registered codes.
- System jobs are the origin recurrent crons (reminders, due-date notifications, task urgency, price adjustment, concrete quotes, pending data-tracking flags).
- Add job is disabled while every handler already has a row. Delete a custom job (or add a new handler in code) before creating another.
- Checkboxes select every row on the page, including System jobs. The bulk bar (between Filter and the table) offers Activate, Pause, and Disable (Edit) immediately, and Delete (Delete permission) with confirmation.
- Bulk Delete skips system jobs. If the selection is only system rows, nothing is deleted.
- The row ⋮ includes Edit, Run now (unless Disabled), Activate / Pause / Disable for the statuses that are not current, and Delete only when the job is not System.
- Schedule shows the five-field cron and timezone (default
America/New_York).
Create / edit modal
- Name, Cron expression, Timezone, Status.
- Run history lists recent SUCCEEDED / FAILED / RUNNING rows.
- Run now starts one execution immediately if none is already RUNNING.
Production HTTP /cron-* URLs still exist for origin crontab cutover and require CRON_SECRET.