
# 워크플로 내보내기 및 재생

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을 쓸 파일 경로입니다. 기본값은 stdout입니다. |

```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.
```
