โ† Pattern library

Collaboration

Approval Request

A submitter sends a resource (document, expense, design) to one or more approvers, who can approve, reject with reason, or request changes.

๐ŸŒฟ

When to use this

For workflows requiring human sign-off โ€” expense reports, design reviews, content publishing, code merges.

collabapprovalworkflowreviewsign-off
โœจ Built using these library patterns:
approval

What I assumed

I made these guesses to fill gaps. Let me know if any are wrong.

    Flow diagram

    Step-by-step recipe

    Copy this and paste into Cursor, Claude Code, or v0.

    PATTERN: Approval Request
    INPUT: submitter, resource, approvers[], approval_rules
    OUTPUT: approved | rejected | changes_requested
    
    STEPS:
      1. Submitter creates resource and clicks "Submit for approval"
      2. Submitter selects approver(s) โ€” single, all-required, or any-of
      3. Notification sent to each approver (email + in-app, composable_with: notification)
      4. Resource enters "pending approval" state, locked from edits
      5. Each approver opens resource, sees full content + approval panel
      6. Approver chooses: Approve, Reject (with reason), or Request changes (with comment)
      7. IF approve โ†’ record decision, check if approval rule satisfied
      8. IF rule satisfied (e.g., 2-of-3 approved) โ†’ mark resource Approved, trigger downstream
      9. IF reject โ†’ notify submitter with reason, return resource to draft state
      10. IF request changes โ†’ submitter gets notification with comments, can edit and resubmit
      11. All decisions logged in activity feed (composable_with: activity-feed)
    
    ERROR_HANDLING:
      - All approvers OOO โ†’ escalate to backup or auto-route after N days
      - Approver leaves company โ†’ admin can reassign pending approvals
      - Submitter retracts mid-review โ†’ notify approvers, mark withdrawn
      - Conflicting approver decisions (one approves, one rejects) โ†’ policy: rejection wins, OR escalate to senior
    
    EXTENSION_POINTS:
      - Comment thread on the resource (composable_with: ["comment"])
      - @mention specific approvers (composable_with: ["mention"])
      - Auto-route based on amount/category (composable_with: ["routing"])
      - Audit trail in activity feed (composable_with: ["activity-feed"])
    

    States โ€” how things change

    StateDescriptionTransitions
    DraftSubmitter editing freely
    • Submittedโ†’Pending approval
    Pending approvalLocked, awaiting approver decisions
    • Rule satisfiedโ†’Approved
    • Rejectedโ†’Rejected
    • Changes requestedโ†’Changes requested
    • Withdrawnโ†’Draft
    Changes requestedSubmitter editing per feedback
    • Resubmittedโ†’Pending approval
    ApprovedFinal approval reached, downstream triggeredterminal
    RejectedResource will not proceedterminal

    Easy-to-miss situations

    The kinds of edge cases that break demos.

    • What if all approvers are on vacation?

      medium

      Request stalls indefinitely, blocks downstream work.

      Suggested handling: Per-user "out of office" delegate set in profile. After 3 business days no response, auto-escalate to backup or manager.

    • What if two approvers give conflicting decisions?

      medium

      One approves, another rejects โ€” what wins?

      Suggested handling: Define explicit policy upfront: "Any rejection blocks approval" OR "Senior approver tiebreaker". Show policy on the approval panel so approvers know stakes.

    • What if the submitter changes the resource AFTER approval?

      high

      Approval becomes meaningless, downstream acts on different content.

      Suggested handling: Lock the resource on approval. To change, submitter must withdraw or restart approval cycle. Keep version history showing what was approved.

    • What if an approver is also the submitter?

      medium

      Self-approval defeats the purpose.

      Suggested handling: Block submitter from being in approver list (or auto-skip their vote). Show clear UI: "You can't approve your own request โ€” adding additional approvers".

    • What if the approval is for a high-stakes action (large expense)?

      high

      Higher fraud risk, need additional verification.

      Suggested handling: Tier approvals by amount: <$1k auto, $1k-10k manager, >$10k VP + 2FA. Require typed reason for high-value approvals to slow careless clicks.

    Composes well with

    Combine these patterns when you need a richer flow.

    Build a flow starting from this pattern โ†’