In any Salesforce implementation, data integrity and access control are key pillars of system security. While Salesforce provides standard profiles and permission sets to control user access, there are times when you need to go beyond declarative settings and introduce custom logic—especially when it comes to sensitive actions like record deletion.
This blog showcases a practical and highly relevant use case: restricting the deletion of Case records to only users with the “System Administrator” profile using an Apex trigger. It’s a powerful technique to add an extra layer of protection over your support or customer service processes, ensuring that only the right people have the ability to delete critical Case records.
You’ll learn how to write a before delete trigger that checks the profile of the logged-in user and blocks the delete action for anyone not holding the required profile, delivering a custom error message in real time.
🧠 Why Restricting Delete Actions Is Important
By default, if a user has the Delete permission on an object, they can remove records—even if those records are important, linked to other data, or needed for auditing purposes. While this level of access is fine for trusted users, it poses a huge risk if left unchecked for standard profiles.
With this trigger, you enforce a custom business rule at the code level, making it impossible for anyone other than a System Administrator to delete Case records, regardless of what their profile permissions allow. This is especially helpful in organizations where:
-
Case records are tied to compliance and audit processes
-
Deleting a Case could lead to data loss or broken automation
-
You want to hardcode a business rule without relying solely on profile settings
🔍 What You’ll Learn in This Blog
-
How to write a before delete Apex trigger in Salesforce
-
How to compare the current user’s profile ID with a specific profile (System Administrator)
-
How to use
addError()
to prevent the deletion and display a custom message -
Why using profile-level checks inside code can be more reliable than relying only on permissions
-
How to keep your Apex logic clean, reusable, and secure
⚙️ How the Trigger Works – Under the Hood
This solution uses a simple handleBeforeDelete
method inside a trigger handler class, which gets called during the before delete
context of the Case
object.
Here’s the core flow:
-
Use
UserInfo.getProfileId()
to get the current user’s profile. -
Query the
Profile
object to retrieve theId
of the System Administrator profile. -
Loop through each Case record in
Trigger.old
and compare the user’s profile ID to the System Administrator profile ID. -
If they don’t match, the code uses
addError()
on the record to block the deletion and show a message like:“You don’t have the rights. Go away!”
This is a lightweight, secure, and easy-to-deploy solution that can be extended for any object where restricted deletion is necessary.
🎯 Where and When to Use This Approach
This method is ideal for:
-
Case records in support-driven organizations
-
Finance or HR objects where data must be preserved
-
Custom objects tied to regulatory or client data
-
Scenarios where audit compliance prohibits unauthorized deletions
It’s also a great learning exercise for Salesforce developers to explore how Apex can be used to enforce logic not achievable through configuration alone.
👨💻 Customization Ideas
-
Modify the logic to allow deletion by a set of specific profiles, not just System Admins
-
Allow deletion only if the Case is in a closed or specific status
-
Track attempted deletions using custom logging or create a custom notification
-
Add dynamic logic based on record type or business unit
🎥 Learn with a Visual Guide – YouTube Playlist Included
To make implementation easier, we’ve included a YouTube playlist where you can follow along step-by-step. It covers the complete setup, code explanation, and even tips to debug and deploy.
Solution:
public class CaseTriggerHandler {
public static void handleBeforeDelete (List<Case> oldRecords) {
Id currentUserProfileId = UserInfo.getProfileId(); User Info.
Id sysAdminProfileId = [SELECT Id, Name FROM Profile WHERE Name = ‘System
Administrator’ LIMIT 1].Id;
for (Case caseRec : oldRecords) {
if (sysAdminProfileId != currentUserProfileId) {
caseRec.addError(‘You dont have the rights. Go away!’);|
}
}
}
}