---
name: queue-worker
description: Add a background job via BullMQ (Node) or Hangfire (.NET). Use for async/scheduled work.
---

# Skill: Queue Worker

## When to use

Work that must not block the request: emails, exports, audit shipping, scheduled jobs.

## Pattern (BullMQ — the default)

- **Producer** (any API host): a `Dispatcher` that `queue.add(name, data, opts)`.
- **Consumer** (`apps/worker-nest`): a `Worker(queueName, processor, { connection, concurrency })`.

## Steps

1. Define the job payload type in the owning enterprise-module (`em-audit`, `em-notifications`, or a new one).
2. Producer enqueues with retry opts (`attempts`, exponential `backoff`, `removeOnComplete`).
3. Add a `Processor` in `apps/worker-nest/src/processors/`.
4. Wire it into `worker-nest/src/app.module.ts`.

## Gotchas

- `maxRetriesPerRequest: null` on the ioredis connection — BullMQ requires it.
- Make processors **idempotent** — a job can run more than once (at-least-once delivery).
- Set `removeOnComplete`/`removeOnFail` ages or Redis fills up.
- Never throw raw — failed jobs retry; log context for debugging.
- The producer must never block on enqueue failure (audit pattern: log + swallow).

## Validation

Enqueue → worker processes; retries on failure; idempotent on double-run; Redis not growing unbounded.
