
# Pemicu Tindakan

`Queuety::on_action()` memungkinkan Anda mengubah tindakan WordPress biasa menjadi pemanggilan alur kerja yang tahan lama.

Ini memberi Anda penghubung yang rapi:

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

Ini berguna saat peristiwa yang dibutuhkan sudah tersedia di WordPress dan respons yang mahal atau berjalan lama harus berlangsung secara asinkron.

## Contoh: tinjau konten saat sebuah pos disimpan

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

Dalam contoh tersebut:

- `save_post` tetap merupakan peristiwa WordPress asli
- `map` mengubah argumen hook mentah menjadi status alur kerja biasa
- `when` melewati peristiwa yang tidak diinginkan sebelum apa pun diantrekan
- `idempotency_key` mencegah pemanggilan hook berulang menjalankan eksekusi duplikat

## Yang berjalan secara sinkron

Callback tindakan itu sendiri tetap berjalan dalam permintaan WordPress saat ini.

Artinya, bagian-bagian ini berjalan secara sinkron:

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

Hanya langkah alur kerja yang berjalan secara asinkron setelah pemanggilan.

## Aturan payload

Payload yang dipetakan harus berisi array biasa, nilai skalar, dan `null`.

Jangan teruskan objek WordPress mentah seperti `WP_Post` langsung ke status alur kerja. Normalisasikan terlebih dahulu di dalam `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,
    ],
);
```

Kunci yang diawali dengan `_` ditolak karena nama tersebut dicadangkan untuk status internal alur kerja.

## Argumen yang diterima

WordPress memerlukan jumlah `accepted_args` saat mendaftarkan callback tindakan.

Secara default, Queuety menyimpulkannya dari callback `map`, `when`, dan `idempotency_key` Anda, jadi kasus umum tidak memerlukan konfigurasi tambahan:

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

Jika Anda memerlukan penggantian manual, berikan `accepted_args` secara eksplisit:

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

## Pembuat alur kerja inline

Anda dapat memanggil nama alur kerja yang terdaftar atau `WorkflowBuilder` inline.

Pembuat inline berguna ketika alur kerja khusus hook didefinisikan dalam file bootstrap yang sama:

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

## Kapan pola ini cocok

Gunakan pemicu tindakan saat:

- WordPress sudah memancarkan peristiwa yang Anda perlukan
- respons harus tetap berjalan meski permintaan mengalami timeout atau worker dimulai ulang
- pekerjaan lanjutan mungkin bercabang, menunggu, atau memerlukan persetujuan
- pemanggilan hook duplikat memerlukan idempotensi yang tahan lama

Gunakan pemanggilan `Queuety::dispatch()` atau `Queuety::workflow()` langsung jika pekerjaan tidak terkait dengan batas peristiwa WordPress.

## Bukan untuk filter

`Queuety::on_action()` memang dirancang khusus untuk tindakan saja.

Filter adalah transformasi sinkron pada waktu permintaan. Biasanya filter harus tetap sinkron karena WordPress mengharapkan nilai yang telah difilter dikembalikan seketika.
