ChronoTask is a secure, light-weight background job scheduler backend API. Built with Node.js, Express, and SQLite, it allows developers to schedule delayed one-off HTTP callbacks or recurring interval-based HTTP requests.
The system features a continuous background worker queue with crash recovery, exponential backoff retries, and ownership-based multi-user isolation.
- 🔒 Secure authentication & user isolation: Login & registration via JWT and
bcryptpassword hashing. Every scheduled job is locked to the user who created it. - 📧 Input normalization: Automatically normalizes email credentials (case-insensitive & whitespace trimmed) to prevent duplicate accounts and login issues.
- 🛠️ Robust CRUD endpoints: Create, view, list, pause, resume, and cancel/delete jobs. Deleting a job automatically cleans up its execution logs using database cascade triggers.
- 🔄 Custom Background Worker: Polling scheduler checks for due jobs every 5 seconds and executes HTTP requests in parallel using native
Promise.allSettled. - 🛡️ Double-Execution Prevention: Atomically locks jobs by setting status to
runningright before firing requests, ensuring multiple execution ticks don't overlap. - 🔁 Fault Tolerance & Exponential Backoff: Automatically handles failed HTTP calls (network issues or HTTP codes >= 400). It retries with increasing delay intervals:
10 * 2^failure_countseconds. Jobs are marked asfailedpermanently after 5 failed attempts. - 🧹 Startup Crash Recovery: Resets any jobs stuck in
runningstatus back topendingon server reboot. - 💾 Database Protection: Parses header templates safely via
try/catchand slices response bodies to a maximum of 5,000 characters to prevent SQLite bloat.
ChronoTask/
├── src/
│ ├── db.js # Initialises SQLite database and schemas
│ ├── server.js # Entry point for Express server & worker start
│ ├── worker.js # Core background polling loop & retry engine
│ ├── middleware/
│ │ └── auth.js # JWT validation middleware
│ └── routes/
│ ├── auth.js # Registration & login routers
│ └── jobs.js # Job scheduling, log view, and state controls
├── .env # Configuration variables
├── package.json # Node dependencies & scripts
└── README.md # Project documentation
- Clone and navigate to the project directory:
cd ChronoTask - Install dependencies:
npm install
- Configure environment variables:
Create a
.envfile in the root folder with the following contents:PORT=3000 JWT_SECRET=super_secret_chronotask_key_123! DATABASE_URL=chronotask.db
- Run the application:
- For production:
npm start
- For development with auto-reload:
npm run dev
- For production:
- POST
/api/auth/register - Body:
{ "email": "user@example.com", "password": "yourpassword123" } - Response (201 Created):
{ "message": "User registered successfully", "userId": 1 }
- POST
/api/auth/login - Body:
{ "email": "user@example.com", "password": "yourpassword123" } - Response (200 OK):
{ "message": "Login Successfull", "token": "eyJhbGciOiJIUzI1NiIsIn..." }
Note: All /api/jobs endpoints require a Bearer <token> in the Authorization header.
- POST
/api/jobs - Body:
{ "name": "Send Webhook Trigger", "url": "https://httpbin.org/post", "method": "POST", "schedule_type": "interval", "schedule_value": 30, "payload": { "event": "invoice_paid" } } - Response (201 Created):
{ "message": "job scheduled successfully", "job": { "id": 1, "name": "Send Webhook Trigger", "url": "https://httpbin.org/post", "method": "POST", "schedule_type": "interval", "schedule_value": 30, "next_run_at": 1782221234567, "status": "pending" } }
- GET
/api/jobs - Response (200 OK): Returns list of scheduled jobs belonging to the authenticated user.
- GET
/api/jobs/:id/logs - Response (200 OK): Returns chronological list of execution attempts, timestamps, status codes, response sizes, and errors.
- PATCH
/api/jobs/:id/pause - Response (200 OK):
{"message": "Job paused successfully"}
- PATCH
/api/jobs/:id/resume - Response (200 OK):
{"message": "job resumed successfully", "next_run_at": 1782226789012}
- DELETE
/api/jobs/:id - Response (200 OK):
{"message": "Job deleted successfully"}
You can use HTTP clients like Thunder Client or curl to test the API.
- Register & Login: Register a user and sign in to obtain a JWT.
- Schedule: Schedule a job pointing to
https://httpbin.org/getas aonceorintervaltask. - Logs: Let the task run in the background. After the scheduled execution time has passed, fetch the logs via
GET /api/jobs/<job-id>/logsto see the details of the response. - Testing Retries: Schedule a job targeting a broken endpoint (e.g.
http://localhost:9999). Monitor the logs and watch the system retry with exponential delays (10s,20s,40s,80s) before failing permanently. - Secure Isolation: Log in as a separate user and verify that attempting to access, pause, or delete the first user's job ID returns a
404 Not Found or unauthorized.error.
