What’s NodeJS Workflow Engine

As we all know, as a backend development language and runtime environment, NodeJS is good in everything, but only missing a NodeJS workflow engine. CabloyJS 4.0 focuses on the development of NodeJS Workflow Engine, and as a built-in basic core module, it further expands the application scenarios of NodeJS in the backend and provides basic support for the in-depth research and development of various business business logic

Features of NodeJS workflow engine

  1. Easier configuration: Use JSON to configure the process definition, bid farewell to the complexity of XML configuration files
  2. Workflow Definition: Support historical revision, support enable/disable
  3. Clearer architecture: Three core modules are used to implement the architecture of the workflow engine with a layered mechanism, so that the workflow is no longer mysterious
Module Name Description
a-flow Flow Definition, Flow Instance
a-flownode Flow Node(Activity Node)
a-flowtask Flow Task
  1. Support Business Process and Approval Process
  2. Combined with Atom Stages, a set of Atom-based approval workflow is built in. See also: Atom Stages
  3. Combined with Form Validation, it supports configuring read field permissions and write field permissions of different flow nodes. See also: Form Validation
  4. The workflow logic can be customized through the AOP mechanism
  5. The workflow logic can be customized through the Listener mechanism
  6. Open architecture supports more customized development of flow nodes
  7. Contains a lot of test-driven code, you can quickly use the workflow

Demo

  1. Create a new draft: Purchase Order
  2. Select Flow Definition, then Submit, while the draft will enter the corresponding flow process
  3. Claim and Handle the Review task
  4. The flow process ends and the draft is converted to Archive

flow-enus

A minimal workflow definition

src/module/test-flow/backend/src/config/static/flowDef/set00_simple.js

  {
    listener: null,
    process: {
      nodes: [
        {
          id: 'startEvent_1',
          name: 'Start',
          type: 'startEventNone',
        },
        {
          id: 'endEvent_1',
          name: 'End',
          type: 'endEventNone',
        },
      ],
      edges: [
        {
          id: 'edge_1',
          source: 'startEvent_1',
          target: 'endEvent_1',
        },
      ],
    },
  }
Name Description
listener Monitor various events of flow/node/task
process.nodes Flow Nodes
process.nodes.type Type of flow node
process.edges Transitions
process.edges.source Incoming Transitions
process.edges.target Outgoing Transitions

An approval flow definition

src/module/test-flow/backend/src/config/static/flowDef/set01_atomUserTask.js

  {
    listener: null,
    process: {
      nodes: [
        {
          id: 'startEvent_1',
          name: 'Drafting',
          type: 'startEventAtom',
          options: {
            atom: {
              module: moduleInfo.relativeName,
              atomClassName: 'purchaseOrder',
            },
            conditionExpression: 'atom._flowDefKey===\'set01_atomUserTask\'',
          },
        },
        {
          id: 'activity_1',
          name: 'Review',
          type: 'activityUserTask',
          options: {
            assignees: {
              // users: '1,2',
              // roles: '1,2',
              vars: 'flowUser',
            },
            confirmation: false,
            bidding: false,
            completionCondition: {
              // passed: 1,
              // rejected: '100%',
            },
            // rejectedNode:null,
            // allowRejectTask: true,
            // allowCancelFlow: false,
            schema: {
              write: [
                'atomName',
                {
                  name: 'description',
                  property: {
                    type: 'string',
                    ebType: 'text',
                    ebTitle: 'Description',
                  },
                },
              ],
            },
          },
        },
        {
          id: 'endEvent_1',
          name: 'End',
          type: 'endEventNone',
        },
      ],
      edges: [
        {
          id: 'edge_1',
          source: 'startEvent_1',
          target: 'activity_1',
        },
        {
          id: 'edge_2',
          source: 'activity_1',
          target: 'endEvent_1',
        },
      ],
    },
  }
  • process.nodes.type
Name Description
startEventAtom Start Event (Draft): Binding to the specified Atom Class through options.atom and options.conditionExpression. Automatically start the matching workflow definition when the specified Atom is submitted
activityUserTask User Task: Can specify participants, whether to bid, completion conditions, read field permissions, write field permissions, etc.
endEventNone End Event