
# 액션 트리거

`Queuety::on_action()`을 사용하면 일반 WordPress 액션을 지속 가능한 워크플로 디스패치로 바꿀 수 있습니다.

이를 통해 다음과 같이 깔끔하게 연결할 수 있습니다.

`WordPress action -> mapped payload -> durable workflow`

관심 있는 이벤트가 이미 WordPress에 있고, 비용이 많이 들거나 오래 걸리는 처리는 비동기로 수행해야 할 때 유용합니다.

## 예제: 게시물 저장 시 콘텐츠 검토

```php
use Queuety\Queuety;

Queuety::on_action(
    'save_post',
    workflow: 'content_review',
    map: static fn ( int $post_id, object $post, bool $update ): array => [
        'post_id' => $post_id,
        'post_type' => $post->post_type,
        'update' => $update,
    ],
    when: static fn ( int $post_id, object $post ): bool => 'post' === $post->post_type,
    idempotency_key: static fn ( int $post_id ): string => "save_post:{$post_id}",
);
```

이 예제에서는 다음과 같습니다.

- `save_post`는 여전히 원래 WordPress 이벤트입니다
- `map`는 원시 훅 인수를 일반 워크플로 상태로 변환합니다
- `when`는 대기열에 추가하기 전에 원치 않는 이벤트를 건너뜁니다
- `idempotency_key`는 훅이 반복 실행되어 중복 작업이 디스패치되는 것을 방지합니다

## 동기적으로 실행되는 항목

작업 콜백 자체는 여전히 현재 WordPress 요청 안에서 실행됩니다.

즉, 다음 부분은 동기적으로 실행됩니다:

- `when`
- `map`
- `idempotency_key`

디스패치 후 비동기적으로 실행되는 것은 워크플로 단계뿐입니다.

## 페이로드 규칙

매핑된 페이로드에는 일반 배열, 스칼라 및 `null`만 포함해야 합니다.

WordPress 같은 원시 객체를 `WP_Post` 워크플로 상태에 그대로 전달하지 마세요. 먼저 `map()` 안에서 정규화하세요:

```php
Queuety::on_action(
    'save_post',
    workflow: 'content_review',
    map: static fn ( int $post_id, object $post, bool $update ): array => [
        'post_id' => $post_id,
        'post_type' => $post->post_type,
        'post_status' => $post->post_status,
        'update' => $update,
    ],
);
```

`_`로 시작하는 키는 해당 이름이 내부 워크플로 상태용으로 예약되어 있으므로 거부됩니다.

## 허용되는 인수

WordPress는 작업 콜백을 등록할 때 `accepted_args` 개수를 지정해야 합니다.

Queuety는 기본적으로 `map`, `when` 및 `idempotency_key` 콜백에서 이를 추론하므로 일반적인 경우에는 추가 설정이 필요하지 않습니다:

```php
Queuety::on_action(
    'save_post',
    workflow: 'content_review',
    map: static fn ( int $post_id, object $post, bool $update ): array => [
        'post_id' => $post_id,
        'update' => $update,
    ],
);
```

직접 재정의해야 한다면 `accepted_args`를 명시적으로 전달하세요:

```php
Queuety::on_action(
    'comment_post',
    workflow: 'comment_review',
    accepted_args: 2,
);
```

## 인라인 워크플로 빌더

등록된 워크플로 이름이나 인라인 `WorkflowBuilder`를 디스패치할 수 있습니다.

훅별 워크플로가 동일한 부트스트랩 파일에 정의되어 있다면 인라인 빌더를 사용하면 편리합니다:

```php
$review = Queuety::workflow( 'comment_review' )
    ->then( ModerateCommentStep::class )
    ->then( NotifyModeratorStep::class );

Queuety::on_action(
    'comment_post',
    workflow: $review,
    map: static fn ( int $comment_id ): array => [
        'comment_id' => $comment_id,
    ],
    idempotency_key: static fn ( int $comment_id ): string => "comment:{$comment_id}",
);
```

## 적합한 경우

다음과 같은 경우 작업 트리거를 사용하세요:

- WordPress가 이미 필요한 이벤트를 발생시킵니다
- 응답이 요청 시간 초과나 워커 재시작 후에도 유지되어야 합니다
- 후속 작업이 분기되거나 대기하거나 승인이 필요할 수 있습니다
- 반복되는 훅 실행에 대해 지속성 있는 멱등성이 필요합니다

작업이 WordPress 이벤트 경계와 연결되지 않았다면 직접 `Queuety::dispatch()` 또는 `Queuety::workflow()` 호출을 대신 사용하세요.

## 필터에는 사용하지 마세요

`Queuety::on_action()`는 의도적으로 작업 전용입니다.

필터는 요청 시점에 동기적으로 수행되는 변환입니다. WordPress는 필터링된 값을 즉시 반환받아야 하므로 일반적으로 동기식으로 유지해야 합니다.
