Skip to main content
Traducción. Autoritativo: ../../standards/jobs.md.

QueuePort (categoría 7 de la constitución)

  • Interfaz en packages/core: publish(queue, payload, opts), schedule(queue, payload, runAt). Los payloads son envelopes validados con Zod: { job_id: uuidv7, tenant_id, correlation_id, kind, data }.
  • Binding en el composition root de cada módulo (R21). Adaptador por defecto en F1: Vercel Queues. Vendors nuevos (QStash, etc.): ADR antes del primer import.

Consumidores

  • Idempotencia OBLIGATORIA: verificar e insertar en core.processed_jobs (job_id, consumer, processed_at) dentro de la transacción de trabajo; un duplicado hace ack y salta. Job de limpieza por TTL.
  • Política de reintentos (default de industria, sobreescribible por cola con justificación en el spec del módulo): 5 intentos, backoff exponencial con jitter (base 30 s, tope 1 h).
  • Los reintentos agotados y las fallas duras DEBEN persistirse en core.dead_letters (job_id, queue, payload, attempts, last_error, status: pending_review|replayed|discarded, correlation_id) más alerta a BetterStack. La herramienta de replay vive en Softcrum Ops. Los éxitos de alto volumen son métricas, no filas.
  • Mensajes envenenados: los payloads inválidos de schema van directo a dead_letters (sin reintentos).

Colas de notificación (junto con standards/notifications.md)

  • Una cola por canal por carril: notif.{canal}.transactional y notif.{canal}.marketing.
  • El transaccional SIEMPRE tiene prioridad: los workers de marketing ceden (pausan o drenan) cuando la profundidad transaccional supera el umbral.
  • Rate limiting: token bucket en Upstash por PROVEEDOR (global — por ejemplo, los 10 rps de Resend son por team, a través de TODOS los tenants) y por TENANT (uso justo). Un 429 implica backoff, nunca descartar.
  • Blasts de email: exclusivamente el endpoint batch de Resend (100 por request); NUNCA sincronizar contactos a Resend Audiences (nuestro almacén es la fuente de verdad).

Cron fan-out

  • Patrón de fan-out por tenant (existente) para: pre-creación de particiones, exportación y purga de retención, reconciliación nocturna, recomputes de frescura de datos (tier por entitlement: nocturno/12h/6h/3h/1h), escaneos de points_expiring_soon, snapshots de consumo (cada 30 min).