We have a really complex workflow, it can be considered similar to building a house.
As a first step, a person submits an application for a building permit. This building permit needs to be sent to the correct department/person, depending on the type of building and location. It could also be a group of people (e.g. city planning department). The approver shall receive in email that a new application is awaiting review, and there shall be periodic reminders if no action has been taken. Once approved, certain tasks shall be created in our system, e.g. "Pour concrete", "Construct walls". Some of them can be handled in parallel (windows can be installed while electricity is being installed), while others require other activities to be completed first (e.g. you can't add a roof if there are no walls). We also can't create all tasks right away, as they will depend on decisions along the way - maybe it hasn't been decided yet if solar panels should be added. We don't want to add a "Add solar panels" task and close it as "not applicable". Instead, at an appropriate time during the workflow, when the decision is made that solar panels shall be installed, only then the relevant tasks would be created. There are also some review/approval steps along the way - can't start working on the roof if the walls were not built according to the correct standard. During this whole workflow the overall project moves between different statuses (application submitted, application approved/rejected, final review, done etc.).
It would be great if we could visualize this workflow, or even let the client design it in a visual designer, instead of just writing code.
We would prefer if we didn't have to build "simple" functionality like sending emails ourselves, but a lot of our logic requires updating entities in our SQL database, or possibly even invoking external APIs. ELSA looks very promising, but I couldn't quite understand how to translate the samples to a real-world application. It seemed like if we use ELSA endpoints, then ELSA would basically replicate the whole project status inside the workflow...? Basically, ELSA would keep a copy of all projects and tasks...? We would prefer if we could keep using our own entities, so we can build our own task list etc., and persist it the way we see fit.
Do we have to use custom activities?
The process you describe sounds like it could be very elegantly handled in a workflow, which would orchestrate what tasks to create when, and continue the process as tasks completes, further determining the next steps to take (create tasks, send emails, send Slack notifications, etc).
Elsa most certainly will not have to store your business entities like projects and tasks. These remain in your own application. Instead, Elsa would invoke (custom) activities that interact with your system to create projects and tasks there. Elsa would merely act as an orchestrator.
Although I don't have an example for Elsa 2, I did write a small guide for Elsa 3 that demonstrates a very similar (yet simplified) process.
In a nutshell, the guide demonstrates the following concepts:
You can find the guide demonstrating these ideas here.
The workflow looks like this:
The activities "Create Email Account", "Create Slack Account", etc. are RunTask
activities, which do nothing more than tell your own system to perform a task called e.g. "Create Slack Account".
It is then up to your system to do something with this request. In the guide, I provided a simple ASP.NET MVC application that simply creates a domain-specific entity called OnboardingTask
and add it to the database.
It is then up to a user of this system to complete the tasks. As they do so, they click a "Complete" button, which sends a message to the workflow server, which in turn continues the workflow, which then creates more tasks for the user to complete, until the workflow completes.
Besides using the generic RunTask
activity, you can easily implement custom activities that interact with your system.
For example, you could create a PerformTask
activity that invokes an API endpoint on your system, that then creates a task.
Your activity could then wait for the created task to be completed. It would be up to your system to send a signal when the task eventually does complete, e.g. via HTTP or AMQP. When said signal is received by the workflow server, it will resume your PerformTask
activity, in response to which the activity should complete ad yield control back to the overal workflow to continue to the next step(s).