I built the backend for a service request platform clients use to raise, approve, and track operational configuration changes. On paper it's "workflow automation." In practice it's a long negotiation about which decisions a machine should make and which ones a person must.
Automate the path, not the judgment
The engine handles multi-level approval flows across several request categories, tracks SLAs, and manages the full lifecycle of a request automatically. What it deliberately doesn't do is make the approval decision. A human approves; the system routes, reminds, escalates, records, and enforces the rules around that decision.
That line — automate the path, keep the judgment human — is the whole design philosophy. Cross it and you get a system people quietly route around because it makes choices they don't trust.
SLAs are promises with teeth
Tracking an SLA is easy. Making it mean something is the work: when does the clock start, what pauses it, who gets escalated to when it's about to breach. I learned to model SLA state explicitly rather than computing it on the fly — a request always knows where it stands.
Time zones are a feature, not a footnote
Clients schedule SOP timings for equipment across 500+ sites in multiple time zones. "9am" is not a time; it's a time somewhere. Storing and reasoning in UTC, and converting only at the edges, saved me from an entire genus of bugs.
The 20+ APIs are the easy part
Request creation, approval transitions, lifecycle queries — straightforward once the state machine is right. The state machine is the product. Get the states and transitions honest, and the endpoints almost write themselves.
Good workflow automation is invisible: it removes the busywork around a decision while leaving the decision exactly where it belongs.