corrad-bp/docs/process-builder/BUSINESS_RULES_TROUBLESHOOTING.md
Md Afiq Iskandar b2692bec73 Enhance Process Builder with Mobile Responsiveness and Node Highlighting
- Implemented mobile responsive states for the process builder, allowing for better usability on smaller screens by auto-hiding panels and providing toggle functionality.
- Added node highlighting capabilities to improve user interaction, enabling users to easily identify and navigate to specific nodes within the process flow.
- Updated the ProcessFlowCanvas component to support centering on highlighted nodes, enhancing the visual experience during node selection.
- Improved overall layout and interaction design for mobile and tablet devices, ensuring a seamless user experience across different screen sizes.
2025-07-08 14:10:50 +08:00

11 KiB

Business Rules Node Troubleshooting Guide

Overview

The Business Rules node allows you to define complex conditional logic in your process flows. This guide addresses common issues with variable dropdowns and operator selection.

Common Issues and Solutions

1. Variable Dropdown Not Populating

Problem: The variable dropdown in business rules conditions shows "Select variable" but no options appear.

Root Causes:

  • Process variables are not properly loaded in the store
  • Variable types are not correctly defined
  • The gatewayAvailableVariables computed property is not updating

Solutions:

A. Check Variable Store State

// In browser console, check if variables are loaded:
console.log('Current process variables:', processStore.currentProcess?.variables);
console.log('Gateway available variables:', gatewayAvailableVariables.value);

B. Ensure Proper Variable Types

Variables must use these specific types that match the VariableBrowser component:

  • string - for text values
  • int - for whole numbers
  • decimal - for decimal numbers
  • boolean - for true/false values
  • date - for date values
  • datetime - for date-time values
  • object - for JSON objects

Incorrect:

{
  "myVariable": {
    "type": "number",  // ❌ Should be "int" or "decimal"
    "value": 123
  }
}

Correct:

{
  "myVariable": {
    "type": "int",     // ✅ Correct type
    "value": 123
  }
}

C. Force Component Re-render

If variables exist but dropdown doesn't update, the issue is with reactivity. The component uses a variablesUpdateKey to force re-renders:

// This key changes when variables are updated
const variablesUpdateKey = computed(() => {
  // Creates hash of variable names to detect changes
  const variableNames = Object.keys(processStore.currentProcess.variables).sort().join(',');
  return `vars-${variableNames.length}-${hash}`;
});

2. Operator Dropdown Not Showing

Problem: After selecting a variable, the operator dropdown remains empty.

Root Cause: The getOperatorsForType() function cannot determine the variable type.

Solution: Ensure the variable has a proper type. The function expects these types:

const getOperatorsForType = (variableType) => {
  switch (variableType?.toLowerCase()) {
    case 'string':
      return [
        { value: 'eq', label: '= (Equal to)' },
        { value: 'neq', label: '≠ (Not equal to)' },
        { value: 'contains', label: 'Contains' },
        { value: 'not_contains', label: 'Does not contain' },
        { value: 'starts_with', label: 'Starts with' },
        { value: 'ends_with', label: 'Ends with' },
        { value: 'is_empty', label: 'Is empty' },
        { value: 'is_not_empty', label: 'Is not empty' }
      ];
    case 'int':
    case 'decimal':
      return [
        { value: 'eq', label: '= (Equal to)' },
        { value: 'neq', label: '≠ (Not equal to)' },
        { value: 'gt', label: '> (Greater than)' },
        { value: 'gte', label: '≥ (Greater than or equal to)' },
        { value: 'lt', label: '< (Less than)' },
        { value: 'lte', label: '≤ (Less than or equal to)' },
        { value: 'between', label: 'Between (inclusive)' }
      ];
    case 'boolean':
      return [
        { value: 'eq', label: '= (Equal to)' },
        { value: 'is_true', label: 'Is True' },
        { value: 'is_false', label: 'Is False' }
      ];
    case 'date':
    case 'datetime':
      return [
        { value: 'eq', label: '= (Equal to)' },
        { value: 'neq', label: '≠ (Not equal to)' },
        { value: 'gt', label: '> (After)' },
        { value: 'gte', label: '≥ (On or after)' },
        { value: 'lt', label: '< (Before)' },
        { value: 'lte', label: '≤ (On or before)' },
        { value: 'between', label: 'Between dates' }
      ];
    default:
      return [
        { value: 'eq', label: '= (Equal to)' },
        { value: 'neq', label: '≠ (Not equal to)' }
      ];
  }
};

3. Variable Browser Component Issues

Problem: VariableBrowser component doesn't show variables even when they exist.

Debugging Steps:

  1. Check Props: Ensure availableVariables prop is passed correctly:
<VariableBrowser
  v-model="condition.variable"
  :availableVariables="props.availableVariables"  <!--  Correct prop passing -->
  :allowCreate="true"
  @change="updateConditionVariable(groupIndex, condIndex)"
/>
  1. Verify Variable Structure: Each variable must have this structure:
{
  name: "variableName",
  type: "string|int|decimal|boolean|date|datetime|object",
  scope: "global|local",
  description: "Variable description",
  currentValue: null // Optional current value for preview
}
  1. Check Grouping Logic: The VariableBrowser groups variables by type:
const groupedVariables = computed(() => {
  const types = {
    string: { label: 'Text Variables', variables: [] },
    int: { label: 'Integer Variables', variables: [] },
    decimal: { label: 'Decimal Variables', variables: [] },
    boolean: { label: 'Boolean Variables', variables: [] },
    date: { label: 'Date Variables', variables: [] },
    datetime: { label: 'DateTime Variables', variables: [] },
    object: { label: 'Object Variables', variables: [] }
  };
  
  // Variables are grouped by type
  variables.forEach(variable => {
    const type = variable.type || 'string';
    if (types[type]) {
      types[type].variables.push(variable);
    }
  });
  
  return Object.values(types).filter(group => group.variables.length > 0);
});

Correct Business Rule Structure

Complete Working Example

{
  "id": "business-rule-123",
  "type": "business-rule",
  "label": "Eligibility Check",
  "position": { "x": 400, "y": 200 },
  "data": {
    "label": "Eligibility Check",
    "description": "Check if applicant meets eligibility criteria",
    "ruleGroups": [
      {
        "id": "group-1",
        "name": "Age and Status Check",
        "operator": "AND",
        "conditions": [
          {
            "id": "condition-1-1",
            "variable": "applicantAge",
            "operator": "greater_than",
            "value": 18
          },
          {
            "id": "condition-1-2",
            "variable": "maritalStatus",
            "operator": "equals",
            "value": "married"
          }
        ],
        "actions": [
          {
            "id": "action-1-1",
            "type": "set_variable",
            "variable": "isEligible",
            "value": true
          }
        ]
      }
    ],
    "outputVariable": "ruleResult",
    "errorVariable": "ruleError"
  }
}

Required Process Variables

{
  "applicantAge": {
    "name": "applicantAge",
    "type": "int",
    "scope": "global",
    "value": 25,
    "description": "Applicant's age in years"
  },
  "maritalStatus": {
    "name": "maritalStatus",
    "type": "string",
    "scope": "global",
    "value": "married",
    "description": "Applicant's marital status"
  },
  "isEligible": {
    "name": "isEligible",
    "type": "boolean",
    "scope": "global",
    "value": null,
    "description": "Whether applicant is eligible"
  },
  "ruleResult": {
    "name": "ruleResult",
    "type": "object",
    "scope": "global",
    "value": null,
    "description": "Business rule execution result"
  },
  "ruleError": {
    "name": "ruleError",
    "type": "object",
    "scope": "global",
    "value": null,
    "description": "Business rule execution error"
  }
}

Debugging Tips

1. Browser Console Debugging

// Check if variables are loaded
console.log('Process variables:', processStore.currentProcess?.variables);

// Check available variables for business rules
console.log('Available variables:', gatewayAvailableVariables.value);

// Check selected node data
console.log('Selected node:', selectedNodeData.value);

// Debug operator dropdown issue
const testVariable = 'selectStatusperkahwinan';
const foundVar = gatewayAvailableVariables.value.find(v => v.name === testVariable);
console.log('Found variable:', foundVar);
console.log('Variable type:', foundVar?.type);

// Test getOperatorsForType function (if available in component)
if (typeof getOperatorsForType === 'function') {
  console.log('Operators for string:', getOperatorsForType('string'));
  console.log('Operators for boolean:', getOperatorsForType('boolean'));
  console.log('Operators for decimal:', getOperatorsForType('decimal'));
}

2. Component Key Debugging

If the component isn't updating, check the key attribute:

<BusinessRuleNodeConfigurationModal
  :key="`business-rule-${selectedNodeData.id}-${variablesUpdateKey}`"
  <!-- This key should change when variables update -->
/>

3. Variable Type Validation

// Validate variable types
const validateVariableTypes = (variables) => {
  const validTypes = ['string', 'int', 'decimal', 'boolean', 'date', 'datetime', 'object'];
  
  Object.values(variables).forEach(variable => {
    if (!validTypes.includes(variable.type)) {
      console.error(`Invalid variable type: ${variable.type} for ${variable.name}`);
    }
  });
};

Best Practices

  1. Always define variable types correctly - Use the exact types expected by the VariableBrowser
  2. Include unique IDs - Each condition and action should have a unique ID
  3. Test incrementally - Add one condition at a time to isolate issues
  4. Use descriptive names - Make variable and rule names clear and meaningful
  5. Check browser console - Most issues will show up in console errors

Operator Values Reference

Use these exact operator values in your JSON definitions:

String Operators

  • eq - Equal to
  • neq - Not equal to
  • contains - Contains substring
  • not_contains - Does not contain substring
  • starts_with - Starts with
  • ends_with - Ends with
  • is_empty - Is empty
  • is_not_empty - Is not empty

Number Operators (int/decimal)

  • eq - Equal to
  • neq - Not equal to
  • gt - Greater than
  • gte - Greater than or equal to
  • lt - Less than
  • lte - Less than or equal to
  • between - Between (inclusive)

Boolean Operators

  • eq - Equal to
  • is_true - Is True
  • is_false - Is False

Date/DateTime Operators

  • eq - Equal to
  • neq - Not equal to
  • gt - After
  • gte - On or after
  • lt - Before
  • lte - On or before
  • between - Between dates

Common Error Messages

Error Cause Solution
"Variable not found" Variable name doesn't match exactly Check spelling and case sensitivity
"No operators available" Variable type not recognized Ensure variable type is one of the supported types
"Dropdown not populating" Variables not loaded or wrong structure Check variable store and structure
"Component not updating" Reactivity issue Check component key and force re-render
"Operator dropdown empty" Using wrong operator values Use correct operator values from reference above

Final Checklist

Before reporting issues, verify:

  • All variables have correct types (string, int, decimal, boolean, date, datetime, object)
  • Process variables are loaded in the store
  • Component receives availableVariables prop
  • Each condition/action has unique ID
  • Browser console shows no errors
  • Variable names match exactly between definition and usage