Saltar a contenido

Workflow: SupplierProductChange

Resumen

Implementación de Laravel Workflow para orquestar el proceso de cambios en SupplierProduct. El workflow centraliza y secuencia las operaciones que ocurren cuando cambian atributos de un producto de proveedor (precio, stock, contenido, ofertas).

Problema que resuelve

Anteriormente, cuando un SupplierProduct cambiaba múltiples atributos simultáneamente, se despachaban múltiples jobs de forma independiente:

SupplierProduct cambia precio + stock
        │
        ├──► CalculatePricesJob
        ├──► EvaluateSelectedSupplierProductJob
        └──► Múltiples sincronizaciones duplicadas

Problemas: - Sincronizaciones duplicadas por cambios compuestos - Falta de secuencia garantizada entre procesos - Difícil trazabilidad y auditoría - Sin consolidación de cambios

Solución implementada

Un único workflow que orquesta todo el proceso:

SupplierProduct cambia
        │
        ▼
┌─────────────────────────────────────┐
│   SupplierProductChangeWorkflow     │
├─────────────────────────────────────┤
│ 1. CalculatePricesActivity          │  ← Solo si cambió precio/oferta
│ 2. GenerateContentActivity          │  ← Solo si cambió contenido (CL)
│ 3. EvaluateSelectedActivity         │  ← Siempre
│ 4. DispatchSyncActivity             │  ← Solo si es necesario sincronizar
└─────────────────────────────────────┘
        │
        ▼
   Jobs de sync independientes
   (Medusa, WooCommerce, etc.)

Archivos creados

app/Workflows/SupplierProductChange/
├── SupplierProductChangeWorkflow.php       # Workflow principal
└── Activities/
    ├── CalculatePricesActivity.php         # Calcula precios del SupplierProduct
    ├── GenerateContentActivity.php         # Genera contenido IA (solo CL, PC-/PCM-)
    ├── EvaluateSelectedActivity.php        # Evalúa selección de proveedor
    └── DispatchSyncActivity.php            # Despacha jobs de sync a canales

Archivos modificados

Archivo Cambio
config/workflows.php Agregado feature flag supplier_product_change_workflow
app/Services/Sync/Evaluation/SupplierProductEvaluationStrategy.php Integración con workflow via feature flag
.env Variable WORKFLOW_SUPPLIER_PRODUCT_CHANGE=true

Configuración

Activar el workflow

# En .env
WORKFLOW_SUPPLIER_PRODUCT_CHANGE=true

Desactivar (volver a jobs tradicionales)

# En .env
WORKFLOW_SUPPLIER_PRODUCT_CHANGE=false

Tipos de cambio detectados

Constante Valor Descripción
CHANGE_PRICE price Cambio en regular_price o special_price
CHANGE_STOCK stock Cambio en total_stock
CHANGE_CONTENT content Cambio en name, short_description, long_description
CHANGE_OFFER offer Cambio en offer_start o offer_end
CHANGE_REASSIGNMENT reassignment Cambio en id_product_item

Flujo de ejecución

Paso 1: CalculatePricesActivity

  • Condición: Solo si detectó cambio de price u offer
  • Acción: Ejecuta $supplierProduct->calculateAndStorePrices()
  • Resultado: Precios calculados y almacenados

Paso 2: GenerateContentActivity

  • Condición: Solo si detectó cambio de content
  • Validaciones adicionales:
  • El proveedor debe ser CL (Compulandia)
  • El SKU debe comenzar con PC- o PCM-
  • Acción: Despacha GenerateProductContentJob
  • Resultado: Contenido IA generado para el ProductItem

Paso 3: EvaluateSelectedActivity

  • Condición: Siempre se ejecuta
  • Acción: Evalúa todos los SupplierProducts del ProductItem para determinar el proveedor seleccionado
  • Resultado:
  • should_sync: Si debe sincronizar
  • sync_type: Tipo de sincronización (product_basic, product_status)
  • selection_changed: Si cambió el proveedor seleccionado

Paso 4: DispatchSyncActivity

  • Condición: Solo si should_sync = true y existe product_item_id
  • Acción: Usa ProductSyncDispatcherService para despachar jobs a los canales configurados
  • Resultado: Jobs de sincronización despachados a sus colas respectivas

Monitoreo

Waterline UI

El paquete laravel-workflow/waterline proporciona una interfaz web para visualizar: - Estado de workflows (pending, running, completed, failed) - Activities ejecutadas - Timeline de ejecución - Excepciones

Consultas manuales

// Ver workflows recientes
$workflows = \Workflow\Models\StoredWorkflow::latest()->take(10)->get();

// Ver logs de un workflow específico
$logs = \Workflow\Models\StoredWorkflowLog::where('stored_workflow_id', $id)->get();

// Ver resultado de un workflow
$workflow = \Workflow\WorkflowStub::load($id);
$output = $workflow->output();

Resultado del workflow

El workflow retorna un array con toda la información para auditoría:

[
    'supplier_product_id' => 5,
    'detected_changes' => ['price', 'stock'],
    'started_at' => '2026-01-06T15:27:43-03:00',
    'completed_at' => '2026-01-06T15:27:44-03:00',
    'steps' => [
        'calculate_prices' => ['executed' => true, 'result' => [...]],
        'generate_content' => ['executed' => false, 'reason' => '...'],
        'evaluate_selected' => ['executed' => true, 'result' => [...]],
        'dispatch_sync' => ['executed' => true, 'result' => [...]]
    ],
    'summary' => [
        'prices_calculated' => true,
        'content_generated' => false,
        'selection_changed' => true,
        'sync_dispatched' => true,
        'sync_type' => 'product_status'
    ]
]

Beneficios

  1. Consolidación de cambios: Un único workflow por save() del SupplierProduct
  2. Secuencia garantizada: Los pasos se ejecutan en orden correcto
  3. Ejecución condicional: Solo se ejecutan las activities necesarias
  4. Trazabilidad: Todo queda registrado en la base de datos del workflow
  5. Auditoría: Resultado completo con timestamps y detalles de cada paso
  6. Independencia de sync: Los jobs de sincronización corren aparte, no bloquean el workflow
  7. Tolerancia a fallos: Si un servicio externo falla, el workflow ya completó

Dependencias

  • laravel-workflow/laravel-workflow: ^1.0
  • laravel-workflow/waterline: ^1.0 (UI de monitoreo)

Próximos pasos potenciales

  • [ ] Agregar señales para cancelar workflows en progreso
  • [ ] Implementar deduplicación por SupplierProduct (evitar workflows duplicados)
  • [ ] Agregar métricas de tiempo de ejecución por activity
  • [ ] Configurar alertas para workflows fallidos
  • [ ] Extender a otros modelos (ProductItem, etc.)

Fecha de implementación

Enero 2026

Autor

Implementado con asistencia de Claude Code