
# PHP API

Do vsega v Queuety lahko dostopate prek statičnega razreda `Queuety\Queuety`. Ta je enotna vstopna točka za razpošiljanje opravil, sestavljanje potekov dela, upravljanje avtomatov stanj, upravljanje čakalnih vrst in dostop do notranjih podsistemov.

```php
use Queuety\Queuety;
```

## Samostojen dostop do jedra

Izvajalno okolje Queuety, ki temelji na DB, je mogoče inicializirati zunaj WordPress.

Ta samostojna možnost je namenjena jedru za orkestracijo:

- opravila in delavci (za skupine delavcev so potrebne tudi konstante `DB_HOST`, `DB_NAME`, `DB_USER` in `DB_PASSWORD`; glejte spodaj)
- poteki dela in signali
- avtomati stanj in dogodki
- artefakti, dnevniki, metrike in urniki

Ne nadomešča adapterja WordPress. `Queuety::on_action()`,
`replace_wp_cron()`, inicializacija vtičnika in dejanska pot registracije za `wp queuety ...`
še vedno zahtevajo WordPress.

### `Queuety::init( Connection $conn )`

Inicializirajte Queuety z neposredno povezavo, ki temelji na DB.

```php
use Queuety\Connection;
use Queuety\Queuety;

$conn = new Connection(
    host: '127.0.0.1:3306',
    dbname: 'wordpress',
    user: 'root',
    password: 'secret',
    prefix: 'wp_',
);

Queuety::init( $conn );
```

Izbirni argument `table_prefix` spremeni del izvajalnega okolja Queuety v imenih tabel za posamezno povezavo:

```php
$conn = new Connection(
    host: '127.0.0.1:3306',
    dbname: 'wordpress',
    user: 'root',
    password: 'secret',
    prefix: 'wp_',
    table_prefix: 'themequeue_',
);
```

Tako se tabele, kot je `queuety_jobs`, razrešijo v `wp_themequeue_jobs`.

### `Queuety::ensure_schema()`

Preverite, ali obstajajo izvajalne tabele Queuety za aktivno povezavo.

```php
Queuety::init( $conn );
Queuety::ensure_schema();
```

Za celoten model in omejitve uporabe WordPress glejte razdelek [Samostojna uporaba](https://queuety.inline0.dev/sl/docs/features/standalone-use).

## Opravila

### `Queuety::dispatch( $handler, $payload )`

Razpošljite opravilo. Sprejme niz z imenom obravnavalnika ali primerek `Contracts\Job`. Vrne gradnik `PendingJob` za veriženje možnosti.

```php
// Handler name + payload (original API)
Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] );

// Contracts\Job instance (v0.6.0+)
Queuety::dispatch( new SendEmailJob( to: 'user@example.com' ) );

// With options
Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] )
    ->on_queue( 'emails' )
    ->with_priority( Priority::High )
    ->delay( 300 )
    ->max_attempts( 5 )
    ->rate_limit( 10, 60 )
    ->unique()
    ->after( $other_job_id );

// Get the job ID
$job_id = Queuety::dispatch( 'send_email', $payload )->id();
```

Ko je posredovan primerek `Contracts\Job`, serializator izlušči FQCN kot ime obravnavalnika in javne lastnosti kot vsebino. Parameter `$payload` se prezre, kadar je `$handler` primerek `Job`.

### Metode `PendingJob`

| Metoda | Opis |
|---|---|
| `on_queue( string $queue )` | Nastavi ciljno čakalno vrsto |
| `with_priority( Priority $priority )` | Nastavi raven prioritete |
| `delay( int $seconds )` | Zakasnitev pred razpoložljivostjo opravila |
| `max_attempts( int $max )` | Največje število poskusov ponovitve |
| `rate_limit( int $max, int $window )` | Omejitev hitrosti: največje število izvajanj v časovnem oknu v sekundah |
| `unique()` | Prepreči podvojeno razpošiljanje |
| `after( int $job_id )` | Počaka, da se najprej dokonča drugo opravilo |
| `concurrency_group( string $group, int $limit )` | Opravilo doda v skupino za skupno sprejemanje delavcev |
| `cost_units( int $units )` | Razpošiljanju doda metapodatke o relativnih stroških izvajanja |
| `id()` | Vsili razpošiljanje in vrne ID opravila |

`concurrency_group()` in `cost_units()` sta del širšega modela [Upravljanje virov](https://queuety.inline0.dev/sl/docs/features/resource-management), zato lahko isto razpošiljanje sodeluje pri omejitvah sočasnosti na podlagi števila, uteženih proračunih čakalnih vrst ali ponudnikov ter hevristikah za sprejemanje delavcev.

### `Queuety::dispatch_sync( $handler, $payload )`

Opravilo se izvede sinhrono v trenutnem procesu, ne da bi bilo dodano v čakalno vrsto.

```php
// With a Job instance
Queuety::dispatch_sync( new SendEmailJob( to: 'user@example.com', subject: 'Hi', body: 'Hello' ) );

// With a handler name and payload
Queuety::dispatch_sync( 'send_email', [ 'to' => 'user@example.com' ] );
```

Metoda `handle()` opravila se pokliče neposredno. Vrstica v zbirki podatkov se ne ustvari, delavec ni vključen, vmesna programska oprema pa se ne uporabi.

### `Queuety::batch( $jobs )`

Razpošljite več opravil z enim večvrstičnim ukazom INSERT.

```php
$job_ids = Queuety::batch( [
    [ 'handler' => 'send_email', 'payload' => [ 'to' => 'a@example.com' ], 'queue' => 'emails' ],
    [ 'handler' => 'send_email', 'payload' => [ 'to' => 'b@example.com' ], 'priority' => 2 ],
] );
```

### `Queuety::create_batch( $jobs )`

Ustvarite `BatchBuilder` za razpošiljanje skupine opravil s povratnimi klici in spremljanjem napredka. Celoten opis je na voljo v razdelku [Paketna obdelava](https://queuety.inline0.dev/sl/docs/features/batching).

```php
$batch = Queuety::create_batch( [
    new ImportUsersJob( $chunk_1 ),
    new ImportUsersJob( $chunk_2 ),
] )
    ->name( 'Import users' )
    ->then( ImportCompleteHandler::class )
    ->catch( ImportFailedHandler::class )
    ->finally( ImportCleanupHandler::class )
    ->allow_failures()
    ->on_queue( 'imports' )
    ->dispatch();
```

### Metode `BatchBuilder`

| Metoda | Vrne | Opis |
|---|---|---|
| `name( string $name )` | `self` | Nastavi ime za paket |
| `on_queue( string $queue )` | `self` | Nastavi čakalno vrsto za vsa opravila v paketu |
| `then( string $handler_class )` | `self` | Obravnavalnik, klican ob uspešnem dokončanju paketa |
| `catch( string $handler_class )` | `self` | Obravnavalnik, klican ob neuspehu prvega opravila v paketu |
| `finally( string $handler_class )` | `self` | Obravnavalnik, klican ob zaključku paketa (uspešnem ali neuspešnem) |
| `allow_failures()` | `self` | Dovoli izvedbo povratnega klica `then` tudi ob napakah |
| `dispatch()` | `Batch` | Ustvari vrstico paketa in vsa opravila ter vrne objekt vrednosti `Batch` |

### `Queuety::find_batch( $id )`

Poišče paket po ID-ju. Vrne objekt vrednosti `Batch` ali `null`.

```php
$batch = Queuety::find_batch( $batch_id );

if ( null !== $batch ) {
    echo $batch->progress() . '% complete';
}
```

## Upravljanje delavcev

### `Queuety::run_worker( $queue = 'default', $once = false )`

Neposredno zaženite eno zanko delavca.

```php
Queuety::run_worker( 'default' );
Queuety::run_worker( 'critical,default', true );
```

### `Queuety::run_worker_pool( $workers, $queue = 'default' )`

Neposredno zaženite skupino delavcev fiksne velikosti. Potrebni sta razširitvi `pcntl` in `posix`. Skupina za svoje podrejene povezave prebere konstante WordPress `DB_HOST`, `DB_NAME`, `DB_USER` in `DB_PASSWORD` (predpone tabel prevzame samo iz inicializirane povezave), zato jih določite, kadar skupino zaženete zunaj WordPress ([#5](https://github.com/inline0/queuety/issues/5)).

```php
Queuety::run_worker_pool( 4, 'providers' );
```

### `Queuety::run_auto_scaling_worker_pool( $min_workers, $max_workers, $queue = 'default' )`

Neposredno zaženite prilagodljivo skupino delavcev. Veljajo enake zahteve kot za `run_worker_pool()`.

```php
Queuety::run_auto_scaling_worker_pool( 2, 6, 'providers' );
```

### Objekt vrednosti `Batch`

| Metoda/lastnost | Vrsta | Opis |
|---|---|---|
| `$id` | `int` | ID paketa |
| `$name` | `string\|null` | Izbirno ime paketa |
| `$total_jobs` | `int` | Skupno število opravil v paketu |
| `$pending_jobs` | `int` | Opravila, ki so še v čakanju |
| `$failed_jobs` | `int` | Število neuspešnih opravil |
| `$failed_job_ids` | `array` | ID-ji neuspešnih opravil |
| `$created_at` | `DateTimeImmutable` | Čas nastanka paketa |
| `$finished_at` | `DateTimeImmutable\|null` | Čas zaključka paketa |
| `$cancelled_at` | `DateTimeImmutable\|null` | Čas preklica paketa |
| `progress()` | `int` | Odstotek dokončanosti (0–100) |
| `finished()` | `bool` | Ali je paket zaključen |
| `has_failures()` | `bool` | Ali je katero od opravil neuspešno |
| `cancelled()` | `bool` | Ali je bil paket preklican |

### `Queuety::chain( $jobs )`

Ustvarite `ChainBuilder` za zaporedno izvajanje opravil. Vsako opravilo je odvisno od uspešnega dokončanja prejšnjega.

```php
$first_job_id = Queuety::chain( [
    new FetchDataJob( $url ),
    new ProcessDataJob(),
    new NotifyCompleteJob(),
] )
    ->on_queue( 'pipeline' )
    ->catch( ChainFailedHandler::class )
    ->dispatch();
```

### Metode `ChainBuilder`

| Metoda | Vrne | Opis |
|---|---|---|
| `on_queue( string $queue )` | `self` | Nastavi čakalno vrsto za vsa opravila v verigi |
| `catch( string $handler_class )` | `self` | Obravnavalnik, klican, ko je katero koli opravilo v verigi trajno premaknjeno v arhiv |
| `dispatch()` | `int` | Ustvari vsa opravila z zaporednimi odvisnostmi in vrne ID prvega opravila |

### `Queuety::retry( $job_id )`

Znova poskusite izvesti določeno opravilo. Njegovo stanje se ponastavi na `pending`.

```php
Queuety::retry( 42 );
```

### `Queuety::retry_buried()`

Znova poskusite izvesti vsa arhivirana opravila. Vrne število opravil, pri katerih je bil poskus ponovljen.

```php
$count = Queuety::retry_buried();
```

### `Queuety::purge( $older_than_days )`

Odstranite dokončana opravila. Vrne število odstranjenih opravil.

```php
$count = Queuety::purge();     // uses QUEUETY_RETENTION_DAYS
$count = Queuety::purge( 30 ); // purge jobs older than 30 days
```

## Čakalne vrste

### `Queuety::stats( $queue )`

Pridobite število opravil, razvrščenih po stanju.

```php
$stats = Queuety::stats();          // all queues
$stats = Queuety::stats( 'emails' ); // specific queue
// ['pending' => 12, 'processing' => 3, 'completed' => 150, 'failed' => 2, 'buried' => 1]
```

### `Queuety::buried( $queue )`

Pridobite vsa arhivirana opravila.

```php
$jobs = Queuety::buried();
$jobs = Queuety::buried( 'emails' );
```

### `Queuety::pause( $queue )`

Začasno ustavite čakalno vrsto, da jo delavci preskočijo.

```php
Queuety::pause( 'emails' );
```

### `Queuety::resume( $queue )`

Nadaljujte začasno ustavljeno čakalno vrsto.

```php
Queuety::resume( 'emails' );
```

### `Queuety::is_paused( $queue )`

Preverite, ali je čakalna vrsta začasno ustavljena.

```php
if ( Queuety::is_paused( 'emails' ) ) {
    // Queue is paused
}
```

## Poteki dela

### `Queuety::workflow( $name )`

Začnite sestavljati potek dela. Vrne `WorkflowBuilder`.

```php
$workflow_id = Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );
```

### Metode `WorkflowBuilder`

| Metoda | Opis |
|---|---|
| `then( string $handler_class, ?string $name = null )` | Doda zaporedni korak. Izbirno ime za pogojno razvejanje. |
| `parallel( array $handler_classes )` | Doda skupino vzporednih korakov. |
| `for_each( string $items_key, string $handler_class, ?string $result_key = null, ForEachMode $mode = ForEachMode::All, ?int $quorum = null, ?string $reducer_class = null, ?string $name = null )` | Doda dinamičen korak for-each, ki za vsak element v stanju poteka dela ustvari vejo z enim opravilom. |
| `repeat_while( string $target_step, ?string $state_key = null, mixed $expected = true, ?string $name = null, ?string $condition_class = null, ?int $max_iterations = null )` | Skoči nazaj na prej imenovani korak, dokler se ujemata javni ključ stanja ali razred `RepeatCondition`. |
| `repeat_until( string $target_step, ?string $state_key = null, mixed $expected = true, ?string $name = null, ?string $condition_class = null, ?int $max_iterations = null )` | Skoči nazaj na prej imenovani korak, dokler se javni ključ stanja ali razred `RepeatCondition` ne ujema. |
| `run_workflow( string $workflow_name, WorkflowBuilder $sub_builder )` | Doda korak za zagon poteka dela. |
| `delay( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 )` | Doda trajno zakasnitev. Sešteje se trajanje vseh zakasnitev. |
| `wait_for_signal( string $name, ?string $result_key = null, ?string $step_name = null, array $match_payload = [], ?string $correlation_key = null )` | Doda korak čakanja na signal. Izbirna `match_payload` in `correlation_key` omogočata prezrtje nepovezanih dogodkov. |
| `wait_for_signals( array $signal_names, WaitMode $mode = WaitMode::All, ?string $result_key = null, ?string $name = null, array $match_payload = [], ?string $correlation_key = null )` | Počaka na vse ali katerega koli od več signalov, po želji z ujemanjem vsebine in korelacijo. |
| `wait_for_approval( string $signal_name = 'approval', ?string $result_key = 'approval', ?string $name = null, array $match_payload = [], ?string $correlation_key = null )` | Počaka na signal za človeško odobritev. |
| `wait_for_decision( string $approve_signal = 'approved', string $reject_signal = 'rejected', ?string $result_key = 'decision', ?string $name = null, array $match_payload = [], ?string $correlation_key = null )` | Počaka na odobritev ali zavrnitev in shrani strukturirane podatke o odločitvi. |
| `wait_for_input( string $signal_name = 'input', ?string $result_key = 'input', ?string $name = null, array $match_payload = [], ?string $correlation_key = null )` | Počaka na signal za človeški vnos. |
| `wait_for_workflow( int\|string $workflow, ?string $result_key = null, ?string $name = null )` | Počaka na dokončanje enega ID-ja poteka dela ali ID-ja poteka dela, shranjenega v javnem stanju. |
| `wait_for_workflows( array\|string $workflows, WaitMode $mode = WaitMode::All, ?string $result_key = null, ?string $name = null, ?int $quorum = null )` | Počaka, da se dokončajo vsi ali kateri koli od več potekov dela oziroma doseže zahtevano število. |
| `wait_for_workflow_group( string $group_key, WaitMode $mode = WaitMode::All, ?int $quorum = null, ?string $result_key = null, ?string $name = null )` | Počaka na že zagnano skupino potekov dela z internim ključem skupine. |
| `start_workflows( string $items_key, WorkflowBuilder $workflow_builder, string $result_key = 'started_workflow_ids', string $payload_key = 'item', bool $inherit_state = true, ?string $name = null, ?string $group_key = null )` | Za vsak element med izvajanjem razpošlje en potek dela najvišje ravni in po želji označi zagnani nabor s trajnim ključem skupine. |
| `start_agents( string $items_key, WorkflowBuilder $workflow_builder, string $result_key = 'agent_workflow_ids', string $payload_key = 'agent_task', bool $inherit_state = true, ?string $name = null, ?string $group_key = null )` | Drugo ime za `start_workflows()`, namenjeno agentom. |
| `wait_for_agents( array\|string $workflows = 'agent_workflow_ids', WaitMode $mode = WaitMode::All, ?string $result_key = 'agent_results', ?string $name = null, ?int $quorum = null )` | Drugo ime za `wait_for_workflows()`, namenjeno agentom. |
| `wait_for_agent_group( string $group_key = 'agents', WaitMode $mode = WaitMode::All, ?int $quorum = null, ?string $result_key = 'agent_results', ?string $name = null )` | Drugo ime za `wait_for_workflow_group()`, namenjeno agentom. |
| `version( string $version )` | Definiciji poteka dela doda različico na ravni aplikacije za pregled in izvoze. |
| `idempotency_key( string $key )` | Zagotovi trajnost razpošiljanja poteka dela s ključem, ki ga poda klicatelj. Ponovno razpošiljanje z istim ključem vrne prvotni ID poteka dela. |
| `max_transitions( int $max )` | Potek dela se ne uspešno zaključi, če se izvede več kot `$max` prehodov med koraki. |
| `max_for_each_items( int $max )` | Potek dela se ne uspešno zaključi, če korak `for_each()` poskuša ustvariti več kot `$max` elementov. |
| `max_state_bytes( int $bytes )` | Potek dela se ne uspešno zaključi, če javno stanje preseže `$bytes`. |
| `max_cost_units( int $max )` | Potek dela se ne uspešno zaključi, če stroški dokončanih korakov presežejo `$max` enot. |
| `max_started_workflows( int $max )` | Potek dela se ne uspešno zaključi, če bi razpošiljanje preseglo `$max` podrejenih potekov dela. |
| `compensate_with( string $handler_class )` | Zadnjemu dodanemu koraku priloži obravnavalnik za kompenzacijo. |
| `compensate_on_failure()` | Ob neuspehu poteka dela samodejno izvede kompenzacije dokončanih korakov. |
| `on_queue( string $queue )` | Nastavi čakalno vrsto za vse korake. |
| `with_priority( Priority $priority )` | Nastavi prioriteto za vse korake. |
| `max_attempts( int $max )` | Nastavi največje število poskusov ponovitve za posamezen korak. |
| `on_cancel( string $handler_class )` | Registrira razred obravnavalnika za čiščenje ob preklicu. Glejte [Preklic](https://queuety.inline0.dev/sl/docs/workflows/cancellation). |
| `prune_state_after( int $steps = 2 )` | Omogoči samodejno obrezovanje stanja. Odstrani izhode korakov, starejše od določenega praga. Glejte [Obrezovanje stanja](https://queuety.inline0.dev/sl/docs/features/state-pruning). |
| `must_complete_within( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 )` | Nastavi rok za potek dela. Sešteje se trajanje vseh zakasnitev. Glejte [Roki](https://queuety.inline0.dev/sl/docs/workflows/deadlines). |
| `on_deadline( string $handler_class )` | Registrira obravnavalnik, ki se pokliče ob prekoračitvi roka poteka dela. Glejte [Roki](https://queuety.inline0.dev/sl/docs/workflows/deadlines). |
| `dispatch( array $initial_payload = [] )` | Razpošlje potek dela. Vrne njegov ID. |

### `Queuety::workflow_status( $workflow_id )`

Pridobi stanje poteka dela. Vrne objekt `WorkflowState` ali `null`.

```php
$state = Queuety::workflow_status( $workflow_id );
echo $state->name;          // 'generate_report'
echo $state->status->value; // 'running'
echo $state->current_step;  // 1
echo $state->total_steps;   // 3
print_r( $state->state );   // accumulated public state array
echo $state->wait_type;     // 'signal' or 'workflow' while blocked
echo $state->wait_mode;     // 'all', 'any', or 'quorum'
echo $state->definition_version; // 'research.v2'
echo $state->definition_hash;    // '4c7a...'
echo $state->idempotency_key;    // 'brief:42:research'
echo $state->artifact_count;     // 2
print_r( $state->budget );       // configured workflow budget + current usage
print_r( $state->wait_details ); // matched/remaining blockers, result key, correlation info
print_r( $state->artifact_keys ); // ['draft', 'citations']
```

`WorkflowState` ponuja tudi:

- `waiting_for`: imena signalov ali ID-ji potekov dela, ki trenutno blokirajo izvajanje
- `current_step_name`: konfigurirano ime trenutnega koraka, če obstaja
- `wait_mode`: trenutni način čakanja (`all`, `any` ali `quorum`), ko je izvajanje blokirano
- `wait_details`: dodatni podatki za pregled, na primer ujemajoče se in preostale blokade
- `definition_version`: vrednost, ki jo nastavi `version()`, če obstaja
- `definition_hash`: deterministični zgoščeni odtis definicije poteka dela
- `idempotency_key`: trajni ključ za odpošiljanje, če obstaja
- `budget`: konfigurirane omejitve in trenutna poraba, če so varovala omogočena
- `artifact_count`: število shranjenih artefaktov za potek dela
- `artifact_keys`: ključi shranjenih artefaktov za hiter pregled

### `Queuety::retry_workflow( $workflow_id )`

Ponovno poskusi neuspešni potek dela od koraka, v katerem je prišlo do napake.

```php
Queuety::retry_workflow( $workflow_id );
```

Sproži `RuntimeException`, če je bil potek dela po napaki že kompenziran.

### `Queuety::pause_workflow( $workflow_id )`

Začasno ustavi potek dela, ki se izvaja. Delo za trenutni korak, ki je že v čakalni vrsti, se lahko še vedno zaključi, poznejši koraki pa se ne dodajo v čakalno vrsto, dokler poteka dela ne nadaljujete.

```php
Queuety::pause_workflow( $workflow_id );
```

### `Queuety::resume_workflow( $workflow_id )`

Nadaljuj začasno ustavljen potek dela.

```php
Queuety::resume_workflow( $workflow_id );
```

### `Queuety::cancel_workflow( $workflow_id )`

Prekliči potek dela in izvedi vse registrirane čistilne obravnavalnike. Nastavi stanje na `cancelled` ter skrije vsa čakajoča opravila in opravila v obdelavi za ta potek dela.

```php
Queuety::cancel_workflow( $workflow_id );
```

Sproži `RuntimeException`, če je potek dela že `completed` ali `cancelled`. Podrobnosti so v razdelku [Preklic](https://queuety.inline0.dev/sl/docs/workflows/cancellation).

### `Queuety::rewind_workflow( $workflow_id, $to_step )`

Povrni potek dela na prejšnji korak in ga znova zaženi od tam. Stanje za dani korak se obnovi iz dnevnika dogodkov `state_after`, naslednji korak pa se doda v čakalno vrsto.

```php
Queuety::rewind_workflow( $workflow_id, to_step: 1 );
```

Sproži `RuntimeException`, če za ciljni korak ni zabeleženega stanja. Zahteva [Dnevnik dogodkov poteka dela](https://queuety.inline0.dev/sl/docs/workflows/event-log). Podrobnosti so v razdelku [Potovanje skozi čas](https://queuety.inline0.dev/sl/docs/workflows/time-travel).

### `Queuety::fork_workflow( $workflow_id )`

Razcepi potek dela, ki se izvaja, v neodvisno kopijo s trenutnim stanjem. Vrne ID novega poteka dela.

```php
$forked_id = Queuety::fork_workflow( $workflow_id );
```

Razcepljeni potek dela dobi svoj ID in deluje neodvisno od izvirnika. Podrobnosti so v razdelku [Razcepljanje](https://queuety.inline0.dev/sl/docs/workflows/forking).

### `Queuety::export_workflow( $workflow_id )`

Izvozi celotno zgodovino izvajanja poteka dela kot matriko, serializirano v JSON. Vključuje vrstico poteka dela, vsa opravila, dogodke poteka dela in vnose v dnevnik.

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

Za strukturo JSON in primere uporabe glejte [Izvoz in ponovni zagon](https://queuety.inline0.dev/sl/docs/workflows/export-replay).

### `Queuety::replay_workflow( $data )`

Ponovno zaženi izvoženi potek dela v trenutnem okolju. Izvoz ustvari nov potek dela in vrne njegov ID.

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

Podrobnosti so v razdelku [Izvoz in ponovni zagon](https://queuety.inline0.dev/sl/docs/workflows/export-replay).

### `Queuety::replace_wp_cron()`

Vgrajeni sistem WordPress cron zamenja z razporejevalnikom Queuety. Prestrezata se `wp_schedule_event()`, `wp_unschedule_event()` in `wp_get_scheduled_event()`, ponavljajoči se dogodki pa se preusmerijo prek delavca Queuety.

```php
Queuety::replace_wp_cron();
```

Deluje samo, če je naložen WordPress. Podrobnosti so v razdelku [WP-Cron Zamenjava](https://queuety.inline0.dev/sl/docs/features/wp-cron).

### `Queuety::restore_wp_cron()`

Obnovi privzeto vedenje WordPress cron tako, da odstrani povezovalne kljuke Queuety cron.

```php
Queuety::restore_wp_cron();
```

Omejitve so opisane v razdelku [WP-Cron Zamenjava](https://queuety.inline0.dev/sl/docs/features/wp-cron).

### `Queuety::signal( $workflow_id, $name, $data )`

Pošlji signal poteku dela. Če potek dela trenutno čaka na ta signal, se takoj nadaljuje. Sicer se signal shrani in prevzame, ko potek dela doseže ustrezni korak `wait_for_signal`.

```php
Queuety::signal( $workflow_id, 'approved' );

// With data merged into workflow state
Queuety::signal( $workflow_id, 'approved', [
    'approved_by' => 'admin@example.com',
] );
```

Podrobnosti so v razdelku [Signali poteka dela](https://queuety.inline0.dev/sl/docs/workflows/signals).

### `Queuety::approve_workflow( $workflow_id, $data = [], $signal_name = 'approval' )`

Semantični ovoj okoli `signal()` za tokove odobritve.

```php
Queuety::approve_workflow( $workflow_id, [
    'reviewer' => 'editor@example.com',
] );
```

### `Queuety::reject_workflow( $workflow_id, $data = [], $signal_name = 'rejected' )`

Semantični ovoj okoli `signal()` za tokove zavrnitve.

```php
Queuety::reject_workflow( $workflow_id, [
    'reason' => 'needs citations',
] );
```

### `Queuety::submit_workflow_input( $workflow_id, $data = [], $signal_name = 'input' )`

Semantični ovoj okoli `signal()` za strukturiran vnos uporabnika.

```php
Queuety::submit_workflow_input( $workflow_id, [
    'notes' => 'Ship after legal review',
] );
```

### `Queuety::put_artifact( $workflow_id, $artifact_key, $content, $kind = 'json', $step_index = null, $metadata = [] )`

Shrani en trajni artefakt za potek dela.

```php
Queuety::put_artifact(
    $workflow_id,
    'research_brief',
    [ 'summary' => 'done' ],
    'json',
    metadata: [ 'source' => 'agent' ],
);
```

### `Queuety::put_current_artifact( $artifact_key, $content, $kind = 'json', $metadata = [] )`

Shrani en artefakt za trenutno izvajani korak poteka dela.

```php
Queuety::put_current_artifact(
    'draft',
    [ 'status' => 'ready' ],
    'json',
);
```

### `Queuety::workflow_artifact( $workflow_id, $artifact_key )`

Pridobi en shranjeni artefakt za potek dela.

```php
$artifact = Queuety::workflow_artifact( $workflow_id, 'draft' );
```

### `Queuety::workflow_artifacts( $workflow_id, $include_content = false )`

Prikaži seznam artefaktov za potek dela.

```php
$artifacts = Queuety::workflow_artifacts( $workflow_id );
```

### `Queuety::delete_workflow_artifact( $workflow_id, $artifact_key )`

Izbriši en artefakt za potek dela.

```php
Queuety::delete_workflow_artifact( $workflow_id, 'draft' );
```

## Avtomati stanj

### `Queuety::machine( $name )`

Začni graditi avtomat stanj. Vrne `StateMachineBuilder`.

```php
use Queuety\Enums\StateMachineStatus;

$machine_id = Queuety::machine( 'agent_session' )
    ->state( 'awaiting_user' )
    ->on( 'user_message', 'planning' )
    ->state( 'planning' )
    ->action( PlanSessionAction::class )
    ->on( 'planned', 'completed' )
    ->state( 'completed', StateMachineStatus::Completed )
    ->dispatch( [ 'thread_id' => 42 ] );
```

### Metode `StateMachineBuilder`

| Metoda | Opis |
|---|---|
| `initial( string $state_name )` | Izrecno nastavi začetno stanje. |
| `state( string $state_name, ?StateMachineStatus $terminal_status = null )` | Začni konfigurirati eno stanje. |
| `action( string\|array $action_class )` | Registriraj dejanje ob vstopu v trenutno stanje, ki se doda v čakalno vrsto. Podaj ime razreda ali strukturirano definicijo z `class`, `payload` in `config`; `payload` doseže `StateAction::handle()` kot `$payload`. |
| `on( string $event, string $target, string\|array\|null $guard_class = null, ?string $name = null )` | Registriraj en prehod dogodka iz trenutnega stanja. Varovalo sprejme enako strukturirano obliko kot `action()`. |
| `on_queue( string $queue )` | Nastavi čakalno vrsto za dejanja stanj, ki se dodajo vanjo. |
| `with_priority( Priority $priority )` | Nastavi prednost dejanj stanj, dodanih v čakalno vrsto. |
| `max_attempts( int $max_attempts )` | Nastavi omejitev ponovnih poskusov za dejanja stanj, dodana v čakalno vrsto. |
| `version( string $version )` | Definiciji avtomata dodeli različico na ravni aplikacije. |
| `idempotency_key( string $key )` | Zagotovi trajnost odpošiljanja s ključem, ki ga poda klicatelj. Ponovno odpošiljanje z istim ključem vrne izvirni ID avtomata. |
| `dispatch( array $initial_state = [] )` | Odpošlji avtomat in vrni njegov ID. |

Razredi dejanj ob vstopu v stanje lahko razkrijejo tudi izbirno metodo `config()` z enakimi ključi pravilnikov virov, kot jih podpirajo koraki poteka dela: `concurrency_group`, `concurrency_limit` in `cost_units`.

### `Queuety::dispatch_state_machine_definition( $definition, $initial_state = [], $options = [] )`

Odpošlji paket definicije serializiranega avtomata stanj. Večina kode aplikacije naj raje uporabi `machine()->dispatch()`. Ta metoda nižje ravni je namenjena adapterjem, ki želijo zagnati avtomat brez neposredne odvisnosti od gradnika.

```php
$machine_id = Queuety::dispatch_state_machine_definition(
    $definition,
    [ 'thread_id' => 42 ],
    [ 'idempotency_key' => 'thread:42' ],
);
```

### `Queuety::machine_status( $machine_id )`

Pridobi trenutno stanje avtomata. Vrne objekt `StateMachineState` ali `null`.

```php
$status = Queuety::machine_status( $machine_id );

echo $status->name;               // 'agent_session'
echo $status->status->value;      // 'waiting_event'
echo $status->current_state;      // 'awaiting_review'
print_r( $status->state );        // public machine state
print_r( $status->available_events ); // valid incoming events in the current state
```

`StateMachineState` razkriva tudi:

- `definition_version`
- `definition_hash`
- `idempotency_key`
- `error_message`
- `current_action`
- `terminal_status`

### `Queuety::machine_event( $machine_id, $event_name, $payload = [] )`

Pošlji en zunanji dogodek čakajočemu avtomatu.

```php
Queuety::machine_event(
    $machine_id,
    'approve',
    [
        'approved' => true,
        'reviewer' => 'editor@example.com',
    ]
);
```

Podatki so na voljo varovalom prehodov in se združijo z javnim stanjem avtomata, ko je dogodek sprejet.

### `Queuety::list_machines( $limit = 50, $status = null )`

Prikaži seznam shranjenih vrstic avtomatov za pregled.

```php
$machines = Queuety::list_machines();
$waiting  = Queuety::list_machines( status: 'waiting_event' );
```

Vsaka vrstica vključuje ID avtomata, ime, stanje, trenutno stanje avtomata, različico definicije, zgoščeni odtis definicije, idempotentni ključ in časovne oznake življenjskega cikla.

### `Queuety::machine_timeline( $machine_id, $limit = 100, $offset = 0 )`

Pridobi trajno časovnico dogodkov za en avtomat.

```php
$timeline = Queuety::machine_timeline( $machine_id );
$page_two = Queuety::machine_timeline( $machine_id, 100, 100 );
```

Vsaka vrstica dogodka vsebuje: `id`, `machine_id`, `job_id`, `state_name`, `handler`, `event`, `event_name`, `transition_name`, `queue`, `attempt`, `input`, `output`, `state_before`, `state_after`, `context`, `artifacts`, `chunks`, `error`, `duration_ms` in `created_at`.

### `Queuety::machine_trace( $machine_id )`

Pridobi normaliziran sveženj sledi za razhroščevalnik avtomata stanj UI.

```php
$trace = Queuety::machine_trace( $machine_id );
```

Sled vsebuje `machine`, združene `states`, neobdelane `events`, povezana dejanja `jobs`, `logs`, `artifacts` in `chunks`.

### `Queuety::machine_state_at( $machine_id, $event_id )`

Pridobi javno stanje po določenem dogodku sledi avtomata ali `null`, če ni najdeno.

```php
$state = Queuety::machine_state_at( $machine_id, $event_id );
```

Model življenjskega cikla in vzorce uporabe najdete v razdelku [Avtomati stanj](https://queuety.inline0.dev/sl/docs/state-machines).

## Predloge potekov dela

### `Queuety::define_workflow( $name )`

Ustvari gradnik poteka dela za uporabo kot predlogo.

```php
$builder = Queuety::define_workflow( 'onboarding' )
    ->then( CreateAccountHandler::class )
    ->then( SendWelcomeEmailHandler::class );
```

### `Queuety::register_workflow_template( $builder )`

Registriraj predlogo poteka dela.

```php
Queuety::register_workflow_template( $builder );
```

### `Queuety::run_workflow( $name, $payload, $options = [] )`

Odpošlji registrirano predlogo poteka dela po imenu. Vrne ID poteka dela.

```php
$workflow_id = Queuety::run_workflow( 'onboarding', [ 'email' => 'user@example.com' ] );

$workflow_id = Queuety::run_workflow(
    'onboarding',
    [ 'email' => 'user@example.com' ],
    [ 'idempotency_key' => 'onboarding:user@example.com' ],
);
```

Sproži `RuntimeException`, če predloga ni registrirana.

### `Queuety::dispatch_workflow_definition( $definition, $payload, $options = [] )`

Odpošlji potek dela iz paketa definicije izvajalnega okolja.

Večina kode aplikacije naj raje uporabi `run_workflow()` ali `workflow()->dispatch()`. Ta metoda nižje ravni omogoča, da lahko znova uporabni adapterji odpošljejo serializirano definicijo poteka dela brez odvisnosti od notranjih metod upravljalnika potekov dela.

```php
$workflow_id = Queuety::dispatch_workflow_definition(
    $definition,
    [ 'email' => 'user@example.com' ],
    [ 'idempotency_key' => 'onboarding:user@example.com' ],
);
```

### `Queuety::on_action( $hook, $workflow, $map = null, $when = null, $idempotency_key = null, $priority = 10, $accepted_args = null )`

Registriraj dejanje WordPress, ki odpošlje potek dela.

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

`$workflow` je lahko eno od naslednjega:

- ime registrirane predloge poteka dela
- vstavljeni `WorkflowBuilder`

`map`, `when` in `idempotency_key` se izvajajo sinhrono v trenutni zahtevi WordPress. Po odpošiljanju se asinhrono izvajajo samo koraki poteka dela.

Celoten vodič najdete v razdelku [Sprožilniki dejanj](https://queuety.inline0.dev/sl/docs/features/action-triggers).

### `Queuety::workflow_templates()`

Pridobi register predlog potekov dela.

```php
$registry = Queuety::workflow_templates();
$template = $registry->get( 'onboarding' ); // WorkflowTemplate or null
```

### `Queuety::load_workflows( $directory, $recursive )`

Naloži in registriraj vse datoteke potekov dela iz imenika. Vsaka datoteka `.php` mora vrniti `WorkflowBuilder`. Vrne število registriranih potekov dela.

```php
$count = Queuety::load_workflows( __DIR__ . '/workflows/' );
$count = Queuety::load_workflows( __DIR__ . '/workflows/', recursive: true );
```

### `Queuety::load_workflow_file( $file_path )`

Naloži in registriraj eno datoteko poteka dela. Vrne `WorkflowTemplate` ali `null`, če datoteka ne vrne gradnika.

```php
$template = Queuety::load_workflow_file( __DIR__ . '/workflows/onboard-user.php' );
```

## Razporejanje

### `Queuety::schedule( $handler, $payload )`

Ustvari ponavljajoči se razpored. Vrne gradnik `PendingSchedule`.

```php
Queuety::schedule( 'cleanup_handler' )
    ->every( '1 hour' )
    ->on_queue( 'maintenance' );

Queuety::schedule( 'nightly_report' )
    ->cron( '0 3 * * *' )
    ->on_queue( 'reports' );
```

### Metode `PendingSchedule`

| Metoda | Opis |
|---|---|
| `every( string $interval )` | Nastavi izraz intervala (e.g, `1 hour`, `30 minutes`) |
| `cron( string $expression )` | Nastavi izraz cron s 5 polji |
| `overlap( OverlapPolicy $policy )` | Nastavi pravilnik prekrivanja (privzeto: `Allow`). Glejte [Razporejanje](https://queuety.inline0.dev/sl/docs/features/scheduling). |
| `on_queue( string $queue )` | Nastavi ciljno čakalno vrsto (privzeto: `default`) |
| `id()` | Vsili odpošiljanje in vrni ID razporeda |

### `Queuety::scheduler()`

Pridobi notranji primerek `Scheduler`.

```php
$scheduler = Queuety::scheduler();
$schedules = $scheduler->list();
$scheduler->remove( 'handler_name' );
$count = $scheduler->tick(); // manually trigger
```

## Registracija obravnavalnikov

### `Queuety::register( $name, $class )`

Registriraj razred obravnavalnika pod imenom.

```php
Queuety::register( 'send_email', SendEmailHandler::class );
```

### `Queuety::discover_handlers( $directory, $namespace )`

Samodejno odkrij in registriraj razrede obravnavalnikov iz imenika. Vrne število registriranih obravnavalnikov.

```php
$count = Queuety::discover_handlers( __DIR__ . '/handlers', 'MyPlugin\\Handlers' );
```

### `Queuety::registry()`

Pridobi register obravnavalnikov.

```php
$registry = Queuety::registry();
```

## Opazljivost

### `Queuety::logger()`

Pridobi primerek `Logger` za poizvedovanje po vnosih v dnevniku.

```php
$logger = Queuety::logger();
$logs   = $logger->for_job( 42 );
$logs   = $logger->for_workflow( 7 );
$logs   = $logger->for_handler( 'send_email', 50 );
$logs   = $logger->for_event( LogEvent::Failed, 50 );
$logs   = $logger->since( new \DateTimeImmutable( '-1 hour' ), 100 );
$count  = $logger->purge( 30 );
```

### `Queuety::metrics()`

Pridobi primerek `Metrics`.

```php
$stats = Queuety::metrics()->handler_stats( 60 ); // last 60 minutes
```

### `Queuety::webhook_notifier()`

Pridobi primerek `WebhookNotifier`.

```php
$notifier = Queuety::webhook_notifier();
$id       = $notifier->register( 'job.buried', 'https://hooks.slack.com/...' );
$webhooks = $notifier->list();
$notifier->remove( $id );
```

### `Queuety::rate_limiter()`

Pridobi primerek `RateLimiter`.

```php
$limiter = Queuety::rate_limiter();
$limiter->register( 'call_openai', 60, 60 );
```

## Predpomnilnik

### `Queuety::cache()`

Pridobi primerek aktivnega zalednega sistema predpomnilnika.

```php
$cache = Queuety::cache();
$cache->set( 'my_key', 'my_value', 60 );
$value = $cache->get( 'my_key' );
```

### `Queuety::set_cache( $cache )`

Zamenjaj zaledni sistem predpomnilnika. To storite pred `Queuety::init()`, če želite uporabiti prilagojeno izvedbo.

```php
Queuety::set_cache( new RedisCache() );
Queuety::init( $connection );
```

### `QUEUETY_CACHE_TTL`

Privzeti TTL predpomnilnika v sekundah (privzeto: `5`). Nastavite to konstanto v `wp-config.php`, da spremenite privzeti TTL, ki ga uporabljajo notranje operacije predpomnilnika.

```php
define( 'QUEUETY_CACHE_TTL', 10 );
```

Podrobnosti o zalednih sistemih in samodejnem zaznavanju najdete v razdelku [Predpomnjenje](https://queuety.inline0.dev/sl/docs/features/caching).

## Dnevnik dogodkov avtomata stanj

### `Queuety::machine_events()`

Pridobi primerek `StateMachineEventLog`.

```php
$log = Queuety::machine_events();
```

## Dnevnik dogodkov poteka dela

### `Queuety::workflow_events()`

Pridobi primerek `WorkflowEventLog`.

```php
$log = Queuety::workflow_events();
```

### `Queuety::workflow_timeline( $workflow_id, $limit = 100, $offset = 0 )`

Pridobi celotno časovnico dogodkov za potek dela. Vrne matriko vrstic dogodkov, razvrščenih po ID-ju.

```php
$events = Queuety::workflow_timeline( $workflow_id );
$next   = Queuety::workflow_timeline( $workflow_id, 100, 100 );
```

Vsaka vrstica dogodka vsebuje: `id`, `workflow_id`, `job_id`, `parent_event_id`, `step_index`, `step_name`, `step_type`, `handler`, `event`, `queue`, `attempt`, `input`, `output`, `state_before`, `state_after`, `context`, `artifacts`, `chunks`, `error`, `error_message` (kopirano iz `error.message`), `duration_ms` in `created_at`.

### `Queuety::workflow_trace( $workflow_id )`

Pridobi normaliziran sveženj sledi za razhroščevalnik poteka dela UI.

```php
$trace = Queuety::workflow_trace( $workflow_id );
```

Sled vsebuje `workflow`, združene `steps`, neobdelane `events`, `jobs`, `logs`, `artifacts`, `chunks`, `signals` in `wait_dependencies`.

### `Queuety::trace_input( $input )`

Nastavi vhod na ravni aplikacije za trenutno izvajani korak poteka dela.

### `Queuety::trace_output( $output )`

Nastavi izhod na ravni aplikacije za trenutno izvajani korak poteka dela.

### `Queuety::trace_context( array $context )`

Združi kontekst na ravni aplikacije s trenutno izvajanim korakom poteka dela.

### `Queuety::workflow_state_at( $workflow_id, $step_index )`

Pridobi javno stanje po dokončanem ali nadaljevanem določenem koraku poteka dela ali `null`, če ni najdeno.

```php
$state = Queuety::workflow_state_at( $workflow_id, 2 );
```

Primere uporabe in ukaze CLI najdete v razdelku [Dnevnik dogodkov poteka dela](https://queuety.inline0.dev/sl/docs/workflows/event-log).

## Notranji primerki

Te metode vrnejo notranje primerke za naprednejše primere uporabe.

| Metoda | Vrne | Opis |
|---|---|---|
| `Queuety::queue()` | `Queue` | Operacije čakalne vrste (prevzem, sprostitev, skrivanje) |
| `Queuety::worker()` | `Worker` | Upravljanje delovnega procesa |
| `Queuety::workflow_manager()` | `Workflow` | Orkestracija potekov dela |
| `Queuety::machines()` | `StateMachine` | Upravljanje življenjskega cikla avtomata stanj |
| `Queuety::connection()` | `Connection` | Povezava z zbirko podatkov |
| `Queuety::batch_manager()` | `BatchManager` | Upravljanje življenjskega cikla paketov (preklic, obrezovanje) |
| `Queuety::chunk_store()` | `ChunkStore` | Shranjevanje kosov za pretočne korake |
| `Queuety::machine_events()` | `StateMachineEventLog` | Dogodki sledi avtomata stanj in normalizirani svežnji sledi |
| `Queuety::workflow_events()` | `WorkflowEventLog` | Dogodki sledi poteka dela in normalizirani svežnji sledi |
| `Queuety::resource_manager()` | `ResourceManager` | Profili sprejemanja delavcev, uteženi proračuni in pregled sistemskega pomnilnika |
| `Queuety::cache()` | `Cache` | Primerek zalednega sistema predpomnilnika |

## Testiranje

### `Queuety::fake()`

Za testiranje zamenjaj čakalno vrsto s ponaredkom v pomnilniku. Vrne primerek `QueueFake`, ki beleži odposlana opravila, ne da bi dostopal do zbirke podatkov. `create_batch()` beleži tudi lažne metapodatke paketov; verige se preverjajo prek posameznih potisnjenih opravil, ki jih odpošljejo.

```php
$fake = Queuety::fake();
SendEmailJob::dispatch( 'user@example.com', 'Hello', 'Hi!' );
$fake->assert_pushed( SendEmailJob::class );
```

### `Queuety::reset()`

Ponastavi vse notranje stanje, vključno s ponaredkom čakalne vrste. Pokliči v `tearDown()`.

```php
Queuety::reset();
```

### Metode `QueueFake`

| Metoda | Opis |
|---|---|
| `assert_pushed( string $class, ?Closure $callback )` | Preveri, ali je bilo opravilo danega razreda potisnjeno. Izbirni povratni klic filtrira podatke opravila. |
| `assert_pushed_times( string $class, int $count )` | Preveri, ali je bilo opravilo potisnjeno natanko N-krat. |
| `assert_not_pushed( string $class )` | Preveri, ali opravilo nikoli ni bilo potisnjeno. |
| `assert_nothing_pushed()` | Preveri, ali ni bilo potisnjeno nobeno opravilo. |
| `assert_batched( ?Closure $callback )` | Preveri, ali je bil paket odposlan. Izbirni povratni klic filtrira podatke paketa. |
| `pushed( string $class )` | Pridobi vse zabeležene odpošiljanja za razred. Vrne matriko. |
| `batches()` | Pridobi vse zabeležene pakete. Vrne matriko. |
| `reset()` | Počisti vsa zabeležena opravila in pakete. |

Celotne primere najdete v razdelku [Testiranje](https://queuety.inline0.dev/sl/docs/features/testing).

## Vmesniki

### `Handler`

Vmesnik za preproste obravnavalnike opravil.

```php
interface Handler {
    public function handle( array $payload ): void;
    public function config(): array;
}
```

`config()` lahko vrne `queue`, `max_attempts`, `backoff`, `rate_limit`, `concurrency_group`, `concurrency_limit` in `cost_units`.

### `Step`

Vmesnik za obravnavalnike korakov poteka dela.

```php
interface Step {
    public function handle( array $state ): array;
    public function config(): array;
}
```

`config()` lahko vrne `max_attempts`, `backoff`, `concurrency_group`, `concurrency_limit` in `cost_units`.

### `Contracts\ForEachHandler`

Vmesnik za obravnavalnike dinamičnih vej zanke for-each.

```php
namespace Queuety\Contracts;

interface ForEachHandler {
    public function handle_item( array $state, mixed $item, int $index ): array;
    public function config(): array;
}
```

`config()` lahko vrne `max_attempts`, `backoff`, `rate_limit`, `concurrency_group`, `concurrency_limit` in `cost_units`.

### `Contracts\ForEachReducer`

Izbirna funkcija za združevanje rezultatov zanke for-each.

```php
namespace Queuety\Contracts;

interface ForEachReducer {
    public function reduce( array $state, array $for_each ): array;
}
```

### `Contracts\Compensation`

Vmesnik za obravnavalnike kompenzacije korakov.

```php
namespace Queuety\Contracts;

interface Compensation {
    public function handle( array $state ): void;
}
```

### `Contracts\RepeatCondition`

Vmesnik za predikate zank, ki jih uporabljata `repeat_until()` in `repeat_while()`, kadar je primerjava s ključem stanja preveč omejena.

```php
namespace Queuety\Contracts;

interface RepeatCondition {
    public function matches( array $state ): bool;
}
```

### `Contracts\StateAction`

Vmesnik za dejanja ob vstopu v stanje, ki se dodajo v čakalno vrsto.

```php
namespace Queuety\Contracts;

interface StateAction {
    public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string;
}
```

`$payload` vsebuje strukturirano `payload` iz definicije dejanja, če je bil avtomat tako določen. Vrni posodobitve javnega stanja. Vključi `_event` in po želji `_event_payload`, če naj dejanje takoj sproži prehod.

Dejanja stanj lahko določijo tudi izbirno metodo `config()`. Queuety ob dodajanju dejanja ob vstopu v čakalno vrsto iz nje prebere `concurrency_group`, `concurrency_limit` in `cost_units`.

### `Contracts\StateGuard`

Vmesnik za varovala prehodov avtomata stanj.

```php
namespace Queuety\Contracts;

interface StateGuard {
    public function allows( array $state, array $event_payload, string $event, array $payload = [] ): bool;
}
```

### `Contracts\Job`

Vmesnik za samostojne razrede opravil, ki jih je mogoče odpošiljati. Razredi opravil shranijo svoje podatke v javnih lastnostih, logiko izvajanja pa v `handle()`.

```php
namespace Queuety\Contracts;

interface Job {
    public function handle(): void;
}
```

Razredi opravil lahko po želji določijo metodo `middleware()`, ki vrne matriko primerkov `Contracts\Middleware`.

### `Contracts\Cache`

Vmesnik za zaledne sisteme predpomnilnika. Vgrajene izvedbe in prilagojene zaledne sisteme najdete v razdelku [Predpomnjenje](https://queuety.inline0.dev/sl/docs/features/caching).

```php
namespace Queuety\Contracts;

interface Cache {
    public function get( string $key ): mixed;
    public function set( string $key, mixed $value, int $ttl = 0 ): void;
    public function delete( string $key ): void;
    public function has( string $key ): bool;
    public function add( string $key, mixed $value, int $ttl = 0 ): bool;
    public function flush(): void;
}
```

| Metoda | Vrne | Opis |
|---|---|---|
| `get( $key )` | `mixed` | Pridobi vrednost. Če je ni mogoče najti ali je potekla, vrne `null`. |
| `set( $key, $value, $ttl )` | `void` | Shrani vrednost. TTL 0 pomeni, da vrednost ne poteče. |
| `delete( $key )` | `void` | Odstrani vrednost. |
| `has( $key )` | `bool` | Preveri, ali ključ obstaja in mu še ni potekla veljavnost. |
| `add( $key, $value, $ttl )` | `bool` | Atomsko nastavi vrednost samo, če še ne obstaja. Vrne `true`, če je bila vrednost nastavljena. |
| `flush()` | `void` | Iz predpomnilnika odstrani vse elemente. |

### `WorkflowEventLog`

Beleži prehode korakov poteka dela s celotnim kontekstom sledi. Dostop prek `Queuety::workflow_events()`.

| Metoda | Vrne | Opis |
|---|---|---|
| `record_event( array $event )` | `void` | Zabeleži neobdelani dogodek sledi |
| `record_step_started( ... )` | `void` | Zabeleži dogodek step_started z vhodom in stanjem pred izvajanjem |
| `record_step_completed( ... )` | `void` | Zabeleži dogodek step_completed z vhodom, izhodom, stanjem pred in stanjem po izvajanju |
| `record_step_failed( ... )` | `void` | Zabeleži dogodek step_failed s kontekstom sledi in strukturiranimi podrobnostmi o napaki |
| `get_timeline( int $workflow_id, ?int $limit = 100, int $offset = 0 )` | `array` | Pridobi dogodke sledi poteka dela po vrstnem redu, po želji z razdeljevanjem na strani |
| `get_trace( int $workflow_id )` | `array` | Pridobi normaliziran sveženj sledi |
| `get_state_at_step( int $workflow_id, int $step_index )` | `array\|null` | Pridobi javno stanje po dokončanem ali nadaljevanem določenem koraku |
| `prune( int $older_than_days )` | `int` | Izbriše dogodke, starejše od podanega števila dni. Vrne število izbrisanih vrstic. |

### `StateMachineEventLog`

Beleži dogodke življenjskega cikla, dejanj, prehodov in varoval avtomata stanj z enakimi polji sledi kot dogodki poteka dela.

| Metoda | Vrne | Opis |
|---|---|---|
| `record_event( array $event )` | `void` | Zabeleži neobdelan dogodek strojne sledi |
| `get_timeline( int $machine_id, ?int $limit = 100, int $offset = 0 )` | `array` | Pridobi dogodke strojne sledi po vrsti, z neobveznim ostranjevanjem |
| `get_trace( int $machine_id )` | `array` | Pridobi normaliziran sveženj strojne sledi |
| `get_state_at_event( int $machine_id, int $event_id )` | `array\|null` | Pridobi javno stanje po določenem dogodku strojne sledi |
| `prune( int $older_than_days )` | `int` | Izbriše dogodke, starejše od podanega števila dni. Vrne število izbrisanih vrstic. |

### `Contracts\StreamingStep`

Vmesnik za obravnavalnike korakov poteka dela, ki ustvarjajo tok kosov. Vsaka oddana vrednost se takoj shrani v zbirko podatkov. Glejte [Koraki s tokom](https://queuety.inline0.dev/sl/docs/workflows/streaming).

```php
namespace Queuety\Contracts;

interface StreamingStep {
    public function stream( array $state, array $existing_chunks = [] ): \Generator;
    public function on_complete( array $chunks, array $state ): array;
    public function config(): array;
}
```

| Metoda | Opis |
|---|---|
| `stream( $state, $existing_chunks )` | Generator, ki oddaja nize kosov. Vsaka oddaja sproži takojšen zapis v zbirko podatkov. Ob ponovnem poskusu `$existing_chunks` vsebuje predhodno shranjene kose. |
| `on_complete( $chunks, $state )` | Pokliče se po koncu toka. Vrne podatke, ki se združijo s stanjem poteka dela. |
| `config()` | Neobvezna konfiguracija. Podpira `max_attempts`, `backoff`, `concurrency_group`, `concurrency_limit` in `cost_units`. |

### `ChunkStore`

Upravlja shranjevanje kosov za korake s tokom. Dostop prek `Queuety::chunk_store()`.

| Metoda | Vrne | Opis |
|---|---|---|
| `get_chunks( int $job_id )` | `string[]` | Pridobi vse kose za opravilo, urejene po indeksu kosa |
| `append_chunk( int $job_id, int $chunk_index, string $content, ?int $workflow_id, ?int $step_index )` | `void` | Doda en kos |
| `clear_chunks( int $job_id )` | `void` | Izbriše vse kose za opravilo |
| `chunk_count( int $job_id )` | `int` | Prešteje kose za opravilo |
| `get_accumulated( int $job_id )` | `string` | Združi vse kose v en niz |

### `Heartbeat`

Statični pomočnik za pošiljanje signalov dejavnosti iz obravnavalnikov korakov in korakov s tokom. Glejte [Signali dejavnosti](https://queuety.inline0.dev/sl/docs/features/heartbeats).

| Metoda | Opis |
|---|---|
| `Heartbeat::init( int $job_id, Connection $conn )` | Nastavi kontekst opravila. Delavec ga pokliče samodejno. |
| `Heartbeat::beat( array $progress = [] )` | Pošlje signal dejavnosti. Posodobi `reserved_at` in po želji shrani podatke o napredku v `heartbeat_data`. |
| `Heartbeat::clear()` | Počisti kontekst opravila. Delavec ga pokliče samodejno. |
| `Heartbeat::current_job_id()` | Pridobi trenutni ID opravila (za preizkušanje). |

### `Contracts\Middleware`

Vmesnik za vmesno programsko opremo opravil. Vmesna programska oprema ovije izvajanje opravila v cevovod v slogu čebule.

```php
namespace Queuety\Contracts;

interface Middleware {
    public function handle( object $job, \Closure $next ): void;
}
```

## Značilnosti

### `Dispatchable`

Zagotavlja statične metode za odpošiljanje v razredih opravil, ki implementirajo `Contracts\Job`. Argumenti konstruktorja se posredujejo za ustvarjanje primerka opravila.

```php
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

class SendEmailJob implements Job {
    use Dispatchable;
    // ...
}

// Dispatches a new SendEmailJob instance
SendEmailJob::dispatch( 'user@example.com', 'Subject', 'Body' );
```

| Metoda | Vrne | Opis |
|---|---|---|
| `dispatch( ...$args )` | `PendingJob` | Ustvari primerek in ga odpošlje |
| `dispatch_if( bool $condition, ...$args )` | `PendingJob\|null` | Odpošlje samo, če je `$condition` resničen |
| `dispatch_unless( bool $condition, ...$args )` | `PendingJob\|null` | Odpošlje samo, če je `$condition` neresničen |
| `with_chain( array $jobs )` | `ChainBuilder` | Začne verigo iz tega razreda opravil |

```php
// Conditional dispatch
SendEmailJob::dispatch_if( $user->wants_email, $user->email, 'Hello', 'Hi!' );
SendEmailJob::dispatch_unless( $maintenance_mode, $user->email, 'Hello', 'Hi!' );

// Chain from a job class
FetchDataJob::with_chain( [
    new ProcessDataJob(),
    new NotifyCompleteJob(),
] )->dispatch();
```

### Lastnosti opravil

Razredi opravil lahko določijo javne lastnosti, ki jih delavec prebere z refleksijo, da preglasi vedenje pri ponovnih poskusih in časovnih omejitvah.

| Lastnost | Vrsta | Opis |
|---|---|---|
| `$tries` | `int` | Največje število poskusov, preden se opravilo prestavi v arhiv |
| `$timeout` | `int` | Najdaljši čas izvajanja v sekundah (zahteva `pcntl`) |
| `$backoff` | `array` | Naraščajoče vrednosti zakasnitve v sekundah za vsak ponovni poskus |

```php
class ImportProductsJob implements Job {
    use Dispatchable;

    public int $tries = 5;
    public int $timeout = 120;
    public array $backoff = [ 10, 30, 60, 120 ];

    // ...
}
```

### Kavelj `failed()`

Ko je opravilo po izčrpanju vseh ponovnih poskusov prestavljeno v arhiv, delavec pokliče metodo `failed()` primerka opravila, če je določena.

```php
public function failed( \Throwable $exception ): void {
    error_log( "Job failed: {$exception->getMessage()}" );
}
```

## Vgrajena vmesna programska oprema

Vsi razredi vmesne programske opreme implementirajo `Contracts\Middleware` in so v imenskem prostoru `Queuety\Middleware`.

| Razred | Opis |
|---|---|
| `RateLimited( int $max, int $window )` | Uveljavi omejitev hitrosti `$max` izvajanj na `$window` sekund |
| `Timeout( int $seconds )` | Konča opravilo po `$seconds` sekundah (zahteva `pcntl`) |
| `UniqueJob( ?string $key )` | Prepreči sočasno izvajanje z zaklepanjem zbirke podatkov |
| `WithoutOverlapping( string $key, int $release_after )` | Prepreči prekrivanje izvajanj s samodejnim potekom zaklepa |
| `ThrottlesExceptions( int $max_attempts, int $decay_minutes )` | Omejuje izjeme, da prepreči poplavo opravil, ko zunanja storitev ne deluje |

Za podrobnosti o uporabi in primere glejte [Vmesna programska oprema](https://queuety.inline0.dev/sl/docs/features/middleware).

## Naštevanja

### `Priority`

```php
enum Priority: int {
    case Low    = 0;
    case Normal = 1;
    case High   = 2;
    case Urgent = 3;
}
```

### `JobStatus`

```php
enum JobStatus: string {
    case Pending    = 'pending';
    case Processing = 'processing';
    case Completed  = 'completed';
    case Failed     = 'failed';
    case Buried     = 'buried';
}
```

### `WorkflowStatus`

```php
enum WorkflowStatus: string {
    case Running        = 'running';
    case Completed      = 'completed';
    case Failed         = 'failed';
    case Paused         = 'paused';
    case WaitingForSignal  = 'waiting_for_signal';
    case WaitingForWorkflows = 'waiting_for_workflows';
    case Cancelled      = 'cancelled';
}
```

### `StateMachineStatus`

```php
enum StateMachineStatus: string {
    case Running = 'running';
    case WaitingEvent = 'waiting_event';
    case Completed = 'completed';
    case Failed = 'failed';
    case Paused = 'paused';
    case Cancelled = 'cancelled';
}
```

### `BackoffStrategy`

```php
enum BackoffStrategy: string {
    case Fixed       = 'fixed';
    case Linear      = 'linear';
    case Exponential = 'exponential';
}
```

### `ForEachMode`

```php
enum ForEachMode: string {
    case All = 'all';
    case FirstSuccess = 'first_success';
    case Quorum = 'quorum';
}
```

### `WaitMode`

```php
enum WaitMode: string {
    case All    = 'all';
    case Any    = 'any';
    case Quorum = 'quorum';
}
```

### `LogEvent`

```php
enum LogEvent: string {
    case Started                  = 'started';
    case Completed                = 'completed';
    case Failed                   = 'failed';
    case Buried                   = 'buried';
    case Retried                  = 'retried';
    case WorkflowStarted          = 'workflow_started';
    case WorkflowCompleted        = 'workflow_completed';
    case WorkflowFailed           = 'workflow_failed';
    case WorkflowPaused           = 'workflow_paused';
    case WorkflowResumed          = 'workflow_resumed';
    case WorkflowCancelled        = 'workflow_cancelled';
    case WorkflowRewound          = 'workflow_rewound';
    case WorkflowForked           = 'workflow_forked';
    case WorkflowDeadlineExceeded = 'workflow_deadline_exceeded';
    case Debug                    = 'debug';
}
```

### `OverlapPolicy`

```php
enum OverlapPolicy: string {
    case Allow  = 'allow';
    case Skip   = 'skip';
    case Buffer = 'buffer';
}
```

Za podrobnosti o delovanju posameznih pravilnikov glejte [Načrtovanje](https://queuety.inline0.dev/sl/docs/features/scheduling).

## Atributi

### `#[QueuetyHandler]`

PHP Atribut 8 za samodejno registracijo. Glejte [PHP Atributi](https://queuety.inline0.dev/sl/docs/features/attributes).

```php
use Queuety\Attributes\QueuetyHandler;

#[QueuetyHandler( name: 'send_email', queue: 'emails', max_attempts: 5 )]
class SendEmailHandler implements Handler {
    // ...
}
```

## Most CLI

### `Queuety::cli_command()`

Vrne objavljeno ime korenskega ukaza WP-CLI.

Privzeti korenski ukaz je `queuety`. Določite `QUEUETY_CLI_COMMAND`, preden se zažene Queuety, če naj bo ukaz objavljen pod drugim imenom.

### `Queuety::cli_command_map()`

Vrne serializljiv katalog Queuety CLI za preizkuševalna ogrodja, ki morajo poznati objavljene ukaze, ne da bi pregledovala razrede WP-CLI.

Vsak vnos vključuje:
- stabilni ID operacije
- relativno pot CLI
- razred in metodo obravnavalnika WP-CLI
- možne cilje izvajanja
- prilagojevalnik, ki normalizira neobdelane argumente CLI v načrt izvajanja

### `Queuety::resolve_cli_command( $path, $args, $assoc_args )`

Pretvori razčlenjen priklic CLI v načrt izvajanja, ki naj ga zažene preizkuševalno ogrodje.

```php
$plan = Queuety::resolve_cli_command(
    [ 'workflow', 'export' ],
    [ '42' ],
    [ 'output' => '/tmp/workflow.json' ]
);

echo $plan['callable']; // Queuety\Queuety::export_workflow_to_file
print_r( $plan['arguments'] );
```

Načrti izvajanja se namenoma zavedajo prenosa:
- ukazi se razrešijo v javne klicne elemente PHP z normaliziranimi argumenti
- katalog vnaprej navaja vse možne cilje izvajanja, medtem ko `callable` in `transport` določita vejo, izbrano za razčlenjeni vhod

To je standardna raba Queuety za preizkuševalna ogrodja agentov: stabilni ID operacije, javni cilj API in normalizacija, za katero skrbi prilagojevalnik, za posebnosti, značilne samo za CLI, kot so privzete nastavitve čakalne vrste, dekodiranje koristne vsebine JSON, razvejanje skupine delavcev in obravnava datotek izvoza poteka dela.
