
## Fluxuri de lucru într-un singur fișier

Un flux de lucru poate fi complet autonom într-un singur fișier PHP. Definiți împreună clasele pașilor și constructorul, puneți fișierul într-un director și încărcați directorul cu `Queuety::load_workflows()` (prezentat mai jos). Queuety nu scanează niciun director de unul singur.

```php
// workflows/onboard-user.php
use Queuety\Queuety;

class CreateAccount implements \Queuety\Step {
    public function handle(array $state): array {
        $user = create_user($state['email']);
        return ['user_id' => $user->id, 'user_name' => $user->name];
    }
    public function config(): array {
        return ['max_attempts' => 3];
    }
}

class SendWelcome implements \Queuety\Step {
    public function handle(array $state): array {
        wp_mail($state['email'], 'Welcome ' . $state['user_name'], '...');
        return ['welcomed' => true];
    }
    public function config(): array {
        return [];
    }
}

return Queuety::define_workflow('onboard_user')
    ->then(CreateAccount::class, 'create_account')
    ->then(SendWelcome::class, 'send_welcome');
```

Fișierul returnează un `WorkflowBuilder`. Fiecare clasă de pas este definită inline. La încărcarea fișierului, clasele devin disponibile, iar fluxul de lucru este înregistrat ca șablon.

## Încărcarea fluxurilor de lucru

Încărcați toate fișierele fluxurilor de lucru dintr-un director:

```php
// Load all .php files from the workflows directory
$count = Queuety::load_workflows(__DIR__ . '/workflows/');
```

Sau încărcați un singur fișier:

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

Apoi trimiteți fluxul de lucru după nume:

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

## Încărcare recursivă

Transmiteți `true` ca al doilea argument pentru a scana subdirectoarele:

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

Astfel, puteți organiza fluxurile de lucru în dosare:

```
workflows/
├── onboarding/
│   ├── new-user.php
│   └── trial-upgrade.php
├── reports/
│   ├── daily-summary.php
│   └── weekly-digest.php
└── notifications/
    └── digest-email.php
```

## Folosirea tuturor funcțiilor fluxurilor de lucru

Fluxurile de lucru din fișiere acceptă tot ce oferă constructorul, cu excepția `idempotency_key()`, care nu este stocat în șablon; transmiteți-l la fiecare trimitere cu `Queuety::run_workflow( $name, $payload, [ 'idempotency_key' => '...' ] )`. Întârzierile, semnalele, pașii paraleli, ramificarea condițională, rularea fluxurilor de lucru, handler-ele de anulare și reducerea stării sunt acceptate:

```php
// workflows/approval-flow.php
use Queuety\Queuety;

class SubmitRequest implements \Queuety\Step {
    public function handle(array $state): array {
        return ['submitted_at' => date('Y-m-d H:i:s')];
    }
    public function config(): array { return []; }
}

class ProcessApproval implements \Queuety\Step {
    public function handle(array $state): array {
        return [
            'approved_by' => $state['approved_by'],
            'processed' => true,
        ];
    }
    public function config(): array { return []; }
}

class CleanupRequest implements \Queuety\Handler {
    public function handle(array $payload): void {
        delete_pending_request($payload['request_id']);
    }
    public function config(): array { return []; }
}

return Queuety::define_workflow('approval_flow')
    ->then(SubmitRequest::class)
    ->delay(hours: 24)
    ->wait_for_signal('approved')
    ->then(ProcessApproval::class)
    ->on_cancel(CleanupRequest::class)
    ->prune_state_after(2);
```

## Când să folosiți fluxuri de lucru în fișiere

Fluxurile de lucru în fișiere sunt ideale când:

- Un LLM sau un generator de cod creează fluxuri de lucru programatic
- Fluxul de lucru este suficient de simplu încât să încapă într-un singur fișier
- Doriți să păstrați logica pașilor aproape de definiția fluxului de lucru
- Prototipați și doriți să iterați rapid

Pentru fluxurile de lucru mai mari, cu clase de pași partajate, middleware complex sau pași reutilizați în mai multe fluxuri de lucru, abordarea standard cu fișiere separate pentru clase și încărcare automată PSR-4 este mai ușor de întreținut.

## Cum funcționează

În culise, fluxurile de lucru cu fișiere folosesc exact același motor ca generatorul API. Fiecare pas este o sarcină separată în baza de date. Starea circulă prin tabelul `queuety_workflows`. Nu există reluare, cerință de determinism sau diferență de performanță.

Fiecare apel de încărcare `require`ă fișierul (nu `require_once`), așadar încărcați fiecare fișier o singură dată per solicitare; încărcarea lui de două ori redeclară clasele și provoacă o eroare. Valoarea `WorkflowBuilder` returnată este convertită într-un `WorkflowTemplate` și stocată în `WorkflowRegistry`. Expedierea și execuția sunt identice cu cele ale oricărui alt flux de lucru.
