Všetko ide cez jednu fasádu, RoundlyConsulting\Workflows\Facades\Workflows (globálny alias Workflows), ktorá je nadstavbou nad singletonom WorkflowsManager v kontajneri. Manažér nedrží žiadny stav požiadavky, takže je bezpečný pre Octane. Každá metóda, ktorá niečo mení, má návratový typ, ktorý nie je null:
use RoundlyConsulting\Workflows\Facades\Workflows;
// Start and emit
Workflows::start('purchase-approval', $request, $team)->input([...])->by($user)->idempotencyKey($key)->dispatch();
Workflows::emit('purchase_request.submitted', $request, ['amount' => '1200'], idempotencyKey: "sub:{$request->id}", user: $user);
Workflows::for($request)->start('purchase-approval')->dispatch(); // the subject owner's definition, else the app-wide one
// Definitions and versions
Workflows::definitions()->create(key: 'purchase-approval', name: 'Purchase approval', subjectType: 'purchase_request', owner: $team);
Workflows::definition('purchase-approval', $team)->edit($graph); // save the draft — see the definition handle
Workflows::definition('purchase-approval', $team)->publish(by: $admin);
Workflows::versions()->diff($v2, $v3);
Workflows::versions()->export($version);
// Runs
Workflows::instances()->find($ulid);
Workflows::instances()->retry($instance);
Workflows::instances()->cancel($instance, 'withdrawn');
// Registries a builder reads
Workflows::catalogue()->export(); // every step type with its config schema and outcomes
Workflows::subjects()->export('purchase_request');
Workflows::calendars()->names();
Workflows::triggers()->events();
Workflows::schema()->graph(); // the graph JSON Schema
// The graph builder, wake and prune
Workflows::graph()->trigger('start', Trigger::manual())->end('done')->chain('start', 'done');
Workflows::wake(); // what workflows:wake runs
Workflows::prune(); // what workflows:prune runs
Metódy manažéra
| Metóda | Vracia | Čo robí |
|---|
start(string $key, ?Model $subject = null, ?Model $owner = null) | PendingStart | Ručné spustenie; ->dispatch() spustí StartInstanceAction. |
startWith(StartData $data) | StartResult | To isté z DTO. |
emit(string $event, ?Model $subject = null, array $payload = [], ?string $idempotencyKey = null, ?Model $user = null, ?Model $owner = null) | EmitResult | Spustí každú zodpovedajúcu aktívnu definíciu a signalizuje čakajúcim krokom; definícia, ktorá sa odmietne spustiť, sa uvedie vo failed. |
emitWith(EmitData $data) | EmitResult | To isté z DTO. |
for(Model $subject) | SubjectHandle | Spustenie, emit, história, zrušenie a touch pre jeden subjekt. |
definition(string $key, ?Model $owner = null) | DefinitionHandle | Jedna definícia jedného vlastníka (null = celá aplikácia). |
definitions() | DefinitionsAccessor | create, createWith, find, exists, all, sync, restore. |
versions() | VersionsAccessor | validate, diff, overlay, export, import, dryRun. |
instances() | InstancesAccessor | find, recent, detail, steps, retry, cancel. |
catalogue() | CatalogueAccessor | register, all, find, has, export — typy krokov. |
subjects() | SubjectsAccessor | register, find, export, all — typy subjektov. |
subject(string $key, string $model) | SubjectTypeBuilder | Opis typu subjektu na registráciu. |
calendars() | CalendarsAccessor | register, find, names — pracovné kalendáre. |
triggers() | TriggersAccessor | webhook, map, listen, events. |
schema() | SchemaAccessor | graph, template, definitions — JSON Schemas. |
graph() | GraphBuilder | Plynulý zostavovač grafu; čistý, fake ho prepúšťa. |
wake(?CarbonInterface $now = null) | WakeReport | Jeden prechod prebúdzania (WakeAction); celý prechod beží v čase $now. |
prune() | PruneReport | Zmaže dáta po uplynutí doby uchovania (PruneAction). |
signal(), perform() a make() sú na manažérovi verejné, no interné — slúžia prepojeniam a handlom. Z kódu aplikácie ich nevolajte.
Workflows::definition($key, $owner)
Jedna definícia jedného vlastníka (null = celá aplikácia); kľúč iného vlastníka sa nikdy nenájde. Každá metóda, ktorá potrebuje riadok, vyhodí UnknownDefinitionException (404), ak chýba:
$handle = Workflows::definition('purchase-approval', $team);
$handle->model(); // WorkflowDefinition (UnknownDefinitionException if missing)
$handle->draft(); // the draft version or null
$handle->edit($graph, $expectedChecksum); // save the draft (a graph array or a GraphBuilder; created as a copy of the current version)
$handle->discardDraft();
$handle->validate(); // ValidationReport of the draft
$handle->publish(by: $admin); // the draft becomes the current version
$handle->retire(); // no new starts; running instances finish
$handle->activate(); // allow starts again
$handle->resolveFlag($node, $path); // dismiss a template review flag
$handle->rotateWebhook(); // a new webhook id
$handle->versions(); // every version, by number
$handle->version(3);
$handle->instances(InstanceStatus::Failed, perPage: 25); // cursor-paginated history
$handle->start($subject); // PendingStart
$handle->dryRun(?int $version); // PendingDryRun (NoVersionException for a missing version)
$handle->export(?int $version); // TemplatePayload (NoVersionException for a missing version)
| Metóda | Vracia | Čo robí |
|---|
model() | WorkflowDefinition | Riadok; ak chýba, UnknownDefinitionException (404). |
draft() | ?WorkflowVersion | Koncept alebo null. |
edit(array|GraphBuilder $graph, ?string $expectedChecksum = null) | WorkflowVersion | Uloží koncept; zastaraný kontrolný súčet vyhodí DraftConflictException. |
discardDraft() | WorkflowDefinition | Zahodí koncept. |
validate() | ValidationReport | Úplná validácia konceptu. |
publish(?Model $by = null) | WorkflowVersion | Z konceptu sa stane aktuálna verzia. |
retire() / activate() | WorkflowDefinition | Zastaví alebo povolí nové spustenia; bežiace inštancie dobehnú. |
resolveFlag(string $node, string $path) | WorkflowVersion | Zruší príznak na kontrolu zo šablóny. |
rotateWebhook() | WorkflowDefinition | Nové id webhooku. |
versions() / version(int $number) | Collection / ?WorkflowVersion | Všetky verzie podľa čísla, alebo jedna. |
instances(?InstanceStatus $status = null, int $perPage = 25) | CursorPaginator | História, od najnovších. |
start(?Model $subject = null) | PendingStart | Ručné spustenie tejto definície. |
dryRun(?int $version = null) | PendingDryRun | Aktuálna verzia, inak koncept; NoVersionException, ak žiadna nie je alebo číslo neexistuje. |
export(?int $version = null) | TemplatePayload | Prenosná šablóna; NoVersionException rovnako. |
Workflows::definitions()
| Metóda | Vracia | Čo robí |
|---|
create(string $key, string $name, ?string $subjectType = null, ?Model $owner = null, ?string $description = null) | WorkflowDefinition | Definícia v stave draft s verziou 1 s minimálnym grafom (ručný spúšťač → end). |
createWith(CreateDefinitionData $data) | WorkflowDefinition | To isté z DTO. |
find(string $key, ?Model $owner = null) | ?WorkflowDefinition | Ak chýba, null. |
exists(string $key, ?Model $owner = null) | bool | Či kľúč v danom rozsahu existuje. |
all(?Model $owner = null) | Collection | Všetky definície vlastníka. |
sync(?string $path = null, ?Model $owner = null, bool $publish = false, bool $dryRun = false) | SyncReport | Vytvorí, uloží koncept a publikuje zo súborov JSON ($path null = workflows.sync.path). |
restore(string $key, ?Model $owner = null) | WorkflowDefinition | Obnoví mäkko zmazanú definíciu. |
Workflows::versions()
| Metóda | Vracia | Čo robí |
|---|
validate(array|GraphBuilder $graph, ?string $subjectType = null, ?Model $owner = null) | ValidationReport | Validuje ľubovoľný graf. |
diff(WorkflowVersion $from, WorkflowVersion $to) | VersionDiff | Zmeny uzlov a hrán medzi dvoma verziami jednej definície. |
overlay(WorkflowVersion $version) | OverlayReport | Bežiace, čakajúce a zlyhané inštancie podľa aktuálneho uzla. |
export(WorkflowVersion $version) | TemplatePayload | Payload roundly.workflows.template/v1. |
import(TemplatePayload|array $payload, ?Model $owner = null, ?string $key = null) | ImportResult | Nová definícia v stave draft s premapovanými id a príznakmi na kontrolu. |
dryRun(WorkflowVersion|array|GraphBuilder $graph, ?WorkflowDefinition $definition = null) | PendingDryRun | Skúšobný beh neuloženého grafu alebo ľubovoľnej verzie. |
Workflows::instances()
| Metóda | Vracia | Čo robí |
|---|
find(int|string $id) | ?WorkflowInstance | Podľa ULID (bez ohľadu na veľkosť písmen) alebo primárneho kľúča; hodnota, ktorú stĺpec nepojme, sa jednoducho nenájde. |
recent(?InstanceStatus $status = null, ?string $definition = null, ?Model $owner = null, int $limit = 25) | Collection | Od najnovších. |
detail(WorkflowInstance $instance) | WorkflowInstance | Načíta definíciu, verziu, záznam krokov, čakajúce čakania a čakajúce eskalácie. |
steps(WorkflowInstance $instance) | Collection | Všetky pokusy v poradí. |
retry(WorkflowInstance $instance) | WorkflowInstance | Zopakuje zlyhanú inštanciu od zlyhaného kroku. |
cancel(WorkflowInstance $instance, ?string $reason = null) | WorkflowInstance | Zruší bežiacu alebo čakajúcu inštanciu. |
Workflows::for($subject) a $subject->workflows()
| Metóda | Vracia | Čo robí |
|---|
start(string $key, ?Model $owner = null) | PendingStart | Definícia vlastníka subjektu, inak definícia celej aplikácie; výslovne zadaný vlastník hľadá len vo svojom rozsahu. |
emit(string $event, array $payload = [], ?string $idempotencyKey = null, ?Model $user = null) | EmitResult | Emit pre tento subjekt. |
instances(int $perPage = 25) | CursorPaginator | Od najnovších, s načítaným vlastníkom a spúšťajúcim. |
running() | Collection | Bežiace alebo čakajúce inštancie. |
cancelAll(?string $reason = null) | int | Počet zrušených inštancií — vrátane detí zrušeného rodiča; inštancia, ktorá medzitým skončila, sa preskočí. |
touch() | int | Počet znova vyhodnotených podmienkových čakaní. |
Ďalšie accessory
| Accessor | Metóda | Vracia |
|---|
catalogue() | register(string|StepType $type) | StepType |
catalogue() | all() / find($key) / has($key) | array / ?StepType / bool |
catalogue() | export() | CatalogueExport |
subjects() | register(SubjectTypeBuilder|SubjectTypeDefinition $type) | SubjectTypeDefinition |
subjects() | find($key) / export($key) / all() | ?SubjectTypeDefinition / SubjectTypeDefinition / array |
calendars() | register(string $name, Closure $resolver) | self |
calendars() | find(string $name, ?Model $owner = null, ?string $timezone = null) | BusinessCalendar |
calendars() | names() | list<string> |
triggers() | webhook(string $hookId, array $payload, array $headers = []) | StartResult |
triggers() | map(string $event, string $key, ?string $subject, ?string $user, list|string|null $payload, ?string $idempotencyKey) | void |
triggers() | listen(string $event) / events() | void / array<string, string> |
schema() | graph() / template() / definitions() | array |
Buildery
| Builder | Metódy |
|---|
PendingStart | input(array $input), by(?Model $user), idempotencyKey(?string $key), withForm(Request $request, bool $submit = false) → self; dispatch(): StartResult |
PendingDryRun | subject(Model), sample(array), input(array), event(string $key, array $payload = []), assume(array), at(CarbonInterface), log(bool = true), by(?Model) → self; run(): DryRunResult, explore(): DryRunTree |
SubjectTypeBuilder | label(string), ownedBy(string $relation), ownerType(bool = true), ability(string), field(string $name, FieldType|string $type, ?string $label = null, string|array|null $options = null, ?string $path = null, bool $writable = false) → self; key(), build() |
Hodnotové objekty, DTO, modely a enumy
- DTO (všetky final readonly, s verejnými promoted vlastnosťami): StartData, StartResult (wasSkipped(), wasRefused()), EmitData, EmitResult (started, resumed, failed; skipped()), EmitFailure (definition, exception; code()), CreateDefinitionData, DryRunData, DryRunResult, DryRunStep, DryRunTree, WouldBeAction, SideEffect, SimulatedStep, ValidationReport, ValidationError, EdgeReference, VersionDiff, NodeChange, EdgeChange, OverlayReport, NodeOverlay, TemplatePayload, ImportResult, ReviewFlag, SyncReport, SyncedDefinition, WakeReport, PruneReport, CatalogueExport, CatalogueEntry, SubjectTypeDefinition, FieldDefinition, EventMapping, PartyReference, Duration, RetryPolicy, Actor, Signal, StepAuthorization, TransitionOutcome, DoctorFinding.
- Graph\Graph, Graph\Node a Graph\Edge sú spracovaný graf len na čítanie (StepContext::graph(), node(), WorkflowVersion::parsedGraph()): node($id), nodesOfType($type), trigger(), outgoing($id), incoming($id), edgeFor($from, $outcome), setting($key, $default), toArray().
- Modely (vymeniteľné cez workflows.models.*) majú $guarded = [], factory, nastaviteľný kľúč a časové údaje v UTC. Všetky sa mažú mäkko okrem WorkflowIdempotencyKey; workflows:prune maže natrvalo.
- Enumy sú reťazcové s preloženými popismi cez pomocníkov z enums-for-laravel.
| Model | Relácie | Metódy |
|---|
WorkflowDefinition | owner() MorphTo, versions() HasMany, currentVersion() BelongsTo, instances() HasMany | isActive() |
WorkflowVersion | definition() BelongsTo, publisher() MorphTo | reviewFlags(), setReviewFlags(array), isPublished(), parsedGraph(): Graph |
WorkflowInstance | definition(), version(), parent() BelongsTo; owner(), subject(), starter() MorphTo; children(), stepRuns(), waits(), escalations() HasMany | failure(): FailureCode|string|null, path(): list<string> |
StepRun | instance() BelongsTo, waits(), escalations() HasMany | error(): FailureCode|string|null |
WorkflowWait | instance(), stepRun() BelongsTo | — |
WorkflowEscalation | instance(), stepRun() BelongsTo | — |
WorkflowIdempotencyKey | instance() BelongsTo | — |
WorkflowDryRun | definition() BelongsTo, requester() MorphTo | — |
| Enum | Hodnoty |
|---|
ActorMode | system, on_behalf_of |
ConditionOperator | equals, in, gt, lt, between, empty, contains, before, after |
DefinitionStatus | draft, active, retired |
DoctorLevel | ok, warn, fail |
DurationUnit | minutes, hours, days, weeks, months, business_minutes, business_hours, business_days; isBusiness() |
EscalationStatus | pending, claimed, fired, failed, cancelled |
FieldType | string, text, integer, decimal, boolean, date, datetime, enum, party, list |
InstanceStatus | running, waiting, completed, failed, cancelled; isTerminal(), isActive() |
Severity | error, warning |
SignalKind | timer, event, condition, probe, retry, timeout |
StepRunStatus | queued, running, waiting, completed, failed, cancelled |
SyncStatus | created, drafted, published, unchanged, invalid, failed |
TriggerType | manual, event, schedule, webhook |
VersionStatus | draft, published, superseded |
WaitKind | timer, event, condition, retry, timeout |
WaitStatus | pending, claimed, fired, cancelled |
ValidationCode | Každý kód validácie — pozri Validácia pri publikovaní. |
FailureCode | Každý kód zlyhania enginu, vstavaných krokov a prepojení; fromStored(), detail(), retryable(), message() — pozri Riešenie problémov. |
WorkflowOperation | Čo zaznamenáva fake — pozri Testovanie. |