
# Подорож у часі робочого процесу

Queuety може повернути робочий процес до попереднього кроку й відновити виконання з цієї точки. Це корисно, якщо крок видав неправильний результат, потрібно повторити його з іншою конфігурацією або відновити роботу після пошкодження даних без перезапуску всього робочого процесу.

Повернення спирається на [Журнал подій робочого процесу](https://queuety.inline0.dev/uk/docs/workflows/event-log). У журналі мають бути дані `state_after` для цільового кроку.

## Повернення робочого процесу

### PHP API

Викличте `Queuety::rewind_workflow()`, указавши ID робочого процесу та індекс кроку, до якого потрібно повернутися:

```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 );
```

Параметр `to_step` — це індекс кроку, відлік якого починається з нуля, стан якого після завершення потрібно відновити. Виконання продовжується з _наступного_ кроку (to_step + 1).

### CLI

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

| Опція | Опис |
|---|---|
| `<id>` | ID робочого процесу (обов’язково) |
| `<step>` | Індекс кроку для повернення, починаючи з 0 (обов’язково) |

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

## Як це працює

Під час повернення робочого процесу до кроку N:

1. У журналі подій шукається значення `state_after`, записане після завершення кроку N
2. Якщо знімка стану немає, виникає `RuntimeException`
3. Рядок робочого процесу блокується
4. Стан робочого процесу замінюється знімком зі збереженням усіх зарезервованих ключів (`_steps`, `_queue`, `_priority` тощо) з поточного рядка робочого процесу
5. `current_step` встановлюється в N + 1, а `status` — у `running`
6. Поля `error_message` і `failed_at` очищуються
7. Крок із індексом N + 1 додається до черги на обробку
8. Записується подія журналу `workflow_rewound`

Потім виконавець бере крок із черги, і робочий процес продовжується звичайним чином із цієї точки.

## Вимоги

Для повернення потрібні дані `state_after` у журналі подій. Журнал подій записує їх автоматично для кожної події `step_completed`. Якщо журнал було очищено (через `WorkflowEventLog::prune()`) і стан цільового кроку більше не зберігається, повернення завершиться помилкою.

Переконайтеся, що строк зберігання журналу подій охоплює період, до якого може знадобитися повернутися.

## Варіанти використання

### Виправлення помилкового обробника кроку

Якщо через помилку в обробнику кроку з’явився неправильний результат, розгорніть виправлення та поверніться до потрібного кроку:

```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 );
```

### Повторний запуск з іншою конфігурацією

Якщо крок завершився помилкою через зовнішні чинники (обмеження частоти API, неправильні облікові дані), виправте конфігурацію та поверніться до нього для повторного запуску:

```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 );
```

### Відновлення після помилкових даних

Якщо попередній крок додав у стан помилкові дані, поверніться до відомого коректного знімка:

```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 );
```

## Порівняння з повторною спробою

| Аспект | `retry_workflow()` | `rewind_workflow()` |
|---|---|---|
| Звідки відновлюється виконання | Крок, що завершився помилкою | Будь-який попередній крок |
| Стан | Поточний стан робочого процесу | Відновлений зі знімка журналу подій `state_after` |
| Умова | Робочий процес має стан `failed` | Знімок журналу подій для цільового кроку |
| Стан після виконання | `running` | `running` |
| Подія журналу | немає | `workflow_rewound` |
