Article

Why phase one of an approval or workflow system should define the state machine and exception branches before counting screens

Teams often begin workflow projects by discussing lists, detail pages, pending queues, and buttons. The real delivery risk usually sits elsewhere: how many states exist, which actions change them, how exceptions enter and exit the flow, when humans may override the system, and how that override is traced. If those boundaries stay vague, faster UI delivery usually just produces faster rework.

Published

May 5, 2026

Reading Time

7 min

Process

approval workflow systemstate machine designexception branchweb app development

Workflow systems rarely fail because they have too few features. They fail because the state truth is unclear

Approval, ticketing, purchasing, reimbursement, after-sales, and order-flow systems may look like forms plus steps on the surface, but the hard part is state handling. Draft, submitted, returned, rejected, cancelled, additional-information, re-approval, and manual takeover all need consistent meaning across product, engineering, and operations.

In projects like these, I usually do not treat full screen coverage as the first milestone. A steadier phase one defines the state machine, key actions, exception branches, and logging rules first, because long-term maintainability depends far more on that structure than on whether every list view is already built.

Define states first, or the screens and APIs will each invent their own logic

Many requirement documents jump straight into “submission page,” “approval page,” “pending list,” and “detail page” without ever establishing a clear state dictionary. Then the frontend treats “returned” and “rejected” as nearly the same thing, the backend mixes “cancelled” with “closed,” and the business team expects “waiting for additional information” to still behave like an active approval item. Every piece can be built, yet the workflow remains ambiguous.

A stronger starting point is to list the full set of possible states for one business object, then define which actions are allowed in each state, which new state follows, and which roles can trigger the transition. Once that map is stable, filters, buttons, notifications, reports, and audit records become much easier to align.

Name each state, its meaning, and its entry condition before discussing layout details

Separate confusing business actions such as return, reject, withdraw, and void into explicit definitions

Document editability, approvability, and reminder behavior per state together with permissions

Exception branches are not patches. Frequent ones belong in the first model

Systems often fall back to offline handling not because the main path is broken, but because no one designed the exception paths. What happens when an approver is absent, when additional documents are submitted, when an urgent case skips a step, or when a high-value request needs escalation? If those answers live only in chat messages and temporary judgment, the company ends up with one workflow in the system and another one in reality.

Not every edge case deserves automation on day one, but frequent and predictable exceptions should not be treated as implementation leftovers. If an exception happens often enough to change ownership, timing, or risk, it belongs in the model early.

Separate noisy edge cases from recurring exceptions; recurring ones deserve design attention

Escalation, temporary delegation, additional-information loops, and withdraw-and-resubmit paths usually need explicit modeling

If an exception can only be explained in remarks, the system boundary is probably still weak

Manual overrides need their own rules instead of pretending the workflow is fully automatic

Real delivery always includes legitimate human intervention: an administrator submits on behalf of someone else, a manager temporarily reassigns a case, finance corrects a state, service staff backfills data, or operations revert a mistake. If the system allows none of that, people start editing databases or going back to spreadsheets. If everyone can change any status freely, traceability and accountability disappear just as quickly.

That is why manual override is not a yes-or-no decision. It should be designed as a controlled capability. The team needs to decide who can override what, under which conditions, whether the original value and reason are preserved, whether extra confirmation is needed, and whether the change triggers notifications.

Design manual correction as a small set of controlled actions rather than as a hidden backdoor

Keep the original state, operator, timestamp, and reason for important overrides

Define whether the workflow resumes automatically after an override or waits for explicit review

Screens, APIs, notifications, and reports should all be derived from the same state machine

Teams often hold separate discussions for frontend pages, backend APIs, message notifications, and reporting needs. Each area may sound reasonable on its own, yet the combined system still feels inconsistent. The usual reason is not that one module failed. It is that no one shared a single definition of workflow truth.

Once the state machine and exception branches are agreed on first, many implementation decisions become simpler. Teams can determine which lists need grouping, which buttons appear in which states, which notifications are triggered by transitions, which reports count actions, and which APIs require stronger idempotency guarantees. The upfront discussion may feel slower, but it usually removes a large amount of rework later.

Main takeaways

The backbone of a workflow system is the state machine, the action set, and the exception branches, not the screen tree alone.

If frequent exceptions and manual override boundaries are undefined, the system usually supports only the happy path.

Pages, APIs, notifications, and reports should all be derived from the same workflow truth if the product is expected to remain maintainable.

Related Services

Related Articles

If you are building a workflow system, define the state map and exception list before expanding scope

We can first map the core states, key actions, exception branches, manual override rules, and logging requirements, then decide which screens and interfaces belong in phase one.