Skip to content

Queue Package

@activation-sys/queue — BullMQ workers and queues for async processing, backed by Redis.

Installation

Already included in the monorepo workspace.

ts
import { addActivationJob, startAllWorkers, initializeQueues } from '@activation-sys/queue';

Exports

ts
// Redis connection
export { createConnection, redis, disconnect } from './config/redis.js';

// Queues
export { activationQueue, addActivationJob, getActivationJobCounts };
export { paymentQueue, addPaymentJob, getPaymentJobCounts };
export { notificationQueue, addNotificationJob, getNotificationJobCounts };

// Workers
export { startActivationWorker, stopActivationWorker };
export { startPaymentWorker, stopPaymentWorker };
export { startNotificationWorker, stopNotificationWorker };

// Lifecycle
export async function initializeQueues(options?: {
  startWorkers?: boolean;
  storeProviderManager?: EsimProviderPluginManager;
  onStoreIssued?: OnStoreIssued;
});
export async function shutdownQueues();

Job Types

ActivationJob

ts
{
  type: 'activation',
  activationId: string,
  userId: string,
  operatorSlug: 'stc' | 'mobily' | 'zain',
  step: 'initiate' | 'verify_identity' | 'complete'
}

PaymentJob

ts
{
  type: 'payment',
  paymentId: string,
  orderId: string,
  userId: string,
  gateway: 'stc_pay' | 'apple_pay' | 'mada' | 'visa' | 'mastercard' | 'stripe'
}

NotificationJob

ts
{
  type: 'notification',
  userId: string,
  channel: 'push' | 'sms' | 'email',
  templateId: string,
  data: Record<string, unknown>
}

Queue Configuration

QueueConcurrencyRetriesBackoff StrategyCompleted RetentionFailed Retention
Activation103Custom: 1s → 5s → 30s100 jobs24h / 1000
Payment55Exponential (1s base)500 jobs7 days / 5000
Notification202Exponential (1s base)50 jobs24h / 500

Usage Examples

ts
// Initialize all queues and start workers. Pass the eSIM provider manager
// so store fulfillment starts too — without it the store worker stays off.
// The store worker drives the issuance state machine on esim_store_orders:
// in_flight stamping before every provider call, classified EsimProviderError
// handling, reconcile-instead-of-reissue on ambiguous attempts, and
// pending_verification for async KYC providers.
await initializeQueues({
  startWorkers: true,
  storeProviderManager: esimProviderPluginManager,
  onStoreIssued: sendStoreEsimDeliveryEmail,
});

// Add a job
await addActivationJob({
  type: 'activation',
  activationId: '...',
  userId: '...',
  operatorSlug: 'stc',
  step: 'initiate',
});

// Check job counts
const counts = await getActivationJobCounts();
// { active: 1, completed: 5, failed: 0, delayed: 0, waiting: 2 }

// Graceful shutdown
await shutdownQueues();

Redis Configuration

  • Production: rediss:// with TLS 1.3
  • Each queue gets a dedicated connection with namespace prefix (activation:, payment:, notification:)
  • maxRetriesPerRequest: null required for BullMQ

Internal documentation - Activation System