
# Acionadores de ações

`Queuety::on_action()` permite transformar uma ação WordPress comum em um despacho durável de fluxo de trabalho.

Isso cria uma ligação clara:

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

Isso é útil quando o evento de interesse já existe em WordPress e a resposta demorada ou de alto custo deve ocorrer de forma assíncrona.

## Exemplo: revisar conteúdo quando uma publicação é salva

```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}",
);
```

Nesse exemplo:

- `save_post` continua sendo o evento WordPress original
- `map` transforma argumentos brutos do hook em estado simples do fluxo de trabalho
- `when` ignora eventos indesejados antes que qualquer coisa seja enfileirada
- `idempotency_key` impede que chamadas repetidas do hook iniciem execuções duplicadas

## O que é executado de forma síncrona

O próprio callback da ação continua sendo executado na solicitação atual de WordPress.

Isso significa que estas partes são síncronas:

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

Somente as etapas do fluxo de trabalho são executadas de forma assíncrona após o despacho.

## Regras para o payload

Os payloads mapeados devem conter arrays simples, escalares e `null`.

Não passe objetos brutos de WordPress, como `WP_Post`, diretamente ao estado do fluxo de trabalho. Primeiro, normalize-os dentro de `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,
    ],
);
```

Chaves que começam com `_` são rejeitadas porque esses nomes são reservados para o estado interno do fluxo de trabalho.

## Argumentos aceitos

WordPress exige uma contagem de `accepted_args` ao registrar um callback de ação.

Queuety deduz esse valor por padrão com base nos callbacks `map`, `when` e `idempotency_key`, portanto o caso mais comum não exige configuração adicional:

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

Se precisar substituir o valor manualmente, passe `accepted_args` explicitamente:

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

## Criadores de fluxos de trabalho em linha

Você pode iniciar um fluxo de trabalho registrado pelo nome ou um `WorkflowBuilder` em linha.

Criadores em linha são úteis quando o fluxo de trabalho específico do hook é definido no mesmo arquivo de inicialização:

```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}",
);
```

## Quando é adequado

Use acionadores de ações quando:

- WordPress já emitir o evento de seu interesse
- a resposta precisar resistir a tempos limite da solicitação ou reinicializações do processo de trabalho
- o trabalho de acompanhamento puder se ramificar, aguardar ou exigir aprovação
- chamadas duplicadas do hook precisarem de idempotência durável

Use uma chamada direta a `Queuety::dispatch()` ou `Queuety::workflow()` quando o trabalho não estiver vinculado a um limite de evento WordPress.

## Não use para filtros

`Queuety::on_action()` foi projetado intencionalmente apenas para ações.

Filtros são transformações síncronas executadas durante a solicitação. Em geral, devem continuar síncronos, pois WordPress espera que um valor filtrado seja retornado imediatamente.
