Skip to content

Queue Jobs

Background work is processed by the BullMQ worker service (services/worker). The API enqueues jobs; the worker processes them independently.

Queues

Queue nameConstantPurpose
invoice-processingQUEUE_NAMES.INVOICE_PROCESSINGOCR extraction for uploaded invoices
email-syncQUEUE_NAMES.EMAIL_SYNCIMAP inbox polling to import invoices
automationQUEUE_NAMES.AUTOMATIONPer-user automation triggers
webhook-deliveryQUEUE_NAMES.WEBHOOK_DELIVERYDeliver webhook payloads to subscriber URLs

Job data interfaces

typescript
// invoice-processing
interface InvoiceProcessingJobData {
  invoiceId: string
  tenantId: string
}

// email-sync
interface EmailSyncJobData {
  tenantId: string
}

// automation
interface AutomationJobData {
  tenantId: string
  tenantUserId: string
}

// webhook-delivery
interface WebhookDeliveryJobData {
  webhookId: string
  webhookDeliveryId: string
  tenantId: string
  event: string
  url: string
  secret: string | null
  payload: Record<string, unknown>
}

Invoice processing flow

  1. Worker receives InvoiceProcessingJobData from the invoice-processing queue
  2. Downloads the invoice file from RustFS using the presigned URL
  3. Sends the image to Google Cloud Vision API for OCR text extraction
  4. Passes the OCR text to OpenAI for structured data extraction (amount, date, invoice number, etc.)
  5. Updates the Invoice record in the database with the extracted fields
  6. Sets invoice.status to processed (or error if any step fails)

Webhook delivery flow

  1. An API event (e.g. entry.approved) fires — the webhook service looks up active subscriptions for the event
  2. Creates a WebhookDelivery record and enqueues a webhook-delivery job
  3. Worker POSTs the payload to the subscriber's URL
  4. If a secret is set, signs the payload with HMAC-SHA256 and includes the signature in the X-Signature-256 header
  5. Updates WebhookDelivery with the response status and duration

Retry behaviour

Jobs are retried with exponential backoff on failure. Failed jobs remain in the queue's failed list and can be inspected or retried via the BullMQ dashboard (if configured).

TT Time Tracker — Internal Documentation