Skip to content
← Back to case studies

Multi-step workflow engine built from scratch

A generic workflow engine inside the ERP: step definition, rule-driven progression, side effects on completion and an SLA job that flags overdue work.

Industry
Apparel and fashion manufacturing
Period
2026
Role
Architect and main author
Scale
33 routines and classes

33

routines and classes

SLA

with automatic overdue alerts

1

generic engine, many processes

Technologies

InterSystems IRISObjectScriptAsync jobsRESTERP customisation layerWhatsApp notifications

Challenge

The client had several internal processes with the same shape: a sequence of steps, each with an owner, a deadline and a completion criterion. Each of those processes had been solved with its own dedicated screen and rules scattered inside it. None of them had a tracked deadline. And changing the order of a step meant touching code.

The request that came in was for one new process. Except several just like it already existed.

Solution

Instead of delivering yet another dedicated screen, I built a generic workflow engine inside the ERP, split into four pieces by responsibility.

Step definition. The flow’s definition became data: sequence, owning team, deadline, advancement condition, required attachments and what fires on completion. Changing the flow means changing configuration.

Activation and advancement engine. It is the only piece that knows how to change the state of a flow instance. It validates the advancement condition, records who advanced it and when, and activates the next step. No screen writes state directly.

Side effects per step. Completing a step can trigger a business action. In the first process, product registration, the last step creates the item in the ERP from the data accumulated along the flow, which ends the retyping at the end of the process. The mapping between a form field and where that data is stored is configuration too, validated against the ERP’s own customisation layer: the standard API creates the bare item and the engine fills in the rest, without waiting for the vendor to expose every field through the API.

SLA job. It runs asynchronously, looks for overdue steps and notifies. It is what gives the configured deadline any practical effect.

There is also an operational dashboard that shows where each instance is stuck, for how long, and with whom.

Outcome

A new process comes in as step configuration, not as development. The most visible management gain is the overdue alert: information that used to surface only when someone complained now arrives on its own. The engine grew to the point where another developer on the team added a piece without touching the core, which is the best test that the separation of responsibilities worked.

What this case shows

I saw that the one-off request was an instance of a wider class, and solved the class. The design separates who defines the flow, who changes its state and who displays it on screen. Deadlines here are part of the process, not a report someone pulls afterwards.

Stuck on a term? There is a glossary. Glossary