Skip to content

Class Name: CategoryController

Last Updated: 2025-10-22 Source Code: https://github.com/AANP-IT/I2C.Salesforce.Metadata/blob/STAGING/force-app/main/default/classes/CategoryController.cls

API Name: CategoryController Type: Controller (LWC Backend) Test Coverage: [To be verified]

Business Purpose

The CategoryController provides a Lightning Web Component interface for retrieving ProductCategory IDs by category name. This lightweight utility supports storefront filtering and category-based product discovery functionality, enabling LWC components to resolve category names to IDs for navigation and filtering purposes.

Class Overview

Scope and Sharing

  • Sharing Model: without sharing (bypasses record-level security)
  • Access Modifier: public
  • Interfaces Implemented: None

Key Responsibilities

  • Resolve ProductCategory IDs from category names for LWC components
  • Validate user access to ProductCategory object
  • Provide cacheable method for improved performance
  • Handle errors gracefully with LWC-friendly exceptions

Public Methods

getProductCategoryIdByName

@AuraEnabled(cacheable=true)
public static Id getProductCategoryIdByName(String categoryName)

Purpose: Retrieves the ProductCategory Id for a given category name, with client-side caching enabled for performance optimization.

Parameters: - categoryName (String): The exact Name field value of the ProductCategory to retrieve

Returns: - Id: The Salesforce record ID of the matching ProductCategory, or null if not found

Throws: - AuraHandledException: When user lacks access to ProductCategory object or query fails

Usage Example:

// LWC JavaScript
import getProductCategoryIdByName from '@salesforce/apex/CategoryController.getProductCategoryIdByName';

getCategoryId() {
    getProductCategoryIdByName({ categoryName: 'Memberships' })
        .then(categoryId => {
            this.categoryId = categoryId;
        })
        .catch(error => {
            console.error('Category lookup failed:', error);
        });
}

Business Logic: Validates user has read access to ProductCategory object, queries for first matching category by exact name match, returns category ID or null if not found. Uses LIMIT 1 which may return non-deterministic results if duplicate category names exist.


Private/Helper Methods

FORCE_ERROR

Purpose: Test-only flag to simulate exceptions for unit testing Called By: Test classes only (via @TestVisible annotation)


Dependencies

Apex Classes

  • None (standalone utility)

Salesforce Objects

  • ProductCategory: Standard Commerce Cloud object for category management (Fields: Id, Name)

Custom Settings/Metadata

  • None

External Services

  • None

Design Patterns

  • Aura-Enabled Controller: Standard LWC backend service pattern
  • Cacheable Query: Leverages Salesforce client-side caching for performance
  • Test Seam Injection: @TestVisible flag for exception simulation in tests

Governor Limits Considerations

SOQL Queries: 1 query per method invocation DML Operations: None CPU Time: Minimal - simple query execution Heap Size: Minimal - single ID return value

Bulkification: Not applicable - designed for single category lookup Async Processing: None - synchronous execution only

Error Handling

Strategy: Try-catch with AuraHandledException wrapping Logging: No explicit logging - errors propagated to LWC User Notifications: Error messages displayed via LWC error handling

Security Considerations

Sharing Rules: Bypassed via "without sharing" - all categories visible to all users Field-Level Security: Object-level security checked via Schema.sObjectType.ProductCategory.isAccessible() CRUD Permissions: Read-only query, no DML operations Input Validation: No validation of categoryName parameter (accepts any string)

Test Class

Test Class: CategoryControllerTest.cls (to be created) Coverage: [To be verified] Test Scenarios Covered: - Successful category ID retrieval by name - Category not found returns null - FLS violation throws AuraHandledException - Duplicate category names (non-deterministic LIMIT 1 behavior)

Changes & History

  • Initial Implementation: CategoryController created for LWC category lookups
  • 2025-10-22: Documentation updated to template format

⚠️ Pre-Go-Live Concerns

CRITICAL - Fix Before Go-Live

  • WITHOUT SHARING Declaration: Verify all ProductCategories should be universally accessible regardless of user permissions. Consider security implications for restricted or internal categories.

HIGH - Address Soon After Go-Live

  • No Duplicate Name Handling: Multiple categories with same name return non-deterministic results. Consider adding unique constraint on ProductCategory.Name per Catalog or implementing duplicate detection.
  • QueryException Exposure: Line 19 exposes internal error messages to frontend, potentially leaking database schema information.

MEDIUM - Future Enhancement

  • No Record Not Found Exception: Method returns null for missing categories instead of throwing exception. Frontend must handle null returns.
  • No Input Validation: categoryName parameter not validated (no null/blank checks)
  • No Bulk Lookup Method: Cannot batch multiple category name lookups in single call

LOW - Monitor

  • Test Flag in Production Code: FORCE_ERROR flag exists in production class - consider extracting to test utility
  • No Cache Versioning: Cacheable=true has no namespace or versioning strategy

Maintenance Notes

Complexity: Low Recommended Review Schedule: Annually Key Maintainer Notes: - This is a lightweight utility for LWC components - changes should be rare - WITHOUT SHARING means all users see all categories - verify this aligns with business security requirements - LIMIT 1 may return wrong category if duplicate names exist - enforce uniqueness at database level - Cacheable=true improves performance but may cause stale data if categories are frequently renamed - Consider adding bulk method if multiple category lookups are needed simultaneously - Frontend components must handle null returns when category name doesn't exist