
## Workflows in één bestand

Een workflow kan volledig op zichzelf staan in één PHP-bestand. Definieer de stapklassen en de builder samen, plaats het bestand in een map en laad die map met `Queuety::load_workflows()` (zie hieronder). Queuety scant zelf geen mappen.

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

Het bestand retourneert een `WorkflowBuilder`. Elke stapklasse wordt inline gedefinieerd. Wanneer het bestand wordt geladen, zijn de klassen beschikbaar en wordt de workflow als sjabloon geregistreerd.

## Workflows laden

Laad alle workflowbestanden uit een map:

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

Of laad één bestand:

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

Verzend daarna op naam:

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

## Recursief laden

Geef `true` als tweede argument door om submappen te scannen:

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

Zo kun je workflows in mappen organiseren:

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

## Alle workflowfuncties gebruiken

Bestandsworkflows ondersteunen alles wat de builder ondersteunt, behalve `idempotency_key()`, dat niet in de sjabloon wordt opgeslagen; geef het per verzending door met `Queuety::run_workflow( $name, $payload, [ 'idempotency_key' => '...' ] )`. Vertragingen, signalen, parallelle stappen, voorwaardelijke vertakkingen, run-workflows, annuleringshandlers en statusopschoning werken allemaal:

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

## Wanneer bestandsworkflows gebruiken

Bestandsworkflows zijn ideaal wanneer:

- Een LLM of codegenerator workflows programmatisch maakt
- Een workflow eenvoudig genoeg is om in één bestand te passen
- Je de staplogica dicht bij de workflowdefinitie wilt houden
- Je een prototype maakt en snel wilt itereren

Voor grotere workflows met gedeelde stapklassen, complexe middleware of stappen die in meerdere workflows worden hergebruikt, is de standaardaanpak met afzonderlijke klassebestanden en PSR-4-autoloading beter onderhoudbaar.

## Werking

Achter de schermen gebruiken bestandsworkflows exact dezelfde engine als builder API. Elke stap is een afzonderlijke taak in de database. De status wordt doorgegeven via de tabel `queuety_workflows`. Er is geen replay, geen determinismevereiste en geen prestatieverschil.

Elke laadfunctie `require`t het bestand (geen `require_once`), dus laad elk bestand één keer per verzoek; als je het twee keer laadt, worden de klassen opnieuw gedeclareerd en mislukt de uitvoering. De geretourneerde `WorkflowBuilder` wordt omgezet naar een `WorkflowTemplate` en opgeslagen in de `WorkflowRegistry`. Verzending en uitvoering zijn identiek aan die van elke andere workflow.
