# Janaah Job Execution System API Documentation ## Overview A job execution system for scheduling and executing HTTP webhooks with MongoDB data integration. Features clean status management, smart retry logic, and comprehensive job monitoring. ## Job Types | Type | Description | Scheduling | Recurrence | |------|-------------|------------|------------| | `once` | Execute once | Immediate or scheduled | No | | `recurrent` | Execute repeatedly | Immediate or scheduled | Every N seconds | ## Job Status System ### Status Flow ``` pending → running → finished ``` ### Finish Reasons - `succeeded` - All runs completed successfully - `failed` - All runs failed (or 3 consecutive failures for recurrent) - `canceled` - Manually canceled - `expired` - Expired before/during execution ## API Endpoints ### Create Job ``` POST /jobs ``` **Basic Job:** ```json { "event": "user_signup", "type": "once", "request": { "url": "https://webhook.site/endpoint", "method": "POST", "headers": { "Authorization": "Bearer token" }, "payload": { "message": "Hello {{user.name}}!", "timestamp": "{{$timestamp}}" }, "use_sources": true, "sources": { "user": { "collection": "users", "match": {"name": "John"}, "fields": ["name", "email"], "single": true } } } } ``` **Scheduled Job:** ```json { "event": "reminder", "type": "once", "scheduled_at": "2025-07-22T15:00:00Z", "expires_at": "2025-07-22T16:00:00Z", "request": { "url": "https://webhook.site/endpoint", "method": "POST", "payload": { "message": "Scheduled reminder" }, "use_sources": false } } ``` **Recurrent Job:** ```json { "event": "daily_report", "type": "recurrent", "every": 86400, "expires_at": "2025-08-01T00:00:00Z", "request": { "url": "https://webhook.site/endpoint", "method": "POST", "payload": { "report_date": "{{$today}}", "timestamp": "{{$timestamp}}" }, "use_sources": false } } ``` **Response:** ```json { "job_id": "abc123", "message": "Job created and will run immediately" } ``` ### List Jobs ``` GET /jobs ``` **Query Parameters:** - `status` - Filter by status (`pending`, `running`, `finished`) - `event` - Filter by event name - `sort_by` - Sort field (`created_at`, `status`, `event`) - `sort_order` - Sort direction (`asc`, `desc`) - `page` - Page number (default: 1) - `limit` - Items per page (default: 10, max: 100) **Examples:** ```bash # Recent failed jobs GET /jobs?status=finished&sort_by=created_at&sort_order=desc # User signup jobs, page 2 GET /jobs?event=user_signup&page=2&limit=20 ``` **Response:** ```json { "jobs": [ { "id": "abc123", "status": "finished", "finish_reason": "succeeded", "created_at": "2025-07-22T01:00:00Z", "runs": [ { "run_id": "xyz789", "status": "completed", "started_at": "2025-07-22T01:00:00Z", "completed_at": "2025-07-22T01:00:01Z", "payload": { "message": "Hello John!", "timestamp": "2025-07-22T01:00:00Z" } } ] } ], "total": 25, "page": 1, "limit": 10, "total_pages": 3 } ``` ### Get Job ``` GET /jobs/:id ``` **Response:** ```json { "id": "abc123", "job_request": { "event": "user_signup", "type": "once", "request": { "url": "https://webhook.site/endpoint", "method": "POST", "payload": { "message": "Hello {{user.name}}!" } } }, "status": "finished", "finish_reason": "succeeded", "created_at": "2025-07-22T01:00:00Z", "is_scheduled": false, "is_recurrent": false, "runs": [ { "run_id": "xyz789", "status": "completed", "started_at": "2025-07-22T01:00:00Z", "completed_at": "2025-07-22T01:00:01Z", "payload": { "message": "Hello John!", "timestamp": "2025-07-22T01:00:00Z" } } ] } ``` ### Cancel Job ``` POST /jobs/cancel/:id ``` **Response:** ```json { "message": "Job abc123 has been canceled" } ``` ### Simulate Request ``` POST /simulate ``` Test request configuration without creating a job. **Request:** ```json { "request": { "url": "https://webhook.site/endpoint", "method": "POST", "payload": { "user": "{{user}}", "timestamp": "{{$timestamp}}" }, "use_sources": true, "sources": { "user": { "collection": "users", "match": {"name": "John"}, "fields": ["name", "email"], "single": true } } } } ``` **Response:** ```json { "user": { "name": "John", "email": "john@example.com" }, "timestamp": "2025-07-22T01:00:00Z" } ``` ## Retry Logic ### Non-Recurrent Jobs - Failed runs are retried up to `MAX_RETRIES` times (default: 2) - Each retry is tracked as a separate run - Job succeeds if any retry succeeds ### Recurrent Jobs - **No retries** - if a run fails, wait for next recurrence - Stops after 3 consecutive failures - Each recurrence generates fresh payload from database ## Special Macros | Macro | Description | Example | |-------|-------------|---------| | `{{$timestamp}}` | Current timestamp (RFC3339) | `2025-07-22T01:00:00Z` | | `{{$uuid}}` | New UUID | `550e8400-e29b-41d4-a716-446655440000` | | `{{$today}}` | Current date | `2025-07-22` | | `{{$randomInt}}` | Random integer (0-999) | `742` | | `{{$randomFloat}}` | Random float (0-1) | `0.8394` | ## MongoDB Sources ### Single Source ```json { "user": { "collection": "users", "match": {"_id": "user123"}, "fields": ["name", "email", "contact:phone,address"], "single": true } } ``` **Usage:** - `{{user}}` - Full object - `{{user.name}}` - Specific field - `{{user.contact.phone}}` - Nested field ### Array Source ```json { "orders": { "collection": "orders", "match": {"userId": "user123"}, "fields": ["_id", "total", "status"], "single": false, "sort": {"createdAt": -1}, "limit": 5 } } ``` **Usage:** - `{{orders}}` - Full array only ## Environment Variables ```env MONGODB_URI=mongodb://localhost:27017/janaah MONGODB_DATABASE=janaah MAX_RETRIES=2 MIN_EVERY=5 MAX_EVERY=86400 DEFAULT_EXPIRES_DURATION=24h PORT=4040 ``` ## Error Responses ```json { "error": "expires_at (2025-07-22T01:00:00Z) must be after scheduled_at (2025-07-22T02:00:00Z)" } ``` ## Examples ```bash # Create immediate job curl -X POST http://localhost:4040/jobs \ -H "Content-Type: application/json" \ -d @tests/job_test.json # List running jobs curl "http://localhost:4040/jobs?status=running" # Get job details curl http://localhost:4040/jobs/abc123 # Cancel job curl -X POST http://localhost:4040/jobs/cancel/abc123 # Test configuration curl -X POST http://localhost:4040/simulate \ -H "Content-Type: application/json" \ -d @tests/correct_config_mongo.json