Inštalácia
Pridajte balík, inštalačným príkazom publikujte konfiguráciu a migrácie a spustite migráciu. Service provider a alias fasády Workflows sa načítajú automaticky spolu s providermi balíkov Roundly, na ktorých stojí — crypto (odtlačky idempotentných kľúčov), enums a package-toolkit:
composer require roundly-consulting/workflows-for-laravel roundly-consulting/approvals-for-laravel
php artisan workflows:install # publishes config/workflows.php and the eight migrations
php artisan vendor:publish --tag="approvals-migrations" # approvals powers the approval step in the example below
php artisan migrateworkflows:install odmietne pokračovať, ak už niektorá z tabuliek balíka existuje. Vypíše riadky pre plánovač a nápovedu k registrácii subjektov. Migrácie sa len publikujú (nikdy sa nenačítavajú automaticky) a idú iba dopredu.
approvals-for-laravel zabezpečuje krok approval v príklade nižšie; ak schvaľovanie nepotrebujete, balík ani jeho migrácie neinštalujte. Bez neho publikovanie grafu s krokom approval zlyhá s adapter_missing.
1. Typy kľúčov nastavte pred migráciou
Polymorfné stĺpce dostanú veľkosť pri migrácii. Ak všade používate bigint id, predvolené hodnoty sedia; pri kľúčoch UUID alebo ULID ich nastavte pred php artisan migrate:
# Before php artisan migrate — bigint, uuid or ulid
WORKFLOWS_KEY_TYPE=bigint # user morphs: started_by, published_by, requested_by
WORKFLOWS_OWNER_KEY_TYPE= # owner morphs; blank = WORKFLOWS_KEY_TYPE
WORKFLOWS_SUBJECT_KEY_TYPE= # subject morphs; blank = WORKFLOWS_KEY_TYPE
WORKFLOWS_PRIMARY_KEY_TYPE=bigint # the package's own idsModel, ktorého kľúč nezodpovedá nastavenému typu, sa odmietne ešte pred akýmkoľvek SQL výnimkou InvalidWorkflowsConfigurationException s názvom kľúča — PostgreSQL tak nikdy neodpovie surovým „invalid input syntax“. Kontroluje to aj workflows:doctor.
2. Naplánujte wake a prune
Oneskorenia, časové limity, opakovania, eskalácie a plány prebúdza plánovač. Nič sa neplánuje automaticky — bez tohto riadku sa oneskorenie nikdy neskončí:
// routes/console.php
use Illuminate\Support\Facades\Schedule;
Schedule::command('workflows:wake')->everyMinute()->withoutOverlapping(10)->onOneServer();
Schedule::command('workflows:prune')->daily();workflows:wake spúšťa splatné časovače, opakovania, časové limity čakaní, kontroly podmienok, eskalácie a plánované spúšťače, preberá späť vypršané lease a znova odosiela stratené joby. onOneServer() potrebuje cache zdieľanú všetkými servermi (redis, database, memcached, dynamodb). Správnosť od toho nikdy nezávisí — každé prevzatie je compare-and-set.
3. Spustite queue worker
Pri zapnutom workflows.queue.enabled (predvolene) beží každý krok ako job — RunStepJob, ResumeStepJob, FireEscalationJob; nesú len id, tries = 1, odosielajú sa po commite. Timeout jobu je engine.lease − 30 s (predvolene 570 s): retry_after spojenia frontu musí byť dlhší a worker potrebuje pcntl, aby timeout vynútil. Predvolené spojenie database v Laraveli má retry_after 90 s, preto ho v novej aplikácii zvýšte — alebo znížte engine.lease, ak sú všetky kroky krátke. workflows:doctor zlyhá pri prikrátkom retry_after a bez pcntl varuje. S vypnutým frontom bežia kroky priamo v požiadavke, ktorá ich spustí alebo obnoví, cez trampolínu (bez rekurzie), obmedzené limits.max_steps.
# A step job may run for up to 570 s (engine.lease − 30 s): retry_after must be longer.
DB_QUEUE_RETRY_AFTER=600 # Laravel's default database queue (90 s otherwise)
REDIS_QUEUE_RETRY_AFTER=600 # the redis queue
php artisan workflows:doctor # fails on a too-short retry_after4. Zaregistrujte typ subjektu a použite trait
Subjekt je model, ktorého sa inštancia týka. Každý typ zaregistrujte raz, v metóde boot() service providera:
// AppServiceProvider::boot()
use RoundlyConsulting\Workflows\Facades\Workflows;
Workflows::subjects()->register(
Workflows::subject('purchase_request', PurchaseRequest::class)
->label('Purchase request')
->ownedBy('team')
->field('amount', 'decimal', 'Amount')
->field('requester', 'party', 'Requester'),
);use RoundlyConsulting\Workflows\Traits\HasWorkflows;
class PurchaseRequest extends Model
{
use HasWorkflows; // $request->workflows(), touch on update, cancel on delete
}5. Definujte, publikujte a spustite workflow
use RoundlyConsulting\Workflows\Facades\Workflows;
use RoundlyConsulting\Workflows\Graph\Build\{Party, Trigger, When};
// Once, in a service provider: what a purchase request looks like to the engine.
Workflows::subjects()->register(
Workflows::subject('purchase_request', PurchaseRequest::class)
->label('Purchase request')
->ownedBy('team')
->field('amount', 'decimal', 'Amount')
->field('requester', 'party', 'Requester')
->field('approver', 'party', 'Approver'),
);
// The workflow itself is data: a JSON graph your users edit in a builder — or written in PHP.
$definition = Workflows::definitions()->create(key: 'purchase-approval', name: 'Purchase approval',
subjectType: 'purchase_request', owner: $team);
Workflows::definition('purchase-approval', $team)->edit(Workflows::graph() // or ->edit(json_decode($json, true))
->trigger('start', Trigger::manual())
->condition('check', When::field('subject.amount')->gt('500'))
->approval('approve', approvers: [Party::field('subject.approver')])
->end('done')
->connect('start', 'check')
->connect('check', 'approve', on: 'true')
->connect('check', 'done', on: 'false')
->connect('approve', 'done', on: ['approved', 'rejected', 'expired']));
Workflows::definition('purchase-approval', $team)->publish(by: $admin);
// Start it (this graph's trigger is `manual`) — with an `event` trigger the app event starts it instead.
$result = Workflows::start('purchase-approval', subject: $request, owner: $team)
->by($request->requester)
->idempotencyKey("submit:{$request->id}")
->dispatch();
$result->instance->status; // InstanceStatus::Running — a queue worker runs it on to the approval step, where it waitsTagy na publikovanie
| Tag | Publikuje |
|---|---|
workflows-config | config/workflows.php |
workflows-migrations | Osem migrácií s časovou pečiatkou pri publikovaní. |
workflows-translations | lang/vendor/workflows/{en,sk} |
workflows-routes | Súbor s voliteľnou prichádzajúcou webhook route. |
php artisan vendor:publish --tag="workflows-config" # config/workflows.php
php artisan vendor:publish --tag="workflows-migrations" # the eight migrations, timestamped on publish
php artisan vendor:publish --tag="workflows-translations" # lang/vendor/workflows/{en,sk}
php artisan vendor:publish --tag="workflows-routes" # the opt-in inbound webhook route fileTabuľky
| Tabuľka | Obsahuje |
|---|---|
workflow_definitions | Pomenované workflowy pre každého vlastníka: kľúč, názov, kľúč typu subjektu, stav, aktuálna verzia, id webhooku. |
workflow_versions | Číslované snímky grafu: graf, spúšťač, aktér, nastavenia, kontrolný súčet, príznaky na kontrolu, kto publikoval. |
workflow_instances | Behy: verzia, vlastník, subjekt, spúšťač, stav, aktuálny uzol, zlyhanie, rodič a hĺbka. |
workflow_step_runs | Záznam krokov: jeden riadok na pokus jednej návštevy, so vstupom, výstupom, výsledkom, chybou a lease. |
workflow_waits | Časovače, udalosti, kontroly podmienok, opakovania a časové limity, na ktoré engine čaká. |
workflow_escalations | Najbližšia čakajúca úroveň eskalácie každej čakajúcej návštevy. |
workflow_idempotency_keys | Kľúče spustení a efektov, uložené ako odtlačky. |
workflow_dry_runs | Zaznamenané skúšobné behy (iba s ->log() alebo zapnutým dry_run.log). |
Názvy tabuliek sa dajú nastaviť (workflows.tables.*); všetky stĺpce nájdete v časti Databáza.
Preklady
Angličtina a slovenčina sú súčasťou balíka v mennom priestore workflows:: — enums, exceptions, failures, fields, steps a validation. Prekladajú sa názvy krokov, validačné správy, správy o zlyhaní aj popisy enumov.
Kontrola inštalácie
php artisan workflows:doctor # --json for CI and health checks, --strict to fail on warnings
php artisan about --only=workflows # step types, bridges, queue mode, key types, limits, webhooksphp artisan about zobrazí sekciu Workflows: počet typov krokov, nainštalované prepojenia, režim frontu, štyri typy kľúčov, limity a či je zapnutá webhook route.
Prechod z verzie 1.0.0
Žiadna migrácia ani zmena konfigurácie. Skontrolujte tri veci:
- retry_after spojenia frontu musí byť nad 570 s timeoutu jobu kroku (pri fronte database DB_QUEUE_RETRY_AFTER=600) — spustite workflows:doctor, ktorý inak zlyhá.
- Grafy s krokom approval potrebujú approvals-for-laravel: pridajte ho a pred migráciou publikujte jeho migrácie (approvals-migrations).
- Workflows::emit() už nevyhodí výnimku, keď sa jedna zo zodpovedajúcich definícií odmietne spustiť: ostatné sa spustia a odmietnutie sa uvedie v EmitResult::$failed. Kód, ktorý túto výnimku zachytával, by mal namiesto toho čítať $result->failed.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.