
# Viaje en el tiempo en flujos de trabajo

Queuety puede retroceder un flujo de trabajo a un paso anterior y reanudar la ejecución desde ese punto. Esto resulta útil si un paso generó un resultado incorrecto, si quieres volver a intentarlo con otra configuración o si necesitas recuperarte de datos dañados sin reiniciar todo el flujo.

El retroceso depende del [Registro de eventos del flujo de trabajo](https://queuety.inline0.dev/es/docs/workflows/event-log). El registro de eventos debe contener datos de `state_after` para el paso de destino.

## Retroceder un flujo de trabajo

### PHP API

Llama a `Queuety::rewind_workflow()` con el ID del flujo de trabajo y el índice del paso al que quieres retroceder:

```php
use Queuety\Queuety;

// Rewind workflow 42 to step 1.
// The state is restored to the snapshot taken after step 1 completed,
// and step 2 is enqueued for re-execution.
Queuety::rewind_workflow( $workflow_id, to_step: 1 );
```

El parámetro `to_step` es el índice, empezando por 0, del paso cuyo estado completado debe restaurarse. La ejecución se reanuda desde el paso _siguiente_ (to_step + 1).

### CLI

```bash
wp queuety workflow rewind <id> <step>
```

| Opción | Descripción |
|---|---|
| `<id>` | ID del flujo de trabajo (obligatorio) |
| `<step>` | Índice del paso al que se retrocederá, basado en 0 (obligatorio) |

```bash
wp queuety workflow rewind 42 1
```

## Cómo funciona

Al retroceder un flujo de trabajo hasta el paso N:

1. Se consulta el registro de eventos para obtener el valor `state_after` registrado después de completar el paso N
2. Si no existe ninguna instantánea, se lanza un `RuntimeException`
3. Se bloquea la fila del flujo de trabajo
4. El estado del flujo de trabajo se sustituye por la instantánea, conservando todas las claves reservadas (`_steps`, `_queue`, `_priority`, etc.) de la fila actual del flujo de trabajo
5. Se establece `current_step` en N + 1 y `status` en `running`
6. Se borran los campos `error_message` y `failed_at`
7. Se encola para su procesamiento el paso en el índice N + 1
8. Se registra un evento de registro `workflow_rewound`

A continuación, el trabajador recoge el paso encolado y el flujo de trabajo continúa con normalidad a partir de ese punto.

## Requisitos

Para retroceder se necesitan datos `state_after` en el registro de eventos. El registro los guarda automáticamente para cada evento `step_completed`. Si se ha depurado el registro de eventos mediante `WorkflowEventLog::prune()` y ya no existe el estado del paso de destino, no se podrá retroceder.

Asegúrese de que la retención del registro de eventos cubra el período al que podría necesitar retroceder.

## Casos de uso

### Corregir un controlador de paso con errores

Si un controlador de paso tenía un error que generaba resultados incorrectos, puede implementar la corrección y retroceder:

```php
// Step 2 (CallLLMHandler) produced garbled output due to a prompt bug.
// After fixing CallLLMHandler, rewind to step 1 so step 2 runs again
// with the corrected handler.
Queuety::rewind_workflow( $workflow_id, to_step: 1 );
```

### Reintentar con otra configuración

Si un paso falla por factores externos (límite de velocidad API o credenciales incorrectas), corrija la configuración y retroceda para volver a ejecutarlo:

```php
// Step 3 failed because the API key was expired.
// After updating the key, rewind to step 2 so step 3 retries.
Queuety::rewind_workflow( $workflow_id, to_step: 2 );
```

### Recuperarse de datos incorrectos

Si un paso anterior introdujo datos incorrectos en el estado, retroceda a una instantánea conocida como válida:

```php
// Step 0 fetched correct data, but step 1 corrupted it.
// Rewind to step 0 to restore the good state and re-run step 1.
Queuety::rewind_workflow( $workflow_id, to_step: 0 );
```

## Comparación con el reintento

| Aspecto | `retry_workflow()` | `rewind_workflow()` |
|---|---|---|
| Reanuda desde | El paso fallido | Cualquier paso anterior |
| Estado | Estado actual del flujo de trabajo | Restaurado desde la instantánea del registro de eventos `state_after` |
| Requisito | El flujo de trabajo tiene el estado `failed` | Instantánea del registro de eventos en el paso de destino |
| Estado posterior | `running` | `running` |
| Evento de registro | ninguno | `workflow_rewound` |
