Appian ACD301 study materials
Appian ACD301 study resources

The Approval That Never Times Out

Appian ACD301 · Put your knowledge to work in context.

All case studies

The Approval That Never Times Out

A purchase-request process routes to a manager for approval via a User Input Task. The task is assigned to a group, and any member can claim it. In production, 18% of requests sit in the approval task for more than 30 days because the assigned group has no active members during a reorganization. There is no escalation configured. Separately, the process has a timer event on the task set to 7 days that fires a reminder, but the reminder goes to the same empty group, so nobody sees it. Finance wants requests to auto-escalate to a director after 10 days and to auto-reject after 30 days, with the requester notified at each step. The process currently has no way to distinguish "claimed but stalled" from "never claimed."

1. Design the escalation logic so that the 10-day and 30-day rules behave correctly, including the claimed-vs-unclaimed distinction.

Read the worked answer

The key insight is that a single timer on the user task cannot express both rules reliably, because the timer's clock starts when the task is created, not when it is claimed. The design should use two independent timer paths plus a status flag.

  1. On task creation, record taskStatus = UNCLAIMED and a createdAt timestamp.
  2. When a user claims the task, update taskStatus = CLAIMED and set claimedAt.
  3. A boundary timer event at 10 days from creation fires an escalation path. That path checks taskStatus: if still UNCLAIMED, reassign to the director group and notify the requester. If CLAIMED, the work is in progress - escalate to the director as a nudge but do not reassign, or the claimer loses their work.
  4. A second boundary timer at 30 days fires the auto-reject path unconditionally, notifying the requester and the current assignee.

Critical detail: boundary timers must be interrupting vs. non-interrupting chosen deliberately. The 10-day reminder should be non-interrupting (task stays open); the 30-day reject should be interrupting (task is cancelled and the process moves to rejection).

2. The existing 7-day reminder fires but nobody sees it. What is the root cause and the general fix?

Read the worked answer

The reminder is delivered to a group with no active members, so the notification has no recipient. The process is technically working; the delivery target is empty.

The general fix is to stop treating group membership as a guaranteed delivery channel. Options, in order of preference:

  • Validate group membership at runtime before sending: if the group has zero active members, route to a fallback assignee (e.g., the group's manager or a configured backup group) and log the substitution.
  • Add a monitoring check that alerts administrators when a task sits unclaimed beyond a threshold, independent of the reminder mechanism.
  • Assign to a role or a specific user where accountability is required, rather than an open group.

The 18% figure is the symptom; the cause is that the process has no concept of "this task is going nowhere." Escalation timers are the structural fix, and the reminder should be a secondary layer, not the primary safety net.

3. Finance also wants to know, at any time, how many requests are stalled. What should the process expose to make this answerable?

Read the worked answer

The process should write a process status record (or update a field on the request record) at each state transition: created, claimed, escalated, rejected, approved - with timestamps. Without persisted state transitions, "stalled" can only be inferred from task age, which conflates claimed-but-slow with never-claimed.

With those fields, "stalled" becomes a queryable definition, e.g., taskStatus = UNCLAIMED AND daysSinceCreation > 10. Finance can then build a report on the record type rather than asking someone to inspect running process instances, which is neither scalable nor auditable.

The design principle: if a business question must be answerable at any time, the process must persist the data that answers it, not rely on the process engine's internal state.