Skip to work

"It's just an approval workflow" is the most expensive sentence in procurement software

In the demo, it's three boxes: request, manager, CFO. Everyone nods. Then production shows up with questions the canvas never asked.

2 min read

  • procure-to-pay
  • workflow-engine
  • fintech
  • product

The questions the canvas never asked

  • The approver left the company last month, and the workflow still points at them.
  • The amount lands exactly on the threshold. Above 10k goes to finance. Is 10k above 10k?
  • The request was approved, then someone edited one line. Does the whole chain re-run, or just the delta? Who decides that?
  • The manager is on leave and delegated their approvals. Does the delegate's own delegation count? Until when?
  • Approval by group: any of the five? All of them? Three out of five? In what order?
  • A condition depends on an answer given two steps earlier. That answer just changed.

I spent two years shipping and maintaining an approval workflow engine at a procurement fintech. The three boxes took a sprint. The list above took the rest.

How we actually answered it

We froze the workflow at init: conditions resolved once at launch, and a running request never re-derived them. Mid-flight edits simply didn't exist. Approval groups came straight from the teams in the HRIS. Vacations earned a proper feature, a replacement approver that applied even to workflows already running, because absence is the one thing you can't freeze. And the approver who had left the company? Fixed by hand, more often than I'd like to admit.

Freezing at init isn't a hack. It's the honest trade-off: deterministic, auditable, and it quietly declines half the list above.

A workflow builder is a programming language your users never asked to learn

Every condition is syntax, every unhandled edge case is a bug they'll file. So my opinion hasn't moved: keep the engine boring, deterministic, tested code, and derive the configuration from the systems that already know the answer, editable in plain language.

That is what ledgerloop does with the HRIS, and what the components in approvals-ui model directly: quorum gates, amount thresholds, and a policy lint that knows what segregation of duties means. Which one of these bit you first?