๐Ÿ“š ERP Documentation Viewer

Beautiful, colorful documentation for your ERP system

Check Redundant Names Controller Documentation

File: /controllers/checkRedundantNames.php

Purpose: Data quality validation system for checking name uniqueness across all system entities

Last Updated: December 20, 2024

Total Functions: 2

Lines of Code: ~602

---

๐Ÿ“‹ Overview

The Check Redundant Names Controller is a comprehensive data quality validation system that ensures name uniqueness across all system entities. It handles:

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Entity Validation Coverage (40+ Tables)

Entity TypeTable NameValidation FieldSpecial Rules
**Product Categories**productcatproductCatNameHierarchy-aware
**Products**productproductNameCategory-specific
**Assets**assetsassetsNameStandard validation
**Asset Categories**assetscatcattitelStandard validation
**Banks**bankbanknameStandard validation
**Bank Accounts**bankaccountaccountnameStandard validation
**Clients**clientclientnameStandard validation
**Client Codes**clientclientcodeCode validation
**Cost Centers**costcenternameStandard validation
**Expense Types**expensestypeexpensestypenameStandard validation
### Comprehensive Entity List

The system validates names across these entities:

---

๐Ÿ”‘ Key Functions

1. Default Action (empty $do) - Real-Time Validation

Location: Line 343

Purpose: Perform real-time name validation during data entry

Parameters:

$name = $_GET['name'];        // Name to validate
$tablename = $_GET['tablename']; // Entity type
$catid = $_GET['catid'];      // Category ID (for products)

Process Flow:

1. Extract validation parameters from GET request

2. Handle category ID for product-specific validation

3. Call checkName() function with parameters

4. Return validation result (0=unique, 1=duplicate)

Category Handling:

if (!isset($catid) && $catid == '-1') {
    $catid = 0;
}
checkName($name, $tablename, $catid);

---

2. Edit Mode Validation (do=checkNameWithId) - Exclude Current Record

Location: Line 353

Purpose: Validate name uniqueness while excluding the current record being edited

Parameters:

$name = $_GET['name'];     // New name to validate
$id = $_GET['id'];         // Current record ID to exclude
$tablename = $_GET['tablename']; // Entity type

Process Flow:

1. Load Current Record: Get existing name for the record being edited

2. Name Comparison: Check if name actually changed

3. Conditional Validation: Only validate if name changed

4. Category Extraction: For products, extract category from existing data

Entity-Specific Loading:

switch ($tablename) {
    case "productcat":
        $data = $productCatDAO->load($id);
        $oldName = $data->productCatName;
        break;
    case "client":
        $data = $myClientRecord->load($id);
        $oldName = $data->clientname;
        break;
    case "product":
        $data = $productExt->loadEX($id);
        $oldName = $data->productName;
        $catid = $data->productCatId; // Extract category
        break;
    // ... 40+ other cases
}

Change Detection Logic:

if ($name != $oldName) {
    if ($tablename == "product") {
        if (isset($catid) && $catid != 0) {
            checkName($name, $tablename, $catid);
        }
    } else {
        checkName($name, $tablename, 0);
    }
} else {
    echo $flag; // No change, return success
}

---

3. checkName() - Core Validation Logic

Location: Line 537

Purpose: Execute the actual name validation with comprehensive entity support

Function Signature:

function checkName($name, $tablename, $catid)

Validation Process:

1. Parameter Validation: Ensure name and table are provided

2. Entity-Specific Queries: Execute appropriate DAO query for each entity

3. Special Product Logic: Handle category-specific product validation

4. Result Determination: Return 0 (unique) or 1 (duplicate)

Comprehensive Validation Chain:

if (($tablename == "productcat" && (count($productCatDAO->queryByProductCatName($name)) > 0)) || 
    ($tablename == "assets" && (count($myAssetsRecord->queryByAssetsName($name)) > 0)) || 
    ($tablename == "bank" && (count($myBankRecord->queryByBankname($name)) > 0)) ||
    // ... 40+ other entity checks
   ) {
    $flag = '1'; // Duplicate found
} elseif ($tablename == "product") {
    // Special product category validation
    if (isset($catid) && $catid != 0) {
        if (count($productExt->checkForProductNameInOneCategory2($name, $catid)) > 0) {
            $flag = '1';
        } else {
            $flag = '0';
        }
    }
} else {
    $flag = '0'; // Unique name
}

Product Category Validation:

// Products can have same name in different categories
if ($tablename == "product") {
    $catid = $_GET['catid'];
    if (isset($catid) && $catid != 0) {
        if (count($productExt->checkForProductNameInOneCategory2($name, $catid)) > 0) {
            $flag = '1'; // Duplicate in same category
        } else {
            $flag = '0'; // Unique within category
        }
    }
}

---

๐Ÿ”„ Workflows

Workflow 1: Real-Time Name Validation

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: User Enters Name
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1JavaScript Triggers AJAX Request
- User types in name field
- onBlur or onKeyup event triggers
- Extract entity type and name
- Add category ID if applicable
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Controller Receives Validation Request
- Parse GET parameters
- Validate parameter completeness
- Extract name, tablename, catid
- Handle category defaults
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Execute Entity-Specific Validation
- Identify entity type from tablename
- Select appropriate DAO and query method
- Handle special cases (products, client codes)
- Execute database query for duplicates
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Apply Validation Rules
IF tablename == "product":
โ†’ Check category-specific uniqueness
โ”‚ โ””โ”€โ†’ Allow same name in different categories โ”‚
ELSE:
โ†’ Check global uniqueness
โ”‚ โ””โ”€โ†’ No duplicates allowed system-wide โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
5Return Validation Result
- 0 = Name is unique (valid)
- 1 = Name already exists (invalid)
- JavaScript receives response
- Update UI with validation feedback
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

Workflow 2: Edit Mode Validation

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: User Edits Existing Record
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Load Current Record Data
- Extract record ID from request
- Load existing record via appropriate DAO
- Extract current name value
- Extract category if applicable
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Compare Names
IF new name == current name:
โ”‚ โ””โ”€โ†’ Return 0 (no change, valid) โ”‚
ELSE:
โ”‚ โ””โ”€โ†’ Continue to duplicate check โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Execute Validation (Excluding Current Record)
- Run standard validation logic
- Results exclude current record ID
- Apply same entity-specific rules
- Return validation result
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐Ÿงฎ Calculation Methods

Validation Logic Algorithm

function checkName($name, $tablename, $catid) {
    $flag = '0'; // Default: unique
    
    if (isset($name) && $name != "" && isset($tablename) && $tablename != "") {
        // Build comprehensive validation chain
        $isDuplicate = false;
        
        // Check each entity type
        switch ($tablename) {
            case 'productcat':
                $isDuplicate = count($productCatDAO->queryByProductCatName($name)) > 0;
                break;
            case 'client':
                $isDuplicate = count($myClientRecord->queryByClientname($name)) > 0;
                break;
            case 'product':
                // Special category-specific logic
                if (isset($catid) && $catid != 0) {
                    $isDuplicate = count($productExt->checkForProductNameInOneCategory2($name, $catid)) > 0;
                }
                break;
            // ... handle all 40+ entity types
        }
        
        $flag = $isDuplicate ? '1' : '0';
    }
    
    echo $flag;
}

Performance Optimization

// Optimized query pattern for large datasets
function optimizedNameCheck($name, $tablename) {
    // Use indexed queries with LIMIT 1 for existence checks
    $query = "SELECT 1 FROM {$tablename} WHERE name_field = ? LIMIT 1";
    $result = executeQuery($query, [$name]);
    
    return count($result) > 0 ? 1 : 0;
}

---

๐Ÿ”’ Security & Permissions

Input Validation

// Secure parameter handling
$name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING);
$tablename = filter_input(INPUT_GET, 'tablename', FILTER_SANITIZE_STRING);
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);

// Validate table name against whitelist
$allowedTables = [
    'productcat', 'client', 'supplier', 'product', 
    'bank', 'store', 'unit', 'usergroup',
    // ... all valid entity types
];

if (!in_array($tablename, $allowedTables)) {
    die('Invalid table name');
}

SQL Injection Prevention

// DAO-based queries prevent SQL injection
// Example secure query:
$results = $productCatDAO->queryByProductCatName($name);
// This uses parameterized queries internally

Access Control Recommendations

// Add user permission checks
function validateAccess($tablename) {
    $userPermissions = $_SESSION['user_permissions'];
    
    switch ($tablename) {
        case 'client':
            return $userPermissions['manage_clients'] ?? false;
        case 'product':
            return $userPermissions['manage_products'] ?? false;
        // ... other permission checks
    }
    
    return false;
}

---

๐Ÿ“Š Performance Considerations

Database Optimization

1. Required Indexes:

   -- Create indexes on name fields for all validated entities
   CREATE INDEX idx_productcat_name ON productcat(productCatName);
   CREATE INDEX idx_client_name ON client(clientname);
   CREATE INDEX idx_product_name_category ON product(productName, productCatId);
   CREATE INDEX idx_supplier_name ON supplier(suppliername);
   ```

2. **Query Optimization**:
   - Use LIMIT 1 for existence checks
   - Index all name fields used in validation
   - Optimize category-specific product queries

3. **Caching Strategy**:
   ```php
   // Cache validation results for session duration
   if (!isset($_SESSION['name_cache'])) {
       $_SESSION['name_cache'] = [];
   }
   
   $cacheKey = md5($name . $tablename . $catid);
   if (isset($_SESSION['name_cache'][$cacheKey])) {
       echo $_SESSION['name_cache'][$cacheKey];
       return;
   }
   
   $result = checkName($name, $tablename, $catid);
   $_SESSION['name_cache'][$cacheKey] = $result;
   ```

### Memory Management
php

// Efficient processing for batch validations

function batchValidateNames($validationList) {

$results = [];

foreach ($validationList as $validation) {

$result = checkName($validation['name'], $validation['table'], $validation['catid']);

$results[] = $result;

// Clear any large objects

unset($validation);

}

return $results;

}

---

## ๐Ÿ› Common Issues & Troubleshooting

### 1. **False Positive Duplicates**
**Issue**: Validation shows duplicate when name should be allowed  
**Cause**: Category-specific logic not applied correctly

**Debug**:
php

// Add debugging to checkName function

echo "Checking: name=$name, table=$tablename, catid=$catid
";

if ($tablename == "product") {

$duplicates = $productExt->checkForProductNameInOneCategory2($name, $catid);

echo "Found " . count($duplicates) . " duplicates in category $catid
";

}

### 2. **Edit Mode Not Working**
**Issue**: Edit validation fails when name unchanged  
**Cause**: Record loading or name comparison errors

**Debug**:
php

// Debug edit mode validation

echo "Record ID: $id
";

echo "Old name: '$oldName'
";

echo "New name: '$name'
";

echo "Names equal: " . ($name == $oldName ? 'YES' : 'NO') . "
";

### 3. **Performance Issues**
**Issue**: Slow validation responses  
**Cause**: Missing indexes or inefficient queries

**Solution**:
php

// Profile validation queries

$start = microtime(true);

$result = checkName($name, $tablename, $catid);

$duration = microtime(true) - $start;

if ($duration > 0.1) { // Log slow queries

error_log("Slow validation: {$duration}s for $tablename:$name");

}

---

## ๐Ÿงช Testing Scenarios

### Test Case 1: Basic Name Validation

1. Enter new unique name

2. Verify returns 0 (valid)

3. Enter existing name

4. Verify returns 1 (invalid)

5. Test with special characters

6. Verify proper handling

### Test Case 2: Category-Specific Product Validation

1. Create product in category A

2. Try same name in category A (should fail)

3. Try same name in category B (should succeed)

4. Verify category isolation works

### Test Case 3: Edit Mode Validation

1. Edit existing record without changing name

2. Verify validation passes

3. Change to existing name

4. Verify validation fails

5. Change to new unique name

6. Verify validation passes

### JavaScript Integration Test
javascript

// Example client-side validation

function validateEntityName(name, tablename, catid, callback) {

$.ajax({

url: 'checkRedundantNames.php',

data: {

name: name,

tablename: tablename,

catid: catid || 0

},

success: function(response) {

callback(response == '0'); // true if unique

}

});

}

```

---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When new entities are added to the system

โ†‘