Advanced 40 min read

Project: Case Management Workspace

By the end of this lesson, you'll be able to:

  • Update Case status inline within a datatable
  • Surface a safe, specific error message on a failed status change
  • Apply the Controller/Service/Selector pattern to a Case-focused feature

Prerequisites: "Project: Contact Management Application"

What We're Building

A caseWorkspace component listing open Cases with an inline-editable Status column (Module 10, Lesson 2), backed by a properly layered Apex Service that validates the transition before saving.

The Apex Layer

// Service — validates and applies the status change
public inherited sharing class CaseService {
    public static void updateStatus(Id caseId, String newStatus) {
        if (newStatus == 'Closed' && String.isBlank(caseId)) {
            throw new AuraHandledException('A case is required to close.');
        }

        Case c = new Case(Id = caseId, Status = newStatus);
        Database.update(c, AccessLevel.USER_MODE);
    }
}

// Controller — thin
public with sharing class CaseController {
    @AuraEnabled
    public static void updateStatus(Id caseId, String newStatus) {
        CaseService.updateStatus(caseId, newStatus);
    }
}

The Component

async handleSave(event) {
    const draftValues = event.detail.draftValues;
    try {
        await Promise.all(draftValues.map(draft =>
            updateCaseStatus({ caseId: draft.caseId ?? draft.id, newStatus: draft.status })
        ));
        this.draftValues = [];
        await refreshApex(this.wiredCasesResult);
        this.dispatchEvent(new ShowToastEvent({ title: 'Cases Updated', variant: 'success' }));
    } catch (error) {
        this.dispatchEvent(new ShowToastEvent({
            title: 'Could Not Update Case',
            message: error.body?.message ?? 'An unexpected error occurred.',
            variant: 'error',
        }));
    }
}

AccessLevel.USER_MODE (Module 12) enforces CRUD/FLS/sharing on the update; AuraHandledException (Module 7) surfaces a specific validation message; Promise.all (Module 10) persists every edited row concurrently.

Exercise

Explain, as a comment, why the status validation lives in CaseService rather than directly in CaseController.

Show hint

Recall Module 16's layering rationale.

APEX

Exercise

Challenge: what happens if Database.update is called without AccessLevel.USER_MODE, for a user without edit access to Case Status?

Show hint

Recall Module 12's CRUD/FLS lesson.

APEX

Project: Case Management Workspace Quiz

1. What layer contains the actual status-change validation?

2. What does AccessLevel.USER_MODE enforce on the update?

3. What persists every edited row from the datatable concurrently?

4. What surfaces a specific validation error to the component?

5. Why does the Controller stay thin in this project?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

An inline-editable Case status workspace, applying Module 10's inline editing, Module 7's AuraHandledException error surfacing, and Module 16's layered Apex structure together.