Status: accepted · Date: 2026-11-06 · Related: ADR-0005, ADR-0006
Enforcement: the existing job-runner tests and scripts/jobs-database.test.mjs; each new job adds its own test.
The ARD uses pg-boss on Postgres for the nightly k ≥ 20 aggregation, campaign delivery, report PDF/CSV and list publishing. pg-boss needs a long-lived Node process holding connections and its own schema; a Worker has neither.
Decision
- Use the template's mechanism: a Cron Trigger calls the job runner on a tick, and work that must survive failures goes through the persisted, leased queue of ADR-0006. A worker claims a row with a lease; an expired lease makes the row claimable again; handlers are idempotent.
- No pg-boss, no Cloudflare Queues for these jobs. One queue, in the database we already run, with the tests we already have.
- Varu's jobs are: nightly district aggregation (only districts with ≥ 20 homes, % rounded to 1 point), campaign delivery, report generation and list publishing.
Consequences
- Latency is bounded by the tick interval; none of these jobs is interactive.
- Throughput is modest and enough: the household app sends almost nothing.
- If volume outgrows the tick, Cloudflare Queues or Workflows can replace the transport without changing handlers.