
# 工作流导出与重放

Queuety 可以将工作流的完整执行历史导出为可移植的 JSON 格式，并在不同环境中重放。这有助于在本地复现生产环境中的错误、在不同环境之间迁移工作流，以及进行审计。

## 导出工作流

### PHP API

使用工作流 ID 调用 `Queuety::export_workflow()`。它会返回一个可序列化为 JSON 的数组：

```php
use Queuety\Queuety;

$data = Queuety::export_workflow( $workflow_id );
```

要直接获取 JSON 字符串：

```php
$json = json_encode( $data, JSON_PRETTY_PRINT );
file_put_contents( '/tmp/workflow-42.json', $json );
```

### CLI

```bash
wp queuety workflow export <id> [--output=<file>]
```

| 选项 | 说明 |
|---|---|
| `<id>` | 工作流 ID（必填） |
| `--output=<file>` | 写入 JSON 的文件路径。默认为标准输出。 |

```bash
# Print to stdout
wp queuety workflow export 42

# Write to a file
wp queuety workflow export 42 --output=/tmp/workflow-42.json
```

## 重放工作流

### PHP API

使用导出数据调用 `Queuety::replay_workflow()`。它会返回新的工作流 ID：

```php
use Queuety\Queuety;

$json = file_get_contents( '/tmp/workflow-42.json' );
$data = json_decode( $json, true );

$new_id = Queuety::replay_workflow( $data );
```

### CLI

```bash
wp queuety workflow replay <file>
```

| 选项 | 说明 |
|---|---|
| `<file>` | 已导出的 JSON 文件路径（必填） |

```bash
wp queuety workflow replay /tmp/workflow-42.json
# Success: Workflow replayed. New workflow ID: 85.
```

## JSON 结构

导出内容包含完整的工作流状态、关联作业、跟踪事件、日志条目、已存储信号、制品、分块，以及任何工作流依赖等待记录：

```json
{
    "workflow": {
        "id": 42,
        "name": "generate_report",
        "status": "failed",
        "state": { "user_id": 1, "_steps": [...], "_queue": "default" },
        "current_step": 2,
        "total_steps": 4,
        "parent_workflow_id": null,
        "parent_step_index": null,
        "started_at": "2026-03-28 10:00:00",
        "completed_at": null,
        "failed_at": "2026-03-28 10:05:00",
        "error_message": "API timeout",
        "deadline_at": null
    },
    "jobs": [
        {
            "id": 100,
            "queue": "default",
            "handler": "App\\Handlers\\FetchDataHandler",
            "payload": {},
            "status": "completed",
            "attempts": 1,
            "max_attempts": 3,
            "step_index": 0
        }
    ],
    "events": [
        {
            "id": 1,
            "job_id": 100,
            "step_index": 0,
            "step_name": "fetchData",
            "step_type": "single",
            "handler": "App\\Handlers\\FetchDataHandler",
            "event": "step_completed",
            "input": { "user_id": 1 },
            "output": { "records": 150 },
            "state_before": { "user_id": 1 },
            "state_after": { "user_id": 1, "records": 150 },
            "context": { "source": "api" },
            "error": null,
            "duration_ms": 230,
            "created_at": "2026-03-28 10:00:01"
        }
    ],
    "logs": [
        {
            "id": 1,
            "event": "workflow_started",
            "handler": "generate_report",
            "created_at": "2026-03-28 10:00:00"
        }
    ],
    "signals": [],
    "artifacts": [],
    "chunks": [],
    "wait_dependencies": [],
    "exported_at": "2026-03-28T12:00:00+00:00",
    "queuety_version": "0.22.0"
}
```

上方示例中的部分字段已缩写。实际导出内容包含每个事件记录中的所有跟踪列。

如果原始运行设置了 `definition_version`、`definition_hash` 和 `idempotency_key` 等工作流元数据，导出内容也会保留这些信息。

## 重放的工作方式

重放已导出的工作流时：

1. 会使用导出的状态和步骤定义创建新的工作流记录
2. 新工作流的名称为 `{original_name}_replay_{timestamp}`
3. 历史工作流事件和日志会重新插入新环境
4. 已存储信号和工作流等待依赖记录会作为历史状态重放
5. 如果原始工作流仍处于 `running`，则会将当前步骤加入队列进行处理。Repeat 和 `start_workflows()` 步骤不会重新入队，因此如果重放停在其中一个步骤上，该工作流会保持 `running` 状态且没有作业（[#17](https://github.com/inline0/queuety/issues/17)）
6. 如果原始工作流处于 `waiting_for_signal`、`waiting_for_workflows`、`paused`、`failed`、`cancelled` 或 `completed` 状态，重放后的工作流会保留该状态

重放后的工作流会获得新 ID，并独立运行，不会影响原始工作流。

对于 `waiting_for_workflows` 重放，导出的依赖记录会使用相同的工作流 ID 重新创建。这有利于审计，也适用于依赖工作流同样存在的环境，但不会自动跨环境重新映射依赖 ID。

## 使用场景

### 复现生产环境中的错误

从生产环境导出失败的工作流，并在本地重放：

```bash
# On production
wp queuety workflow export 42 --output=/tmp/workflow-42.json

# Copy the file to your local environment

# On local
wp queuety workflow replay /tmp/workflow-42.json
```

重放后的工作流具有完全相同的状态和步骤定义。运行中的工作流会将当前步骤重新入队，因此你可以从中断处继续执行；暂停或等待中的工作流则会以受阻状态重新创建，以供检查。

### 在不同环境之间迁移工作流

通过导出和重放，将工作流从预发布环境迁移到生产环境（或反向迁移）：

```bash
# On staging
wp queuety workflow export 15 --output=workflow.json

# On production
wp queuety workflow replay workflow.json
```

### 审计与归档

导出已完成的工作流，以便长期存储或满足合规要求。JSON 文件包含完整的执行历史，包括输入、输出、执行前后的状态、时间数据和错误详情。

```php
$data = Queuety::export_workflow( $workflow_id );
// Store $data in your archive system, S3, etc.
```
