Definície a verzie
Definície
$definition = Workflows::definitions()->create(
key: 'purchase-approval', name: 'Purchase approval',
subjectType: 'purchase_request', owner: $team, description: null,
); // or createWith(CreateDefinitionData)
Workflows::definitions()->find('purchase-approval', $team);
Workflows::definitions()->exists('purchase-approval', $team);
Workflows::definitions()->all($team);
Workflows::definitions()->restore('purchase-approval', $team); // un-trash a soft-deleted definition- Nová definícia je v stave draft a jej verzia 1 je koncept s minimálnym grafom (ručný spúšťač → end).
- Kľúče zodpovedajú ^[a-z0-9][a-z0-9._-]{0,99}$ a sú jedinečné v rámci vlastníka (definície celej aplikácie zdieľajú jeden rozsah). Zmazaná definícia si kľúč stále drží: create() vyhodí DefinitionKeyTakenException a restore() ju vráti späť.
Koncepty a publikovanie
$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)- Jeden koncept na definíciu, vynútený zámkom riadka definície. edit() s $expectedChecksum, ktorý sa líši od konceptu, vyhodí DraftConflictException — dve karty editora sa navzájom neprepíšu.
- Publikované verzie sú nemenné. Graf, spúšťač, aktér, nastavenia, kontrolný súčet a publikujúci sa po nastavení published_at nedajú zmeniť (PublishedVersionImmutableException). Mení sa len stav (published → superseded) a kurzor plánu.
- publish() spraví úplnú validáciu, zmrazí koncept, nahradí predchádzajúcu verziu, nastaví aktuálnu verziu, aktivuje definíciu, nastaví kurzor plánu na teraz a po commite vyšle VersionPublished. Bez konceptu → NothingToPublishException. Publikovanie vyradenej definície ju znova aktivuje.
- Bežiace inštancie si verziu ponechajú. Obnovenie, opakovanie aj eskalácie vždy používajú vlastný graf inštancie. Spustenie beží na verzii, ktorá je aktuálna vo chvíli, keď drží zámok definície: spustenie súbežné s publikovaním začne na novej verzii.
- Vyradené definície odmietnu každé spustenie (DefinitionNotActiveException), aj také, ktoré už prebiehalo v čase vyradenia.
- Spustenie zo subjektu — Workflows::for($request)->start($key) a $request->workflows() — najprv hľadá definíciu vlastníka subjektu a potom definíciu celej aplikácie s rovnakým kľúčom. S výslovne zadaným vlastníkom alebo cez Workflows::start($key, $subject, $owner) sa hľadá len v danom rozsahu.
Definície ako súbory
Systémové workflowy celej aplikácie (aj východiskové workflowy pre nových tenantov) môžu byť vo vašom repozitári ako JSON súbory v obálke šablóny — presne to, čo zapisuje workflows:export — a synchronizovať sa pri nasadení:
php artisan workflows:export purchase-approval --path=resources/workflows # writes purchase-approval.json
php artisan workflows:validate --file=resources/workflows/purchase-approval.json
php artisan workflows:sync resources/workflows --publish # create / draft / publish; no-op when unchanged
php artisan workflows:sync --dry # report what would change, write nothing$report = Workflows::definitions()->sync(resource_path('workflows'), owner: $team, publish: true, dryRun: false);
$report->definitions; // list<SyncedDefinition{file, key, status, draftOverwritten, version, message, report}>
$report->untracked; // keys of the owner's definitions no file describes
$report->failed(); // any invalid or failed file- Každý súbor *.json (adresár alebo jeden súbor; predvolene workflows.sync.path) je payload roundly.workflows.template/v1: definition.{key, name, subject_type, description} a graph.
- Chýbajúca definícia sa vytvorí (created). Graf, ktorého kanonický kontrolný súčet sa líši od aktuálnej verzie aj od konceptu, sa uloží ako koncept (drafted); s publish sa potom publikuje, ak je platný (published), inak sa nahlási ako invalid s reportom a z daného súboru sa nič nepublikuje. Nezmenený súbor nič nerobí (unchanged): dvojitá synchronizácia nevytvorí druhú verziu.
- Id uzlov ostávajú tak, ako sú zapísané — na rozdiel od importu šablóny, ktorý ich premapuje — takže súbor sa synchronizuje vždy rovnako a verzie sa dajú porovnať uzol po uzle. Zachovajú sa aj hodnoty špecifické pre vlastníka.
- Koncept upravený inde (v editore), ktorý súbor nahradí, sa nahlási (draftOverwritten).
- Nič sa nevyradí ani nezmaže: definície vlastníka bez súboru sa uvedú ako untracked.
- Vlastník: predvolene celá aplikácia; v príkazoch --owner-type=<morph alias> --owner-id=. Zápisy idú cez akcie definícií, takže sa vysielajú udalosti.
Porovnanie
$diff = Workflows::versions()->diff($v1, $v2); // VersionDiff
$diff->identical;
$diff->nodesAdded; // ids
$diff->nodesRemoved;
$diff->nodesChanged; // list<NodeChange{node, typeChanged, configChanges, retryChanged, escalationsChanged}>
$diff->nodesMoved; // ui-only changes
$diff->edgesAdded;
$diff->edgesRemoved;
$diff->edgesRelabelled; // list<EdgeChange{from, to, before, after}>
$diff->triggerChanges;
$diff->settingsChanges;configChanges sú JSON pointery listov, ktoré sa líšia. Na poradí v mape nezáleží, na poradí v zozname áno. Verzie rôznych definícií → InvalidDiffException.
Šablóny
$payload = Workflows::versions()->export($version); // or $handle->export()
$result = Workflows::versions()->import($payload, $otherTeam, key: null); // ImportResult
$result->definition; // a new draft definition (key suffixed -2, -3 … when taken)
$result->idMap; // old node id => new node id
$result->flags; // list<ReviewFlag{node, path, reason}> — cleared owner-specific values
Workflows::definition($result->definition->key, $otherTeam)->resolveFlag('n_k3x9q2m7ab', '/recipients');Payload (roundly.workflows.template/v1) nesie kľúč, názov, kľúč typu subjektu a popis definície, graf, exported_at a kontrolný súčet zdroja — žiadneho vlastníka, žiadne id, žiadne názvy tried. Hodnoty špecifické pre vlastníka sa zachovajú (opätovný import u toho istého vlastníka je bezstratový) a uvedú v review. Import:
- overí payload a typ subjektu;
- premapuje každé id uzla na nové n_ + 10 znakov base32 a prepíše hrany, odkazy steps.<id> a polia podmienok, vstupy start_workflow, dáta notifikácií a každý reťazec konfigurácie, ktorého schéma uvádza format: node-id;
- vymaže každú hodnotu špecifickú pre vlastníka (strany typu user, kalendáre opening_hours: v trvaniach a nastaveniach, ciele start_workflow, ktoré nový vlastník nemá, endpointy webhookov, cesty, ktoré deklaruje typ) a na koncepte zaznamená ReviewFlag{node, path, reason};
- vytvorí novú definíciu v stave draft (ak je kľúč obsadený, dostane príponu -2, -3 …).
Publikovanie blokuje unresolved_import_reference, kým sa každá označená cesta nenastaví (úprava príznak zruší) alebo sa príznak nezruší cez resolveFlag(). Používatelia, kalendáre a definície jedného tímu sa nikdy nedostanú k inému tímu.
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.