Portal Community

Enterprise Shorthand Strategy

Enterprise shorthand strategies solve several challenges in large organizations:

Real-World Example: Walmart Ecosystem

Walmart operates a global ecosystem of workflows that access store data, customer information, inventory, and regional systems. To enforce consistency, Walmart defined company-wide shorthands:

Walmart Shorthand Strategy

Company Prefix: $$walmart (double $ indicates corporate data)

Purpose: Unified access to Walmart-specific data sources with standardized naming

Philosophy: Workflow designers see a clean, company-branded interface without needing to know internal storage mechanisms

Walmart Shorthands: Complete Reference

Store Data Access

$$walmart.storeId — Current store identifier (from context)
$$walmart.storeName — Human-readable store name
$$walmart.storeRegion — Regional assignment (e.g., "Northeast", "Southwest")
$$walmart.storeManager — Store manager contact information
$$walmart.storeOperatingHours — Store hours and schedule

Customer Data Access

$$walmart.customerId — Current customer identifier
$$walmart.customerTier — Loyalty tier (e.g., "standard", "plus", "premium")
$$walmart.customerRegion — Customer's region code
$$walmart.customerPref — Customer preferences and settings

Regional Operations

$$walmart.regionCode — Region code (NY, CA, TX, etc.)
$$walmart.regionManager — Regional operations contact
$$walmart.regionConfig — Region-specific configuration

Inventory Management

$$walmart.inventory.sku — Stock keeping unit in inventory
$$walmart.inventory.quantity — Quantity on hand
$$walmart.inventory.location — Warehouse location

Implementation: Walmart Shorthand

Step 1: Define the Shorthand Class

using BizFirst.Ai.ProcessEngine.JS.Directives;

/// <summary>
/// Walmart enterprise shorthand: $$walmart
/// Maps company-specific data references to internal storage
///
/// Example: @{$$walmart.customerId}
/// Expands to: @{memory:wmt_context.customerId}
///
/// This allows Walmart workflows to reference data using company-standard prefixes
/// without exposing internal storage structure.
/// </summary>
public class WalmartShorthandDefinition : IShorthandDefinition
{
    public string Prefix => "$$walmart";

    public string Expand(string shorthandPath)
    {
        // Validate path to prevent injection
        if (!IsValidPath(shorthandPath))
            throw new ArgumentException($"Invalid shorthand path: {shorthandPath}");

        // Map company paths to internal memory locations
        var mappedPath = MapWalmartPath(shorthandPath);
        return $"@{{memory:{mappedPath}}}";
    }

    private string MapWalmartPath(string path)
    {
        // Examples:
        // "customerId" → "wmt_context.customer.id"
        // "storeId" → "wmt_context.store.id"
        // "regionCode" → "wmt_context.region.code"

        return path switch
        {
            "customerId" => "wmt_context.customer.id",
            "customerTier" => "wmt_context.customer.tier",
            "customerRegion" => "wmt_context.customer.region",
            "storeId" => "wmt_context.store.id",
            "storeName" => "wmt_context.store.name",
            "storeRegion" => "wmt_context.store.region",
            "storeManager" => "wmt_context.store.manager",
            "regionCode" => "wmt_context.region.code",
            "regionManager" => "wmt_context.region.manager",
            "regionConfig" => "wmt_context.region.config",
            "inventory.sku" => "wmt_context.inventory.sku",
            "inventory.quantity" => "wmt_context.inventory.qty",
            "inventory.location" => "wmt_context.inventory.loc",
            _ => throw new ArgumentException($"Unknown Walmart path: {path}")
        };
    }

    private bool IsValidPath(string path)
    {
        // Prevent injection attacks
        if (string.IsNullOrWhiteSpace(path)) return false;
        if (path.Contains("..")) return false;
        if (path.Contains("}")) return false;
        return true;
    }
}

Step 2: Register in Walmart Services

// In Startup.cs or Program.cs for Walmart deployment
public void ConfigureServices(IServiceCollection services)
{
    // ... other configurations ...

    // Register Walmart enterprise shorthands
    services.AddSingleton<IShorthandDefinition>(
        new WalmartShorthandDefinition()
    );

    // Register standard shorthands as fallback
    services.AddSingleton<IShorthandDefinition>(
        new ConfigShorthandDefinition()
    );
    services.AddSingleton<IShorthandDefinition>(
        new UserShorthandDefinition()
    );

    // Continue with other service registrations
}

Step 3: Initialize Walmart Context

Before workflow execution, populate the Walmart context in execution memory:

// During execution initialization
public async Task InitializeWalmartContext(ExecutionMemory memory, ExecutionRequest request)
{
    // Load store information from context
    var storeData = new
    {
        id = request.StoreId,
        name = await _storeService.GetStoreName(request.StoreId),
        region = await _storeService.GetStoreRegion(request.StoreId),
        manager = await _storeService.GetStoreManager(request.StoreId)
    };

    // Load customer information
    var customerData = new
    {
        id = request.CustomerId,
        tier = await _customerService.GetTier(request.CustomerId),
        region = await _customerService.GetRegion(request.CustomerId)
    };

    // Load regional configuration
    var regionData = new
    {
        code = storeData.region,
        manager = await _regionService.GetManager(storeData.region),
        config = await _regionService.GetConfig(storeData.region)
    };

    // Build unified context object
    var walmartContext = new
    {
        customer = customerData,
        store = storeData,
        region = regionData
    };

    // Store in memory with "wmt_context" key
    memory.Set("wmt_context", walmartContext);
}

Workflow Usage Examples

Example 1: Store-Based Processing

// In a Walmart workflow node configuration
Store Processing

Node: Get Store Details
  Input: None
  Config:
    Store ID: @{$$walmart.storeId}
    Store Name: @{$$walmart.storeName}
    Manager Contact: @{$$walmart.storeManager}
    Region: @{$$walmart.storeRegion}

Example 2: Customer Tier-Based Logic

// In a conditional node
If Condition:
  @{js:
    @{$$walmart.customerTier} === 'premium'
    ? 'Apply premium benefits'
    : 'Apply standard benefits'
  }

Example 3: Regional Inventory Check

// In a loop over inventory items
For Each Item in Inventory:
  Item: @{$output:inventory-lookup-1.items}

  Field Mappings:
    SKU: @{$memory:item.sku}
    Quantity: @{$memory:item.quantity}
    Store: @{$$walmart.storeId}
    Region: @{$$walmart.regionCode}
    Warehouse: @{$memory:item.location}

Configuration Patterns

Single-Prefix Strategy (Walmart Model)

All company data accessed through a single branded prefix:

$$walmart.*  — All Walmart-specific data
$output      — Still available for non-Walmart data
$input       — Still available for node inputs
$var         — Still available for workflow variables

Mixed-Prefix Strategy

Multiple prefixes for different data categories:

$$walmart        — Core Walmart data
$$wmt.inventory  — Inventory-specific (sub-category)
$$wmt.customer   — Customer-specific (sub-category)
$$wmt.store      — Store-specific (sub-category)

Hierarchical Strategy

Nested prefixes for complex hierarchies:

$$walmart.store.id
$$walmart.store.region
$$walmart.customer.tier
$$walmart.customer.preferences
$$walmart.region.manager

Team Documentation Template

Every enterprise using custom shorthands should document them for their teams:

# Walmart Shorthand Reference
## For Workflow Designers

### Available Shorthands

| Shorthand | Resolves To | Example | Notes |
|-----------|-------------|---------|-------|
| $$walmart.customerId | Customer ID in current context | Customer: @{$$walmart.customerId} | Set from request context |
| $$walmart.customerTier | Customer loyalty tier | @{$$walmart.customerTier} | Tier codes: standard, plus, premium |
| $$walmart.storeId | Store/location ID | Store: @{$$walmart.storeId} | Format: 5-digit code (e.g., "10245") |
| $$walmart.storeRegion | Geographic region code | Region: @{$$walmart.storeRegion} | Values: NY, CA, TX, SE, etc. |
| $$walmart.regionManager | Regional operations contact | Contact: @{$$walmart.regionManager} | Email format: manager@walmart.com |

## Usage Examples

### Get Customer Tier
@{$$walmart.customerTier}

### Store-Region Processing
Workflow should process store @{$$walmart.storeId} in region @{$$walmart.storeRegion}

### Conditional Logic
@{js: @{$$walmart.customerTier} === 'premium' ? 'Fast track' : 'Standard'}

## Do's and Don'ts

DO:
- Use $$walmart prefixes for all company data
- Reference context through shorthands (don't hardcode paths)
- Test with various store/customer combinations

DON'T:
- Mix $$walmart references with internal memory paths
- Hardcode storeId or customerId (use shorthand)
- Assume data is always present (use null-safe checks)

Security and Access Control

Enterprise shorthands can enforce security policies:

Principle: Only expose data through shorthands that have been approved for workflow use
public class SecureWalmartShorthandDefinition : IShorthandDefinition
{
    private readonly IAccessControl _accessControl;

    public string Prefix => "$$walmart";

    public string Expand(string shorthandPath)
    {
        // Check if the requesting workflow has access to this path
        if (!_accessControl.IsPathAccessible(shorthandPath))
        {
            throw new UnauthorizedAccessException(
                $"Access denied to Walmart path: {shorthandPath}"
            );
        }

        return $"@{{memory:wmt_context.{shorthandPath}}}";
    }
}

// Example access control
public class WalmartAccessControl : IAccessControl
{
    public bool IsPathAccessible(string path)
    {
        // Customer tier is available to all workflows
        if (path.StartsWith("customer.")) return true;

        // Store-level data requires store manager role
        if (path.StartsWith("store.") && !HasRole("store_manager"))
            return false;

        // Regional data requires regional manager role
        if (path.StartsWith("region.") && !HasRole("regional_manager"))
            return false;

        // Inventory requires inventory access
        if (path.StartsWith("inventory.") && !HasAccess("inventory"))
            return false;

        return false; // Deny by default
    }
}

Runtime Changes Without Code

For maximum flexibility, implement dynamic shorthand registration:

public class DynamicShorthandRegistry
{
    private readonly Dictionary<string, Func<string, string>> _expansions;

    public void RegisterShorthand(string prefix, Func<string, string> expansion)
    {
        _expansions[prefix] = expansion;
    }

    public string ExpandIfRegistered(string prefix, string path)
    {
        if (_expansions.TryGetValue(prefix, out var expander))
            return expander(path);
        return null; // Not registered
    }
}

// Load shorthand definitions from configuration file
public void LoadFromConfig(IConfiguration config)
{
    var shorthandConfigs = config.GetSection("Shorthands").GetChildren();
    foreach (var shConfig in shorthandConfigs)
    {
        var prefix = shConfig["prefix"];
        var templatePattern = shConfig["expansion"];

        // Register dynamic expansion
        Registry.RegisterShorthand(prefix, path =>
        {
            return templatePattern.Replace("{path}", path);
        });
    }
}

Configuration Example (appsettings.json):

{
  "Shorthands": [
    {
      "prefix": "$$walmart",
      "expansion": "@{memory:wmt_context.{path}}"
    },
    {
      "prefix": "$config",
      "expansion": "@{memory:config.{path}}"
    },
    {
      "prefix": "@api",
      "expansion": "@{output:{path} | parseJson}"
    }
  ]
}
Best Practice: Documentation First Before implementing enterprise shorthands, document them thoroughly. Workflow designers need to understand: - What each shorthand means - When to use it - What values are available - How it resolves internally
Avoid Over-Engineering Enterprise shorthands should simplify workflows, not complicate them. If your shorthand strategy requires extensive documentation or configuration, it may be too complex.