@mostajs/workflow
v0.0.1
Published
Turnkey workflow STACK assembling the State·Rule·Trigger triptych: @mostajs/statemachine (states + immutable history) + @mostajs/rules (guards, injected) + @mostajs/trigger (reactions). Single declarative API + orderWorkflow preset. No business logic — wi
Maintainers
Readme
@mostajs/workflow
La stack qui assemble le triptyque State · Rule · Trigger —
@mostajs/statemachine(états + historique immuable) +@mostajs/rules(gardes, injecté) +@mostajs/trigger(réactions) — derrière une API déclarative. Aucune logique propre : câblage + presets. Modèle Drupal Workflow + Rules + Trigger, pattern-stackde l'écosystème.
Auteur : Dr Hamid MADANI [email protected] · Licence : AGPL-3.0-or-later
C'est la seule dépendance workflow de @mostajs/crm (+ @mostajs/numbering) : le domaine ne câble pas les trois primitives lui-même.
Installation
npm i @mostajs/workflow @mostajs/statemachine @mostajs/trigger
# @mostajs/rules : optionnel (seulement si une transition utilise when: { rule })Exemple
import { defineWorkflow, orderWorkflowDef } from "@mostajs/workflow";
const base = orderWorkflowDef(); // preset : automate fini de commande (9 états, couleurs + party)
const emails: string[] = [];
const wf = defineWorkflow(
{
...base,
transitions: base.transitions.map((t) =>
t.id === "notifier" ? { ...t, then: [(tr) => emails.push(`notify:${tr.toState}`)] } : t,
),
},
{ checkPermission: (actorId) => actorId === "admin" },
);
const ref = { entityType: "order", entityId: "42" };
await wf.transition(ref, "init", "notification_attente", { actorId: "admin" });
// init → notification_attente → relance_emetteur_attente → reponse_attente →
// relance_destinataire_attente → validation_attente → finalisation_attente → client_informe
await wf.history(ref); // historique immuable (qui / quand / from→to)Ce que la stack câble
| Déclaratif | Câblé vers |
|---|---|
| transition.when (fonction ou { rule }) | garde @mostajs/statemachine ({ rule } résolu via RuleEvaluator = @mostajs/rules) |
| transition.then[] | triggers @mostajs/trigger sur transition:<id> |
| onPost de la FSM | hub.fire("transition:<id>") puis "enter:<to>" (fire-and-forget) |
| historique immuable | @mostajs/statemachine (via AuditSink / @mostajs/audit) |
Garde déclarative via @mostajs/rules
import { createKnowledgeBase } from "@mostajs/rules";
const kb = createKnowledgeBase();
// transition { id:"valid", from:["attente_admin"], to:"validee", when:{ rule:"transition_allowed(...)" } }
const wf = defineWorkflow(def, { rules: kb }); // kb.holds(goal, ctx)API
defineWorkflow(def, opts?) → Workflow. wf.availableTransitions/canTransition/transition/history, wf.on(event, action), wf.hub. WorkflowOptions = { audit?, checkPermission?, now?, rules?, hub? }. Preset : orderWorkflowDef().
Statut
v0.0.1 — assemblage implémenté et testé (defineWorkflow câblant statemachine + trigger, when fonction + { rule }, then→triggers) + preset orderWorkflow. Feuille de route : docs/03-PLAN-DEV-WORKFLOW.md. Étude : docs/01-ETUDE-ETAT-ART-WORKFLOW-07062026.md.
