{"id":21311961,"url":"https://github.com/vhidvz/workflow-template","last_synced_at":"2025-07-11T23:33:01.534Z","repository":{"id":153512506,"uuid":"628691438","full_name":"vhidvz/workflow-template","owner":"vhidvz","description":"This repository has an example of creating a simple workflow microservice with NestJS and WorkflowJS.","archived":false,"fork":false,"pushed_at":"2025-06-30T00:09:43.000Z","size":159,"stargazers_count":20,"open_issues_count":12,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-30T01:23:29.655Z","etag":null,"topics":["nestjs","template","workflow"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vhidvz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-04-16T18:18:06.000Z","updated_at":"2025-04-23T01:13:07.000Z","dependencies_parsed_at":"2023-12-16T09:43:30.982Z","dependency_job_id":"1cca3f5e-befe-4283-821b-a23fbc13a638","html_url":"https://github.com/vhidvz/workflow-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vhidvz/workflow-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vhidvz%2Fworkflow-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vhidvz%2Fworkflow-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vhidvz%2Fworkflow-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vhidvz%2Fworkflow-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vhidvz","download_url":"https://codeload.github.com/vhidvz/workflow-template/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vhidvz%2Fworkflow-template/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264914167,"owners_count":23682792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nestjs","template","workflow"],"created_at":"2024-11-21T17:22:45.038Z","updated_at":"2025-07-11T23:33:01.227Z","avatar_url":"https://github.com/vhidvz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simple Workflow Microservice\n\nThis repository has an example of creating a simple workflow microservice with [NestJS](https://github.com/nestjs/nest) and [WorkflowJS](https://github.com/vhidvz/workflow-js).\n\n# Diagram\n\n![Simple Workflow](./diagram.svg)\n\n# Up and Running\n\nFirst of all need to clone this repository by following command.\n\n```sh\ngit clone https://github.com/vhidvz/workflow-template.git\n```\n\nThen install the node dependencies with command `cd workflow-template \u0026\u0026 npm ci`. after that, install the MongoDB community server by the following command in your terminal.\n\n```sh\ndocker-compose up -d\n```\n\nTo start and run the project type `npm run start`, that's it...\n\n# Usage and Dangling\n\nSwagger UI is also exists and running on [http://[::1]:3000/api](http://[::1]:3000/api) if you need to understand better please look at the `src/`[app.workflow.ts](https://github.com/vhidvz/workflow-template/blob/master/src/app.workflow.ts) file.\n\n## Scenario 1: Requested Service Not Approved\n\n### _Step 1_\n\nCreate a flow by posting a request with plain data `Hi`.\n\n```sh\ncurl --request POST \\\n  --url http://localhost:3000/flow \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"global\": \"Hi\"\n}'\n```\n\n__Response:__ base on the flow definition exclusive gateway `approval_gateway` cannot automatically done, therefor workflow will pauses at this point.\n\n```json\n{\n  \"data\": {\n    \"global\": \"Hi\",\n    \"_id\": \"643fcfe30eaf231a283a539b\"\n  },\n  \"status\": \"paused\",\n  \"tokens\": [\n    {\n      \"id\": \"cc5c8c5baa370eec\",\n      \"history\": [\n        {\n          \"status\": \"completed\",\n          \"ref\": \"StartEvent_0do01j4\",\n          \"name\": \"start\"\n        },\n        {\n          \"status\": \"completed\",\n          \"ref\": \"Activity_0mra47f\",\n          \"name\": \"initial_task\"\n        },\n        {\n          \"status\": \"paused\",\n          \"ref\": \"Gateway_0az0yjr\",\n          \"name\": \"approval_gateway\"\n        }\n      ]\n    }\n  ],\n  \"_id\": \"643fcfe30eaf231a283a539a\",\n  \"__v\": 0\n}\n```\n\n### _Step 2_\n\nFind a flow by mongo id with the following `GET` request.\n\n```sh\ncurl --request GET \\\n  --url http://localhost:3000/flow/643fcfe30eaf231a283a539a\n```\n\n__Response:__ it must be same as the previous result.\n\n### _Step 3_\n\nResume the flow by posting a `PATCH` request with `no` response by user.\n\n```sh\ncurl -X 'PATCH' \\\n  'http://[::1]:3000/flow/643fcfe30eaf231a283a539a/approval_gateway' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"local\": \"no\"\n}'\n```\n\n__Response:__ because of `some_task` is a user task at this state based on [diagram](#diagram) we need to pause flow, therefor another request needed to complete this task.\n\n```json\n{\n  \"_id\": \"643fcfe30eaf231a283a539a\",\n  \"data\": {\n    \"global\": \"Hi, Hello no!\",\n    \"_id\": \"643fcfe30eaf231a283a539b\"\n  },\n  \"status\": \"paused\",\n  \"tokens\": [\n    {\n      \"id\": \"cc5c8c5baa370eec\",\n      \"history\": [\n        {\n          \"ref\": \"StartEvent_0do01j4\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"start\"\n        },\n        {\n          \"ref\": \"Activity_0mra47f\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"initial_task\"\n        },\n        {\n          \"ref\": \"Gateway_0az0yjr\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"no\"\n          },\n          \"name\": \"approval_gateway\"\n        },\n        {\n          \"ref\": \"Activity_1v0hfx6\",\n          \"status\": \"paused\",\n          \"value\": null,\n          \"name\": \"some_task\"\n        }\n      ]\n    }\n  ],\n  \"__v\": 0\n}\n```\n\n### _Step 4_\n\nFinishing flow by resuming task `some_task`.\n\n```sh\ncurl -X 'PATCH' \\\n  'http://[::1]:3000/flow/643fcfe30eaf231a283a539a/some_task' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"local\": \"done\"\n}'\n```\n\n__Response:__ status of context is terminated and could not resume again.\n\n```json\n{\n  \"_id\": \"643fcfe30eaf231a283a539a\",\n  \"data\": {\n    \"global\": \"Hi, Hello no!, received a value from previous task(some value(done) to end event.)\",\n    \"_id\": \"643fcfe30eaf231a283a539b\"\n  },\n  \"status\": \"terminated\",\n  \"tokens\": [\n    {\n      \"id\": \"cc5c8c5baa370eec\",\n      \"history\": [\n        {\n          \"ref\": \"StartEvent_0do01j4\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"start\"\n        },\n        {\n          \"ref\": \"Activity_0mra47f\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"initial_task\"\n        },\n        {\n          \"ref\": \"Gateway_0az0yjr\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"no\"\n          },\n          \"name\": \"approval_gateway\"\n        },\n        {\n          \"ref\": \"Activity_1v0hfx6\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"done\"\n          },\n          \"name\": \"some_task\"\n        },\n        {\n          \"ref\": \"Event_13pwumb\",\n          \"status\": \"terminated\",\n          \"value\": {\n            \"local\": \"some value(done) to end event.\"\n          },\n          \"name\": \"end\"\n        }\n      ]\n    }\n  ],\n  \"__v\": 0\n}\n```\n\n## Scenario 2: Requested Service Approved\n\n### _Step 1_\n\nCreate a flow by posting a request with plain data `Hi`.\n\n```sh\ncurl --request POST \\\n  --url http://localhost:3000/flow \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"global\": \"Hi\"\n}'\n```\n\n__Response:__ would like be previous [scenario](#scenario-1-requested-service-not-approved) but it has different id.\n\n### _Step 2_\n\nResuming the flow by posting a `PATCH` request with `Vahid` response by user.\n\n```sh\ncurl -X 'PATCH' \\\n  'http://[::1]:3000/flow/643fe71df232a501b76cd7d6/approval_gateway' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"local\": \"Vahid\"\n}'\n```\n\n__Response:__ because of `another_task` is a user task at this state based on [diagram](#diagram) we need to pause flow, therefor another request needed to complete this task.\n\n```json\n{\n  \"_id\": \"643fe71df232a501b76cd7d6\",\n  \"data\": {\n    \"global\": \"Hi, Hello Vahid!\",\n    \"_id\": \"643fe71df232a501b76cd7d7\"\n  },\n  \"status\": \"paused\",\n  \"tokens\": [\n    {\n      \"id\": \"9f053a81fa64e7fa\",\n      \"history\": [\n        {\n          \"ref\": \"StartEvent_0do01j4\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"start\"\n        },\n        {\n          \"ref\": \"Activity_0mra47f\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"initial_task\"\n        },\n        {\n          \"ref\": \"Gateway_0az0yjr\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"Vahid\"\n          },\n          \"name\": \"approval_gateway\"\n        },\n        {\n          \"ref\": \"Gateway_0du1v6k\",\n          \"status\": \"terminated\",\n          \"value\": null,\n          \"name\": \"parallel_gateway\"\n        }\n      ],\n      \"locked\": true\n    },\n    {\n      \"id\": \"f44c569ffee96983\",\n      \"history\": [\n        {\n          \"ref\": \"Activity_1yl745l\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"do_some_work\"\n        },\n        {\n          \"ref\": \"Gateway_0ll1i6q\",\n          \"status\": \"paused\",\n          \"value\": null\n        }\n      ],\n      \"parent\": \"9f053a81fa64e7fa\"\n    },\n    {\n      \"id\": \"772454979815fdc1\",\n      \"history\": [\n        {\n          \"ref\": \"Activity_1mzlm3i\",\n          \"status\": \"paused\",\n          \"value\": null,\n          \"name\": \"another_task\"\n        }\n      ],\n      \"parent\": \"9f053a81fa64e7fa\"\n    }\n  ],\n  \"__v\": 0\n}\n```\n\n### _Step 3_\n\nResuming the flow by posting a `PATCH` request with `Finished Successfully` response by user.\n\n```sh\ncurl -X 'PATCH' \\\n  'http://[::1]:3000/flow/643fe71df232a501b76cd7d6/another_task' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"local\": \"Finished Successfully\"\n}'\n```\n\n__Response:__ because of `review` is a user task at this state based on [diagram](#diagram) we need to pause flow, therefor another request needed to complete this task.\n\n```json\n{\n  \"_id\": \"643fe71df232a501b76cd7d6\",\n  \"data\": {\n    \"global\": \"Hi, Hello Vahid!\",\n    \"_id\": \"643fe71df232a501b76cd7d7\"\n  },\n  \"status\": \"paused\",\n  \"tokens\": [\n    {\n      \"id\": \"9f053a81fa64e7fa\",\n      \"history\": [\n        {\n          \"ref\": \"StartEvent_0do01j4\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"start\"\n        },\n        {\n          \"ref\": \"Activity_0mra47f\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"initial_task\"\n        },\n        {\n          \"ref\": \"Gateway_0az0yjr\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"Vahid\"\n          },\n          \"name\": \"approval_gateway\"\n        },\n        {\n          \"ref\": \"Gateway_0du1v6k\",\n          \"status\": \"terminated\",\n          \"value\": null,\n          \"name\": \"parallel_gateway\"\n        }\n      ],\n      \"locked\": true\n    },\n    {\n      \"id\": \"f44c569ffee96983\",\n      \"history\": [\n        {\n          \"ref\": \"Activity_1yl745l\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"do_some_work\"\n        },\n        {\n          \"ref\": \"Gateway_0ll1i6q\",\n          \"status\": \"terminated\",\n          \"value\": null\n        }\n      ],\n      \"parent\": \"9f053a81fa64e7fa\",\n      \"locked\": true\n    },\n    {\n      \"id\": \"772454979815fdc1\",\n      \"history\": [\n        {\n          \"ref\": \"Activity_1mzlm3i\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"Finished Successfully\"\n          },\n          \"name\": \"another_task\"\n        },\n        {\n          \"ref\": \"Activity_1cqjzpt\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"pay_money\"\n        },\n        {\n          \"ref\": \"Gateway_0ll1i6q\",\n          \"status\": \"terminated\",\n          \"value\": null\n        }\n      ],\n      \"parent\": \"9f053a81fa64e7fa\",\n      \"locked\": true\n    },\n    {\n      \"id\": \"191b71808f807535\",\n      \"history\": [\n        {\n          \"ref\": \"Gateway_0ll1i6q\",\n          \"status\": \"completed\",\n          \"value\": null\n        },\n        {\n          \"ref\": \"Activity_0thx22h\",\n          \"status\": \"paused\",\n          \"value\": null,\n          \"name\": \"review\"\n        }\n      ]\n    }\n  ],\n  \"__v\": 0\n}\n```\n\n### _Step 4_\n\nFinishing flow by resuming task `review`.\n\n```sh\ncurl -X 'PATCH' \\\n  'http://[::1]:3000/flow/643fe71df232a501b76cd7d6/review' \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"local\": \"review\"\n}'\n```\n\n__Response:__ status of context is terminated and could not resume again.\n\n```json\n{\n  \"_id\": \"643fe71df232a501b76cd7d6\",\n  \"data\": {\n    \"global\": \"Hi, Hello Vahid!, received a value from previous task(review to end event.)\",\n    \"_id\": \"643fe71df232a501b76cd7d7\"\n  },\n  \"status\": \"terminated\",\n  \"tokens\": [\n    {\n      \"id\": \"9f053a81fa64e7fa\",\n      \"history\": [\n        {\n          \"ref\": \"StartEvent_0do01j4\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"start\"\n        },\n        {\n          \"ref\": \"Activity_0mra47f\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"initial_task\"\n        },\n        {\n          \"ref\": \"Gateway_0az0yjr\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"Vahid\"\n          },\n          \"name\": \"approval_gateway\"\n        },\n        {\n          \"ref\": \"Gateway_0du1v6k\",\n          \"status\": \"terminated\",\n          \"value\": null,\n          \"name\": \"parallel_gateway\"\n        }\n      ],\n      \"locked\": true\n    },\n    {\n      \"id\": \"f44c569ffee96983\",\n      \"history\": [\n        {\n          \"ref\": \"Activity_1yl745l\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"do_some_work\"\n        },\n        {\n          \"ref\": \"Gateway_0ll1i6q\",\n          \"status\": \"terminated\",\n          \"value\": null\n        }\n      ],\n      \"parent\": \"9f053a81fa64e7fa\",\n      \"locked\": true\n    },\n    {\n      \"id\": \"772454979815fdc1\",\n      \"history\": [\n        {\n          \"ref\": \"Activity_1mzlm3i\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"Finished Successfully\"\n          },\n          \"name\": \"another_task\"\n        },\n        {\n          \"ref\": \"Activity_1cqjzpt\",\n          \"status\": \"completed\",\n          \"value\": null,\n          \"name\": \"pay_money\"\n        },\n        {\n          \"ref\": \"Gateway_0ll1i6q\",\n          \"status\": \"terminated\",\n          \"value\": null\n        }\n      ],\n      \"parent\": \"9f053a81fa64e7fa\",\n      \"locked\": true\n    },\n    {\n      \"id\": \"191b71808f807535\",\n      \"history\": [\n        {\n          \"ref\": \"Gateway_0ll1i6q\",\n          \"status\": \"completed\",\n          \"value\": null\n        },\n        {\n          \"ref\": \"Activity_0thx22h\",\n          \"status\": \"completed\",\n          \"value\": {\n            \"local\": \"review\"\n          },\n          \"name\": \"review\"\n        },\n        {\n          \"ref\": \"Event_13pwumb\",\n          \"status\": \"terminated\",\n          \"value\": {\n            \"local\": \"review to end event.\"\n          },\n          \"name\": \"end\"\n        }\n      ]\n    }\n  ],\n  \"__v\": 0\n}\n```\n\n## License\n\nThis project is licensed under the MIT License - SEE the [LICENSE](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvhidvz%2Fworkflow-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvhidvz%2Fworkflow-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvhidvz%2Fworkflow-template/lists"}