
## Flussi di lavoro in un singolo file

Un flusso di lavoro può essere interamente contenuto in un unico file PHP. Definite insieme le classi dei passaggi e il builder, inserite il file in una directory e caricate quella directory con `Queuety::load_workflows()` (come mostrato sotto). Queuety non esegue la scansione di alcuna directory autonomamente.

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

Il file restituisce un `WorkflowBuilder`. Ogni classe di passaggio è definita inline. Quando il file viene caricato, le classi diventano disponibili e il flusso di lavoro viene registrato come modello.

## Caricare i flussi di lavoro

Caricate tutti i file dei flussi di lavoro da una directory:

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

Oppure caricate un singolo file:

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

Quindi eseguite il dispatch per nome:

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

## Caricamento ricorsivo

Passate `true` come secondo argomento per eseguire la scansione delle sottodirectory:

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

Questo consente di organizzare i flussi di lavoro in cartelle:

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

## Usare tutte le funzionalità dei flussi di lavoro

I flussi di lavoro in file supportano tutte le funzionalità del builder, tranne `idempotency_key()`, che non viene salvato nel modello; passatelo invece a ogni dispatch con `Queuety::run_workflow( $name, $payload, [ 'idempotency_key' => '...' ] )`. Ritardi, segnali, passaggi paralleli, ramificazioni condizionali, run-workflows, gestori di annullamento e riduzione dello stato funzionano tutti:

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

## Quando usare i flussi di lavoro in file

I flussi di lavoro in file sono ideali quando:

- Un LLM o un generatore di codice crea flussi di lavoro in modo programmatico
- Un flusso di lavoro è abbastanza semplice da stare in un unico file
- Volete tenere la logica dei passaggi vicino alla definizione del flusso di lavoro
- State creando un prototipo e volete iterare rapidamente

Per flussi di lavoro più grandi, con classi di passaggio condivise, middleware complesso o passaggi riutilizzati in più flussi, è più facile da gestire l'approccio standard con file di classe separati e caricamento automatico PSR-4.

## Come funziona

Dietro le quinte, i flussi di lavoro in file usano esattamente lo stesso motore del builder API. Ogni passaggio è un job separato nel database. Lo stato viene trasferito tramite la tabella `queuety_workflows`. Non ci sono riproduzione o requisiti di determinismo, né differenze di prestazioni.

Ogni chiamata di caricamento `require` il file (non `require_once`), quindi caricate ogni file una sola volta per richiesta; caricarlo due volte ridefinisce le classi e causa un errore. Il valore `WorkflowBuilder` restituito viene convertito in un `WorkflowTemplate` e salvato nel `WorkflowRegistry`. Il dispatch e l'esecuzione sono identici a quelli di qualsiasi altro flusso di lavoro.
