DEV Community

Cover image for How I Built a Multi-Level Approval Process (L1, L2, L3) with Locking, Emails, and Escalation — A Developer’s Story
Peter Parser
Peter Parser

Posted on

How I Built a Multi-Level Approval Process (L1, L2, L3) with Locking, Emails, and Escalation — A Developer’s Story

ProcessInstance, ProcessWorkItem, auto field updates, and the day I learned why escalation rules save careers.


🏢 Once upon a time in a mid-sized company…

We had a purchase request system.

It looked fine on the surface — users could submit requests, data was stored, reports existed.

But there was one massive problem:

There was no approval system.

And that created chaos.

  • Finance didn’t trust the numbers
  • Department heads didn’t know what they were approving
  • Requests were being edited after submission
  • The CFO saw critical approvals 2 weeks late

That’s when I got the task:

“Build a structured L1 → L2 → L3 approval process.
With record locking, automated emails, escalation rules, and audit-ready tracking.”

This wasn’t just a feature.
It was a system that would define how decisions move inside the company.

Here’s exactly how I built it — step by step.


🔐 1. Record Locking & Unlocking (Data Integrity First)

❌ Problem

Users were editing records even after submitting them for approval.

That meant:

  • Approvers were reviewing moving targets
  • Decisions became invalid
  • Audit trails were unreliable

✅ Solution

I implemented state-based record locking.

  • When a record is submitted → it becomes read-only
  • If rejected → it becomes editable again
  • If fully approved → it is permanently locked

🧠 Logic

if(status == "Submitted" OR "L1 Approved" OR "L2 Approved")
    isLocked = true
else
    isLocked = false
Enter fullscreen mode Exit fullscreen mode

💡 Insight

Locking isn’t just a feature — it’s what makes approvals trustworthy.


👥 2. Designing L1, L2, L3 Approval Levels

I mapped the approval hierarchy to real business roles:

Level Role Responsibility
L1 Department Head Validate request legitimacy
L2 COO Operational approval
L3 CFO Financial approval

Rules I enforced:

  • Each approver can:

    • ✅ Approve
    • ❌ Reject
    • 💬 Add comments
  • ❗ No one can modify previous decisions

  • 🔄 Rejection at any level sends the request back to the requester

💡 Insight

Approval systems are not technical flows — they are organizational trust layers.


📧 3. Automated Email Notifications (Communication Layer)

Approvals fail without visibility.

So I built a trigger-based email system tied to each stage.

📌 Email Triggers

  • On submission → notify L1
  • On L1 approval → notify L2 + requester
  • On L2 approval → notify L3
  • On final approval → notify requester + finance
  • On rejection → notify requester with reason + unlock info

📨 Example Email (L1 → L2)

Subject: L1 Approved — Pending COO Review

Hi [COO Name],

Request #[Record ID] has been approved by the Department Head.

Please review and take action before [Due Date].

Thanks,
System Automation
Enter fullscreen mode Exit fullscreen mode

💡 Insight

Emails are not notifications.
They are decision triggers.


🔄 4. Automated Field Updates (State Management)

To keep everything trackable, I designed a clear status lifecycle.

🔁 Status Flow

Draft → Submitted → L1 Approved → L2 Approved → Final Approved
                ↓           ↓            ↓
             Rejected    Rejected     Rejected
                ↓           ↓            ↓
              Unlock      Unlock       Unlock
Enter fullscreen mode Exit fullscreen mode

🧩 Fields I maintained

  • Status
  • Last_Approved_By
  • Last_Approved_Date
  • Next_Approver_Name
  • Is_Locked

Each approval step automatically updated these fields using Flows / Apex logic.

💡 Insight

If your status field is messy, your entire system becomes untraceable.


⏰ 5. Escalation Rules (The Real Game-Changer)

This is where the system went from “good” to “production-ready”.

🚨 Problem

Approvers delay.

Always.

✅ Solution: Time-based escalation

Rule 1:

  • If L1 pending > 48 hours → Reassign to L2 → Send escalation email

Rule 2:

  • If L2 pending > 24 hours → Notify CFO (view-only) → Send daily reminder to COO

🔥 Why this matters

  • Prevents bottlenecks
  • Removes dependency on manual follow-ups
  • Keeps process moving without friction

💡 Insight

Escalation rules don’t just improve systems —
they protect deadlines, teams, and accountability.


🧠 6. The Core Engine: ProcessInstance & ProcessWorkItem

This is the part that separates beginners from real Salesforce developers.

📦 ProcessInstance

Represents the entire approval process for one record.

Stores:

  • Overall status → IN_PROGRESS, APPROVED, REJECTED
  • Start time / end time
  • Current stage

🧩 ProcessWorkItem

Represents each approval step.

Stores:

  • Assigned approver
  • Step status (Pending / Approved / Rejected)
  • Due date
  • Escalation status
  • Comments

🔍 Real-world query example

Find all L2 approvals that are pending and escalated

This is critical for:

  • Dashboards
  • Reporting
  • Audits

💡 Insight

Without these objects, your system has no memory.
And without memory, there is no audit.


📊 7. Final Architecture Snapshot

User submits request
    → Lock record
    → Create ProcessInstance
    → Create ProcessWorkItem (L1)
    → Send email to L1

L1 approves
    → Update status
    → Create ProcessWorkItem (L2)
    → Notify L2

L2 approves
    → Update status
    → Create ProcessWorkItem (L3)
    → Notify L3

L3 approves
    → Final approval
    → Permanently lock record
    → Close ProcessInstance
    → Send final email
Enter fullscreen mode Exit fullscreen mode

🧪 8. What I’d Improve Next Time

No system is perfect. Here’s what I’d upgrade:

  • 🔀 Parallel approvals (e.g., L2 + Legal together)
  • 🔔 24-hour reminders (not just escalation)
  • ⚡ Store approval history as JSON for faster UI rendering
  • 📊 Build dashboards for real-time approval tracking

✅ Key Lessons from This Build

  • 🔐 Locking is non-negotiable for data integrity
  • 📧 Emails without escalation = ignored notifications
  • 🧠 ProcessInstance + ProcessWorkItem = audit backbone
  • 🧪 Always test escalations using mock overdue scenarios

🔁 Final Thought

If you’ve ever built approval systems, you already know:

L1 is fast. L2 is busy. L3 is critical.

Each level behaves differently.
Your system must respect that.


🚀 Closing

This project wasn’t just about approvals.

It was about:

  • Building trust in data
  • Creating accountability
  • Designing systems that work *without constant human follow-up

If you're building something similar or want to discuss architecture decisions, feel free to connect. Always happy to exchange ideas 🚀

Top comments (0)