Saltar a contenido

PDF-012G - Outbox Worker Readiness

Marcador operativo: PDF-012G OUTBOX WORKER READINESS.

Objetivo

Preparar el readiness operativo del worker de outbox para produccion controlada, sin activarlo automaticamente.

Este gate deja documentado y validable un worker manual/controlado, con allowlist interna, rate-limit persistente candidate, idempotencia, manejo de errores, retry policy y observabilidad minima.

Estado actual del flujo

  • PDF-012F ya documento el envio real unico autorizado desde outbox local/dev.
  • La notification sintetica PDF-012D:BILLING_CUSTOMER_REQUEST:TEST001 quedo en SENT.
  • El reintento quedo bloqueado como ALREADY_SENT_BLOCKED, sin duplicar envio.
  • PDF-012G no reabre envio: solo lee outbox, genera snapshot sanitizado y evalua readiness.

Readiness GO/NO-GO

  • Readiness contractual: GO si la lectura local/dev confirma DB esperada, usuario esperado, transaccion read-only, sin recipients fuera de allowlist, sin tipos no permitidos y sin duplicados de idempotencia.
  • Envio manual real: NO-GO por diseno en este gate.
  • manual_send_go=false hasta un gate posterior con autorizacion explicita separada.

Allowlist

Destinatarios internos iniciales:

  • facturacion@ladirecta.com.ar
  • operaciones@ladirecta.com.ar

Tipo permitido:

  • BILLING_CUSTOMER_REQUEST

Rate-limit

Politica definida para readiness:

  • maximo 1 envio por notification_id;
  • maximo 1 envio por idempotency_key;
  • limite futuro por minuto antes de cualquier scheduler;
  • limite futuro por hora antes de cualquier scheduler;
  • bloqueo si recipient no esta permitido;
  • bloqueo si status ya es SENT;
  • bloqueo si send_blocked_by_default=true y no existe confirmacion manual posterior.

Idempotencia

El worker real futuro debe bloquear cualquier reintento cuando:

  • notification_id ya tenga evento exitoso;
  • idempotency_key ya tenga envio exitoso;
  • la outbox este en SENT;
  • exista decision ALREADY_SENT_BLOCKED;
  • exista decision RETRY_BLOCKED vigente.

Estados operativos

  • READY_BLOCKED
  • SEND_ELIGIBLE_BUT_BLOCKED
  • SEND_APPROVED_MANUAL
  • SENT
  • FAILED
  • RETRY_BLOCKED
  • ALREADY_SENT_BLOCKED

Error handling

Errores previstos:

  • SMTP_AUTH_FAILED: bloquear reintento hasta revalidar secret SMTP.
  • SMTP_TIMEOUT: permitir retry manual con rate-limit.
  • RECIPIENT_BLOCKED: bloquear hasta cambio de allowlist.
  • ALREADY_SENT: bloquear definitivamente.
  • TEMPLATE_MISSING: bloquear hasta corregir template.
  • PAYLOAD_INVALID: bloquear hasta corregir payload.
  • RATE_LIMIT_EXCEEDED: bloquear hasta cierre de ventana.

Retry policy

  • Default: retry manual solo despues de revisar error.
  • Auth SMTP fallida: RETRY_BLOCKED.
  • Timeout SMTP: retry manual rate-limited.
  • Recipient bloqueado: sin retry.
  • Ya enviado: sin retry.
  • Template faltante: sin retry hasta fix.
  • Payload invalido: sin retry hasta fix.
  • Rate-limit excedido: retry bloqueado hasta nueva ventana.

Observabilidad minima

El snapshot sanitizado debe incluir:

  • conteo de pendientes;
  • conteo de bloqueadas;
  • conteo de enviadas;
  • conteo de fallidas;
  • ultimo evento por notification;
  • ultimo error sanitizado;
  • confirmacion de no secrets.

Output local esperado:

  • tmp/pdf-012g/outbox_worker_readiness_snapshot.json
  • tmp/pdf-012g/outbox_worker_readiness_snapshot.txt

Que NO se hizo

  • No se enviaron emails reales.
  • No se ejecuto --confirm-send.
  • No se conecto SMTP para envio.
  • No se activo worker real persistente.
  • No scheduler.
  • No cron.
  • No runtime automatico.
  • No pipeline.
  • No WooCommerce API.
  • No SGC write.
  • No se usaron datos reales de clientes.
  • No secrets ni passwords impresos.
  • No se toco VPS/prod con datos.
  • No hubo SQL write local/dev en esta preparacion.

Proximo paso hacia produccion

Crear un gate posterior para operacion manual controlada del worker real: aprobar SEND_APPROVED_MANUAL, ejecutar una sola notification interna permitida, auditar resultado, mantener idempotencia y validar rollback logico. Scheduler, cron y runtime automatico siguen bloqueados hasta un gate posterior independiente.