Scale Commands

Scale commands are server-initiated actions sent to the terminal via the scale_commands table. The terminal receives them in real-time via WebSocket INSERT events.

Command Types

CommandPayloadDescription
push_weight{}Terminal patches scale with current weight and truck info; pass commandId in the PATCH body to auto-complete
pull_state{}Terminal gets scale state and locks itself (displays session info); complete by patching with commandId only
upload_photos{ "orderId": "uuid" }Terminal uploads all camera photos via batch endpoint with commandId → command auto-completes

⚠️ The single-photo endpoint (POST /api/terminal/orders/{orderId}/cameras/{cameraId}/photos) is deprecated — it has no commandId support. Always use the batch endpoint.

Command Status Flow

PENDING → ACKED → COMPLETED
           ↓
         FAILED (if error)

The ACKED step is optional and can be skipped. Commands complete server-side automatically when the terminal includes commandId in the relevant PATCH or upload request.

Processing Guidelines

  1. Idempotency — check command status before executing; handle already-completed commands gracefully
  2. Sequence — each command has scaleSeq; use it to detect missed commands on reconnect
  3. Error handling — if command fails, PATCH with status: "FAILED" and error message
  4. Acknowledgment — optionally ACK before executing

Executing: push_weight

  1. Read current weight and truck info from the scale
  2. Optionally acknowledge: PATCH /api/terminal/scales/{scaleId}/commands/{commandId} with status: "ACKED"
  3. Patch scale state with weight data and commandId:

Endpoint: PATCH /api/terminal/scales/{scaleId}

{
  "commandId": "command-uuid",
  "stableWeight": 25000,
  "truckNumber": "AA1234BB",
  "truckTrailerNumber": "AA5678CC",
  "axis": {
    "axis1": 5000,
    "axis2": 5000,
    "axis3": 5000,
    "axis4": 5000,
    "axis5": 5000
  }
}

Response 200:

{
  "id": "scale-uuid",
  "name": "Scale 1",
  "stableWeight": 25000,
  "truckNumber": "AA1234BB",
  "activeSessionId": "session-uuid",
  "activeSession": {
    "id": "session-uuid",
    "lockedBy": "USER",
    "lockedUntil": "2025-10-27T15:30:00.000Z"
  },
  "latestCommand": {
    "id": "command-uuid",
    "name": "push_weight",
    "status": "COMPLETED"
  }
}

Including commandId automatically marks the command as COMPLETED.

Executing: pull_state

  1. Get scale state: GET /api/terminal/scales/{scaleId}
  2. Lock the terminal UI (display session info)
  3. Complete command by patching with commandId only (no weight fields required):
{ "commandId": "command-uuid" }

Executing: upload_photos

Command payload contains orderId. Terminal should:

  1. Optionally acknowledge the command
  2. Capture photos from all cameras
  3. Upload via batch endpoint — including commandId auto-completes the command:

Endpoint: POST /api/terminal/scales/{scaleId}/orders/{orderId}/photos/batch

commandId: <command-uuid>
cameraId:  <camera-uuid-1>
file:      [binary image 1]
cameraId:  <camera-uuid-2>
file:      [binary image 2]

Acknowledge Command (Optional)

Endpoint: PATCH /api/terminal/scales/{scaleId}/commands/{commandId}

{
  "status": "ACKED",
  "ackedAt": "2025-10-27T15:00:01.000Z"
}