Part of #106 — decide and prove out where the refresh worker runs, then wire a minimal job end-to-end.
Options (from research)
A. Nitro in-process scheduledTasks. Nitro does fire scheduled tasks on the node-server preset via an in-process croner engine — no external trigger needed (the "doesn't fire on Node" belief is Vercel/Cloudflare-preset-specific). Config via the nitro/vite plugin (experimental.tasks: true + scheduledTasks), tasks in server/tasks/…. Lowest infra.
Downside: a long, rate-limited job shares the web process (memory contention) and is killed with no resume on every web redeploy (Coolify replaces the container; croner does no catch-up).
B. Dedicated Coolify worker. Coolify has built-in container-level Scheduled Tasks (5-field cron). Run the job in a separate worker service (own container, own resource limits, own deploy) — survives web deploys, isolates load, separate logs. Downside: one extra Coolify resource + the job image needs its deps (a reported gotcha: curl: not found in slim images — call node or install curl).
Middle ground: keep the job code as a shared script/package in this repo (our scripts/* already are the worker), housed in the worker container, triggered by Coolify's scheduler.
Recommendation
Given our jobs are GitHub-rate-limited and occasionally multi-minute, lean B (dedicated Coolify worker) for the heavy refresh; Nitro tasks stay fine for light/idempotent jobs. Confirm with a small spike.
Acceptance criteria
References
Part of #106 — decide and prove out where the refresh worker runs, then wire a minimal job end-to-end.
Options (from research)
A. Nitro in-process
scheduledTasks. Nitro does fire scheduled tasks on thenode-serverpreset via an in-process croner engine — no external trigger needed (the "doesn't fire on Node" belief is Vercel/Cloudflare-preset-specific). Config via thenitro/viteplugin (experimental.tasks: true+scheduledTasks), tasks inserver/tasks/…. Lowest infra.Downside: a long, rate-limited job shares the web process (memory contention) and is killed with no resume on every web redeploy (Coolify replaces the container; croner does no catch-up).
B. Dedicated Coolify worker. Coolify has built-in container-level Scheduled Tasks (5-field cron). Run the job in a separate worker service (own container, own resource limits, own deploy) — survives web deploys, isolates load, separate logs. Downside: one extra Coolify resource + the job image needs its deps (a reported gotcha:
curl: not foundin slim images — callnodeor install curl).Middle ground: keep the job code as a shared script/package in this repo (our
scripts/*already are the worker), housed in the worker container, triggered by Coolify's scheduler.Recommendation
Given our jobs are GitHub-rate-limited and occasionally multi-minute, lean B (dedicated Coolify worker) for the heavy refresh; Nitro tasks stay fine for light/idempotent jobs. Confirm with a small spike.
Acceptance criteria
backfill-orgs.tsor the sub-issue-A hot-tier pass) running on the chosen runner on the Coolify box, on a schedule, surviving a web redeployDATABASE_URL/GITHUB_TOKENreach the workerReferences