Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.wizpay.xyz/llms.txt

Use this file to discover all available pages before exploring further.

Task System

The task system is the persistence and state management layer for all payment operations. Every operation — payroll, swap, bridge, FX, liquidity — is represented as a Task with associated units, transactions, and logs.

State Machine

Statuses

StatusTerminalDescription
createdNoTask record exists. No processing has begun.
assignedNoRouted to a queue. Awaiting worker pickup.
in_progressNoWorker has picked up the job. Agent is executing.
reviewNoAt least one unit failed. Requires resolution.
approvedNoReview completed. Ready for finalization.
executedYesAll units completed.
partialYesSome units succeeded, some failed.
failedYesTask-level failure.

Transition Rules

created     → assigned | failed
assigned    → in_progress | failed
in_progress → review | executed | partial | failed
review      → approved | failed
approved    → executed | failed
executed    → (terminal)
partial     → (terminal)
failed      → (terminal)
Invalid transitions throw BadRequestException. Same-status transitions are idempotent no-ops.

Status Recomputation

After each TaskUnit report, TaskUnitService.recomputeTaskStatus() derives the next status:
if (failedUnits > 0) return REVIEW;
if (completedUnits === totalUnits) return EXECUTED;
return IN_PROGRESS;

Data Model

Task

Root entity. One per execution request.
FieldTypeNotes
idUUIDAuto-generated
typestringpayroll, swap, bridge, liquidity, fx
statusstringCurrent state machine position
totalUnitsnumberTotal units in this task
completedUnitsnumberUnits that reported SUCCESS
failedUnitsnumberUnits that reported FAILED
metadataJSONNormalized parameters (used for filtering)
payloadJSONRaw input as submitted
resultJSONExecution result (populated on completion)

TaskUnit

A discrete unit of work. For payroll: one batch of recipients. For swap/liquidity: a single step.
FieldTypeNotes
idUUID
taskIdUUIDParent reference
typestringbatch or step
indexnumberOrder within task (0-indexed)
statusstringPENDING, SUCCESS, FAILED
txHashstring?Populated on success
errorstring?Populated on failure
payloadJSONUnit-specific data

TaskTransaction

Tracks individual on-chain transactions. One record per Circle transfer() call.
FieldTypeNotes
idUUID
taskIdUUIDParent reference
txIdstringCircle transaction ID
recipientstringDestination address
amountstringTransfer amount
currencystringToken symbol
statusstringpending, completed, failed
txHashstring?On-chain hash (when confirmed)
errorReasonstring?Failure reason
batchIndexnumberBatch membership
pollAttemptsnumberPoll count

TaskLog

Append-only audit log. Every state transition and significant event produces a log entry.
FieldTypeNotes
idUUID
taskIdUUIDParent reference
levelstringINFO or ERROR
stepstringMachine-readable identifier (e.g., task.created, bridge.completed)
statusstringTask status at time of logging
messagestringHuman-readable description
contextJSON?Structured contextual data

Retry Semantics

BullMQ Level

Task execution jobs:
  • 3 attempts with exponential backoff (1s base, 5s for bridge)
  • On permanent failure: job marked failed, task status set to failed
Transaction poll jobs:
  • 1 BullMQ attempt — the poller manages its own re-enqueue logic
  • Each poll checks Circle API, then either finalizes or re-enqueues with delay
  • Maximum poll attempts enforced by TransactionPollerService

Idempotency

OrchestratorService.executeTask() contains an idempotency guard:
if (task.status !== TaskStatus.ASSIGNED) {
  return null; // already processed or in-progress
}
This means:
  • If BullMQ retries a job that already executed, it is silently skipped.
  • If the worker crashes after marking in_progress, the retry will also skip (status is no longer assigned). Manual intervention is required.
TaskLogService.hasLogStep() provides deduplication at the log level — processors check before writing duplicate log entries.

Error Handling

Task-Level Failure

When an agent throws during execution:
  1. Orchestrator catches the error.
  2. TaskService.updateStatus(taskId, FAILED) is called (best-effort).
  3. If the status update itself fails, a TaskLog entry is written as fallback.
  4. The original error is re-thrown to BullMQ for retry accounting.

Unit-Level Failure

When a TaskUnit is reported as FAILED:
  1. Unit status updated, failedUnits counter incremented.
  2. Task status recomputed — typically transitions to review.
  3. A TaskLog entry is written at ERROR level.

Transaction-Level Failure

When a TaskTransaction poll returns failed:
  1. Transaction record updated with errorReason.
  2. getTransactionAggregation() checks if all transactions are terminal.
  3. If all terminal: task finalized based on completed/failed ratio.

Partial Success

The partial status is a terminal state. It indicates:
  • At least one transfer succeeded (has a txHash).
  • At least one transfer failed (has an errorReason).
  • The task cannot be retried as a whole — individual failed transfers require manual intervention or a new task.
Aggregation logic:
All completedAll failedMixedAny pending
executedfailedpartialin_progress