Appearance
Referencia de Código
◄ Anterior: Troubleshooting | Índice
Tabla de Contenidos
Archivos Clave
Value Objects
/var/www/Bautista/server/Core/ValueObjects/BackgroundJob.php/var/www/Bautista/server/Core/ValueObjects/Notification.php
Interfaces
/var/www/Bautista/server/Core/Interfaces/JobHandlerInterface.php
Repositorios
/var/www/Bautista/server/Core/Repositories/JobRepository.php/var/www/Bautista/server/Core/Repositories/NotificationRepository.php
Servicios
/var/www/Bautista/server/Core/Services/JobDispatcher.php/var/www/Bautista/server/Core/Services/JobExecutor.php/var/www/Bautista/server/Core/Services/NotificationService.php
Controllers
/var/www/Bautista/server/Core/Controllers/JobController.php/var/www/Bautista/server/Core/Controllers/JobStreamController.php(Fase 2)
Handlers (Ejemplos)
/var/www/Bautista/server/Ventas/Handlers/BatchInvoicingJobHandler.php
Routes
/var/www/Bautista/server/Routes/Core/jobs.php
CLI
/var/www/Bautista/server/cli/background-worker.php/var/www/Bautista/server/cli/bootstrap-cli.php/var/www/Bautista/server/cli/cleanup-stale-jobs.php/var/www/Bautista/server/cli/cleanup-old-jobs.php
Migraciones
/var/www/Bautista/server/migrations/tenancy/202602XX_create_background_jobs_table.php/var/www/Bautista/server/migrations/tenancy/202602XX_create_notifications_table.php/var/www/Bautista/server/migrations/tenancy/202602XX_create_pg_notify_function.php(Fase 2)
Configuración
/var/www/Bautista/server/config/dependencies.php- DI container setup/var/www/Bautista/server/config/features.php- Feature flags
Tests
/var/www/Bautista/server/Tests/Unit/Core/JobDispatcherTest.php/var/www/Bautista/server/Tests/Unit/Core/JobExecutorTest.php/var/www/Bautista/server/Tests/Unit/Core/JobRepositoryTest.php/var/www/Bautista/server/Tests/Unit/Ventas/BatchInvoicingJobHandlerTest.php/var/www/Bautista/server/Tests/Integration/Core/BackgroundJobsFlowTest.php
Convenciones
Estados de Job
| Estado | Descripción | Transiciones Permitidas |
|---|---|---|
pending | Job creado, en cola | → running |
running | Job ejecutándose | → completed, failed |
completed | Job terminó exitosamente | (final) |
failed | Job falló con error | (final) |
Reglas:
- ✅ pending → running: Cuando worker inicia
- ✅ running → completed: Cuando handler retorna sin exception
- ✅ running → failed: Cuando handler lanza exception
- ❌ completed → running: NUNCA (job no se re-ejecuta)
- ❌ failed → pending: NUNCA (retry manual = crear nuevo job)
Tipos de Notificación
| Tipo | Uso | Color UI |
|---|---|---|
success | Job completado exitosamente | Verde |
error | Job falló | Rojo |
info | Información general (ej: job iniciado) | Azul |
Convenciones de mensaje:
- success: "Operación completada: {resumen del resultado}"
- error: "Operación falló: {mensaje de error}"
- info: "Operación iniciada: {descripción del job}"
Nomenclatura de Handlers
Patrón: {Module}{Operation}JobHandler
Ejemplos:
BatchInvoicingJobHandler- Facturación masivaReportGenerationJobHandler- Generación de reportesDataImportJobHandler- Importación de datosExternalSyncJobHandler- Sincronización externa
Tipos de job (snake_case):
batch_invoicingreport_generationdata_importexternal_sync
Logging
Formato structured logging:
php
$logger->info('Job dispatched', [
'job_id' => $jobId,
'job_type' => $type,
'user_id' => $userId,
'schema' => $schema,
]);
$logger->info('Job started', [
'job_id' => $jobId,
'job_type' => $job->type,
]);
$logger->info('Job completed', [
'job_id' => $jobId,
'job_type' => $job->type,
'execution_time_seconds' => $job->getExecutionTime(),
]);
$logger->error('Job failed', [
'job_id' => $jobId,
'job_type' => $job->type,
'error' => $job->error,
]);Archivo de log: /logs/background-jobs.log
Log rotation:
bash
# /etc/logrotate.d/background-jobs
/var/log/background-jobs.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
}Patterns Utilizados
Strategy Pattern
Uso: JobHandlerInterface
Permite agregar nuevos tipos de jobs sin modificar JobExecutor. Cada handler implementa la interface y se registra en el executor.
Beneficio: Open/Closed Principle - abierto a extensión, cerrado a modificación.
Repository Pattern
Uso: JobRepository, NotificationRepository
Abstrae el acceso a datos. Los servicios NO conocen detalles de SQL, solo operan con entidades.
Beneficio: Separación de concerns, fácil testing con mocks.
Value Objects
Uso: BackgroundJob, Notification
Entidades inmutables que representan conceptos de dominio con validación incorporada.
Beneficio: Type safety, domain model claro.
Wrapper Pattern
Uso: Handlers envuelven services existentes
Handler NO modifica service. Reconstruye DTOs y delega al service sin cambios.
Beneficio: CERO impacto en código legacy, rollback instantáneo con feature flag.
Referencias Externas
ADRs Relacionados
- ADR: Background Jobs Architecture - Decisiones arquitecturales
Documentación de Arquitectura
- Architecture: Background Jobs - Conceptos y opciones evaluadas
- Architecture: Multi-Tenant - Schema-based tenancy
- Backend: 5-Layer Architecture - Arquitectura general
Documentación Externa
- Server-Sent Events (SSE) Spec
- PostgreSQL NOTIFY/LISTEN
- PHP exec() Documentation
- RabbitMQ PHP Tutorial (para Fase 4)
Comandos Útiles
Ejecutar Worker Manualmente
bash
php cli/background-worker.php {job_id}Cleanup Jobs Antiguos
bash
php cli/cleanup-old-jobs.phpCleanup Jobs Stale
bash
php cli/cleanup-stale-jobs.phpVerificar Jobs Pendientes
sql
SELECT COUNT(*) FROM background_jobs WHERE status = 'pending';Verificar Jobs Running
sql
SELECT * FROM background_jobs WHERE status = 'running';Verificar Notificaciones No Leídas
sql
SELECT COUNT(*) FROM notifications WHERE is_read = FALSE;Feature Flags
Ubicación: config/features.php
php
return [
'background_jobs' => [
'enabled' => getenv('FEATURE_BACKGROUND_JOBS') === 'true',
'max_pending_per_user' => (int) (getenv('MAX_PENDING_JOBS') ?: 10),
],
];Variables de entorno:
FEATURE_BACKGROUND_JOBS: Activar/desactivar sistema (default: false)MAX_PENDING_JOBS: Límite de jobs pendientes por usuario (default: 10)
Última Actualización: 2026-02-05 Versión: 1.0 (Fase 1 - MVP con Polling)