Skip to content

Background Jobs - Architecture Decision Records

Sistema: Background Jobs System Fecha: 2026-02-05 Estado: Aprobado

Documentos relacionados:


Índice de ADRs

Este directorio contiene las decisiones arquitectónicas clave para el sistema de Background Jobs de Sistema Bautista.

ADR-001: Ejecución con exec() + CLI Worker

Estado: ✅ Aprobado Área: Ejecución de Jobs

Decisión: Usar exec() + proceso PHP CLI para ejecutar jobs en background.

Resumen: Evaluamos múltiples opciones para ejecutar jobs de larga duración sin bloquear requests HTTP. Seleccionamos exec() + CLI worker por su simplicidad, compatibilidad universal y bajo overhead operacional. Descartamos pcntl_fork, ReactPHP/Amphp y Swoole/RoadRunner por limitaciones de compatibilidad, complejidad o requisito de cambio de runtime.

Impacto:

  • Request HTTP retorna inmediatamente (< 200ms)
  • Jobs pueden ejecutar 30+ minutos sin timeouts
  • Sin dependencias externas
  • Límite de ~50-100 jobs concurrentes

ADR-002: Tablas por Schema (Multi-Tenant)

Estado: ✅ Aprobado Área: Multi-Tenancy, Seguridad

Decisión: Crear tabla background_jobs en CADA schema de sucursal (LEVEL_SUCURSAL).

Resumen: Sistema Bautista usa PostgreSQL schema-based multi-tenancy. La tabla background_jobs debe respetar este aislamiento para prevenir violaciones de seguridad. Seleccionamos LEVEL_SUCURSAL (tabla por schema) sobre tabla única con filtros o Row Level Security para garantizar aislamiento por diseño.

Impacto:

  • Aislamiento completo entre sucursales
  • Consistente con arquitectura existente
  • Sin riesgo de data leakage por queries incorrectas
  • Queries consolidadas requieren UNION cross-schema

Relacionado: ADR-005


ADR-003: Polling HTTP → SSE (Fases)

Estado: ✅ Aprobado (Fase 1 implementándose) Área: Frontend, UX, Notificaciones

Decisión: Implementar notificación de jobs en 2 fases:

  1. Fase 1 (MVP): Polling HTTP cada 2 segundos
  2. Fase 2 (Optimización): Server-Sent Events + PostgreSQL NOTIFY

Resumen: Evaluamos 4 opciones de notificación (polling, SSE, WebSockets, Push). Seleccionamos enfoque por fases: polling para MVP rápido (2-3 semanas), SSE para optimización futura (latencia < 200ms). Descartamos WebSockets (complejidad sin beneficio) y Push Notifications (limitaciones desktop).

Impacto:

  • Fase 1: MVP funcional en 2-3 semanas, latencia 2-5s
  • Fase 2: Latencia near real-time 50-200ms
  • Progressive enhancement sin breaking changes

ADR-004: Wrapper Pattern (NO Refactoring)

Estado: ✅ Aprobado Área: Arquitectura, Services, Handlers

Decisión: Usar Wrapper Pattern para agregar ejecución asíncrona a services existentes SIN modificarlos.

Resumen: Queremos ejecutar servicios existentes (ej: FacturaService::batchInvoice()) en background sin refactorizarlos. Seleccionamos Wrapper Pattern: handler recibe service como dependencia, reconstruye DTO y delega ejecución. Descartamos refactorizar service (riesgo de bugs) o invertir dependencias (viola arquitectura).

Impacto:

  • CERO impacto en código legacy
  • Service funciona en modo sync (controller) y async (handler)
  • Rollback instantáneo con feature flag
  • Leve duplicación (construcción de DTO)

ADR-005: Schema Isolation en Background (CRÍTICO)

Estado: ✅ Aprobado Área: Multi-Tenancy, Seguridad Severity: 🔴 CRÍTICO

Decisión: Guardar schema en job y configurar search_path ANTES de ejecutar handler.

Resumen: Worker CLI NO tiene request HTTP ni X-Schema header. Si no configuramos schema, worker ejecuta en schema DEFAULT = violación crítica de multi-tenancy. Seleccionamos guardar schema en payload de job y configurar search_path antes de ejecutar. Mitigaciones obligatorias: exception si schema faltante, tests de integración multi-tenant, code review checklist.

Impacto:

  • Aislamiento garantizado por diseño
  • Handler transparente (no necesita código multi-tenant)
  • Tests detectan violación de aislamiento
  • Exception si schema faltante (fail-safe)

Relacionado: ADR-002


Referencias Cruzadas

Por Área

Multi-Tenancy & Seguridad:

Ejecución & Performance:

Frontend & UX:

Lectura Recomendada

Para implementar un nuevo job handler:

  1. ADR-004: Wrapper Pattern - Patrón de implementación
  2. ADR-005: Schema Isolation - Seguridad multi-tenant (CRÍTICO)

Para entender arquitectura general:

  1. ADR-001: Ejecución con exec() - Cómo se ejecutan jobs
  2. ADR-002: Tablas por Schema - Modelo de datos
  3. ADR-003: Polling → SSE - Notificaciones frontend

Última Actualización: 2026-02-05 Próxima Revisión: Después de implementar Fase 1 (recopilar feedback y ajustar ADRs)