Skip to content
HitFactorAppPublic

About

Demo background-job API used in the Hitfactor autonomous bug-fixing queue video

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

jobs-api

A small background-job service. Clients submit jobs over HTTP, an in-process worker runs them, and clients poll for the result.

  • Node 24, TypeScript (run directly by Node, no build step)
  • Fastify, zod
  • SQLite through the built-in node:sqlite module
  • vitest

Run it

npm install
npm run create-key -- my-laptop     # prints an API key
npm run dev                          # http://localhost:3000
curl -s localhost:3000/v1/jobs \
  -H "x-api-key: $KEY" -H 'content-type: application/json' \
  -d '{"type":"report.generate","payload":{"reportId":"q3","format":"csv"}}'

Test it

npm test          # vitest
npm run typecheck # tsc

API

All /v1 routes except /v1/admin need an X-API-Key header. A key sees only its own jobs.

Method Path Does
POST /v1/jobs Create a job: { type, payload?, priority?, maxAttempts?, runAt? }
POST /v1/jobs/batch Create up to 100 jobs in one transaction: { jobs: [...] }
GET /v1/jobs List jobs, newest first. Query: status, type, limit (1–100), cursor
GET /v1/jobs/:id One job
GET /v1/jobs/:id/events The job's history
POST /v1/jobs/:id/cancel Cancel a queued or running job
POST /v1/jobs/:id/retry Queue a failed job again
GET /health Liveness and database check, no key needed

Admin routes need X-Admin-Token (set ADMIN_TOKEN): POST /v1/admin/api-keys, GET /v1/admin/api-keys, DELETE /v1/admin/api-keys/:id, GET /v1/admin/stats, POST /v1/admin/purge.

Job types

Type Payload
email.send { to, subject, body }
report.generate { reportId, format: "csv" | "pdf", rows? }
webhook.deliver { url, event, body? } (https only)
noop anything

Scheduling and retries

  • runAt is an ISO 8601 timestamp. A timestamp with no offset is read as UTC. The job runs at or after that time.
  • A failed attempt is retried after RETRY_BACKOFF_MS, doubling each time, until the job has made maxAttempts attempts (default DEFAULT_MAX_ATTEMPTS). Then it is failed.
  • Higher priority runs first.

Rate limits

Each API key may make RATE_LIMIT_MAX requests per RATE_LIMIT_WINDOW_MS. Responses carry x-ratelimit-limit and x-ratelimit-remaining; a 429 carries retry-after.

Configuration

Variable Default
PORT 3000
DB_PATH data/jobs.db
ADMIN_TOKEN empty (admin API off)
POLL_INTERVAL_MS 1000
RETRY_BACKOFF_MS 5000
DEFAULT_MAX_ATTEMPTS 3
RATE_LIMIT_WINDOW_MS 60000
RATE_LIMIT_MAX 120
RUN_WORKER true
LOG_LEVEL info

See docs/ARCHITECTURE.md for how the parts fit.

About

Demo background-job API used in the Hitfactor autonomous bug-fixing queue video

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages