Job Queue
Every printable item in PrintStudio is a job. Jobs flow through a typed state machine enforced by BullMQ workers. There are 49 typed transitions across 8 states.
State Machine
Section titled “State Machine”CREATED │ ▼VALIDATED ──────────────────────────────────────────────► CANCELLED │ ▲ ▼ │SLICED (any state) │ ▼QUEUED │ ▼PRINTING ──────► FAILED ──────► (retry: back to QUEUED) │ ▼POST_PROCESS │ ▼READY │ ▼SHIPPEDState Descriptions
Section titled “State Descriptions”| State | Description | Next |
|---|---|---|
CREATED | Job record created from order line item | VALIDATED, CANCELLED |
VALIDATED | Inventory checked, parameters verified | SLICED, CANCELLED |
SLICED | G-code generated by OrcaSlicer | QUEUED |
QUEUED | Waiting for printer assignment | PRINTING, CANCELLED |
PRINTING | Active on a machine | POST_PROCESS, FAILED |
POST_PROCESS | Cooling, de-supporting, finishing | READY |
READY | Complete, awaiting fulfilment | SHIPPED |
SHIPPED | Tracking number assigned | — |
FAILED | Error occurred | QUEUED (retry) or CANCELLED |
CANCELLED | Cancelled by operator or customer | — |
BullMQ Queues
Section titled “BullMQ Queues”Six BullMQ queues drive state transitions:
| Queue | Worker | Transition |
|---|---|---|
validation | Checks inventory + params | CREATED → VALIDATED |
slicing | Runs OrcaSlicer CLI | VALIDATED → SLICED |
routing | AutoPilot assigns printer | SLICED → QUEUED |
printing | Sends G-code, monitors progress | QUEUED → PRINTING → POST_PROCESS |
post-process | Timer-based cooling/finishing | POST_PROCESS → READY |
shipping | Creates shipment, gets tracking | READY → SHIPPED |
All queues are defined in packages/core/src/queues/.
Managing Jobs
Section titled “Managing Jobs”Queue Dashboard
Section titled “Queue Dashboard”The operator dashboard at /dashboard shows the full job board. Sort by state, printer, SKU, or ETA.
Via API
Section titled “Via API”# List all active jobscurl http://localhost:8787/api/jobs?status=printing,queued \ -H "X-API-Key: your-api-key"
# Get a specific jobcurl http://localhost:8787/api/jobs/{jobId} \ -H "X-API-Key: your-api-key"
# Manually release a queued job to a specific printercurl -X POST http://localhost:8787/api/jobs/{jobId}/release \ -H "Content-Type: application/json" \ -H "X-API-Key: your-api-key" \ -d '{ "printerId": "printer-uuid" }'
# Cancel a jobcurl -X POST http://localhost:8787/api/jobs/{jobId}/cancel \ -H "X-API-Key: your-api-key"Via AutoPilot API
Section titled “Via AutoPilot API”# Reprioritise a job (higher number = higher priority)curl -X POST http://localhost:8787/api/orchestrator/reprioritize \ -H "Content-Type: application/json" \ -H "X-API-Key: your-api-key" \ -d '{ "jobId": "job-uuid", "priority": 10 }'
# Pause all automationcurl -X POST http://localhost:8787/api/orchestrator/pause \ -H "X-API-Key: your-api-key"
# Get queue healthcurl http://localhost:8787/api/orchestrator/status \ -H "X-API-Key: your-api-key"Retry Policy
Section titled “Retry Policy”Failed jobs are automatically retried by the AutoPilot:
- Max retries: 3 (configurable via
PUT /api/orchestrator/config) - Backoff: exponential — 1 min, 5 min, 25 min
- Re-routing: on each retry, the router attempts a different printer
- Escalation: after all retries exhausted, operator is notified via OpenClaw and email
Batch Optimisation
Section titled “Batch Optimisation”The AutoPilot runs a batch optimisation pass every 2 minutes. It groups queued jobs by material and machine type and sends compatible jobs to the same printer in sequence, reducing filament change time.