Skip to main content

LoadEntitiesCommand

Overview​

The LoadEntitiesCommand is a secure, enterprise-grade data query command that allows you to load and filter data from approved entities (database tables) within your BankLingo workflows. This command provides flexible querying capabilities while maintaining strict security controls to prevent SQL injection attacks and unauthorized access to sensitive data.

Security First

This command implements multiple layers of security validation including:

  • βœ… Whitelisted entities only - Only pre-approved tables can be queried
  • βœ… Sensitive field blocking - Password, PINs, and security keys are automatically filtered
  • βœ… SQL injection protection - Dangerous SQL keywords are blocked
  • βœ… Input validation - All parameters are validated before query execution

When to Use This Command​

βœ… Good Use Cases:​

  • Workflow data loading: Load customer, branch, or transaction data during process execution
  • Dynamic lookups: Fetch related entities based on workflow context
  • List population: Get dropdown options or reference data for user tasks
  • Data validation: Check if records exist before performing operations
  • Filtered queries: Retrieve specific records based on business logic

β”Œ Bad Use Cases:​

  • Complex reporting (use dedicated reporting tools instead)
  • Data modifications (use specific update commands instead)
  • Joining multiple tables (design specific commands for complex queries)
  • Retrieving sensitive authentication data (automatically blocked)

Available Entities (Whitelist)​

Only the following entities are available for querying. Attempting to query unlisted entities will result in an error.

Need Field Details?

πŸ“‹ See the complete field reference guide with all available fields, data types, and examples:
→’ LoadEntitiesCommand Field Reference

Self-Service Entities (18)​

Entity NameDescription
UserRepoSelf-service users
TransactionRepoUser transactions
BankRepoBank information
BranchRepoBranch information
AreaRepoGeographic areas
DivisionRepoOrganizational divisions
OrganisationRepoOrganizations
PlanTypeRepoPlan types
UserBeneficiaryRepoUser beneficiaries
LoanQuoteRepoLoan quotes/applications
UserDetailRepoUser personal details (names, etc.)
GuaratorInformationRepoGuarantor information
NextOfKinInformationRepoNext of kin details
EmploymentInformationRepoEmployment records
SelfServiceIdentityInformationRepoIdentity documents
SelfServiceAddressInformationRepoAddress records
SelfServiceDisbursementInformationRepoDisbursement details
SelfServiceLoanCollectionInformationRepoCollection account info

Core Banking Entities (11)​

Entity NameDescription
ClientRepoBank clients/customers
LoanAccountRepoLoan accounts
DepositAccountRepoDeposit accounts
DepositTransactionRepoDeposit transactions
LoanTransactionRepoLoan transactions
CBSTransactionRepoCore banking transactions
BranchCoreRepoCore banking branches
DepositProductRepoDeposit product definitions
LoanProductRepoLoan product definitions
JournalEntryRepoJournal entries
GLAccountRepoGeneral Ledger accounts

Total Entities: 29 (18 Self-Service + 11 Core Banking)

v2.2 Update (Jan 2026)

✨ 9 New Self-Service Entities Added: LoanQuote, UserDetail, Guarantor Information, Next of Kin, Employment Information, Identity Information, Address Information, Disbursement Information, and Collection Information - now available for querying loan application data!

Adding New Entities

To add a new entity, contact your system administrator. Entities must be explicitly whitelisted in RepoTableMapping for security reasons.


Blocked Sensitive Fields​

The following fields are automatically blocked and cannot be queried, even if explicitly requested. This protects sensitive user data from unauthorized access.

πŸ”’ Password & Authentication​

  • Password, PasswordHash, PasswordSalt, HashedPassword, UserPassword

πŸ”’ Two-Factor Authentication​

  • TwoFASecretKey, TwoFASecret, AuthenticatorSecret, Authentication2FARequestId, OTPSecret

πŸ”’ Security Questions & Answers​

  • SecurityAnswer1, SecurityAnswer2, SecurityAnswer3
  • SecurityQuestion1, SecurityQuestion2, SecurityQuestion3

πŸ”’ API Keys & Tokens​

  • ApiKey, ApiSecret, AccessToken, RefreshToken, BearerToken, SecretKey, PrivateKey

πŸ”’ PINs & Biometrics​

  • PIN, TransactionPIN, ATMPin, CardPIN
  • Fingerprint, FingerprintData, BiometricData, FaceData

πŸ”’ Financial Secrets​

  • CVV, CardCVV, CardSecurityCode, AccountPIN

πŸ”’ Session & Encryption​

  • SessionSecret, SessionKey, EncryptionKey

πŸ”’ Personal IDs​

  • SSN, SocialSecurityNumber, TaxId, NationalId
Attempting to Access Blocked Fields

If you request blocked fields:

  • Single field: The field is silently excluded from results
  • Multiple fields: Other safe fields are returned, blocked fields are filtered
  • All blocked fields: Request fails with HTTP 403 Forbidden

Parameters​

ParameterTypeRequiredDefaultDescription
entitystringβœ… Yes-The entity (repository) name to query. Must be from the whitelist.
fieldsstringNo"*"Comma-separated list of fields to return. Use "*" for all fields (sensitive fields still excluded). When using JOINs, use full repo names (e.g., LoanQuoteRepo.Id, UserRepo.EmailAddress).
filterstringNonullSQL WHERE clause (without "WHERE" keyword). Must not contain dangerous SQL keywords. Use full repo names in filter expressions (e.g., LoanQuoteRepo.ApprovalState = 1).
orderarray<string>No[]Array of field names to sort by (ascending order).
pagenumberNonullPage number for pagination (1-based). Requires size parameter.
sizenumberNonullNumber of records per page. Maximum: 1000. Requires page parameter.
πŸ”’ Security: Use Full Repo Names

When referencing fields (especially with JOINs), always use the full repository name as documented:

  • βœ… Correct: LoanQuoteRepo.Id, UserRepo.EmailAddress, ClientRepo.FirstName
  • ❌ Wrong: Using any shortened notation or alternative formats

Always match the repository names exactly as they appear in the entity list above. The system handles all internal processing securely.


Response Format​

Success Response​

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 25,
"Size": 10,
"Pages": 3,
"Data": [
{
"Id": 1,
"UserId": "user@example.com",
"EmailAddress": "user@example.com",
"UserStatus": 1,
"DefaultBranchId": 5
},
// ... more records
]
}

Error Response​

{
"IsSuccessful": false,
"Message": "Entity 'InvalidRepo' is not available for querying. Please use one of the allowed entities.",
"StatusCode": "400"
}

Response Fields​

FieldTypeDescription
IsSuccessfulbooleantrue if query succeeded, false otherwise
MessagestringSuccess message or error description
StatusCodestringHTTP status code: "200" (success), "400" (bad request), "403" (forbidden), "500" (server error)
CountnumberNumber of records returned in current page
SizenumberRequested page size
PagesnumberTotal number of pages (if pagination is used)
DataarrayArray of records (each record is an object with field-value pairs)

Examples​

Example 1: Load All Users (Basic Query)​

Use Case: Get all self-service users for a dropdown list.

Request:

{
"entity": "UserRepo"
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 150,
"Size": 0,
"Pages": 1,
"Data": [
{
"Id": 1,
"UserId": "john.doe@example.com",
"EmailAddress": "john.doe@example.com",
"UserStatus": 1,
"DefaultBranchId": 3,
"UserClassification": 1,
"AccountType": 2
},
// ... more users
]
}

Example 2: Load Specific Fields Only​

Use Case: Get only user ID and email for performance reasons.

Request:

{
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress"
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 150,
"Data": [
{
"Id": 1,
"UserId": "john.doe@example.com",
"EmailAddress": "john.doe@example.com"
},
{
"Id": 2,
"UserId": "jane.smith@example.com",
"EmailAddress": "jane.smith@example.com"
}
]
}

Example 3: Filter Users by Status​

Use Case: Get only active users (UserStatus = 1).

Request:

{
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress, UserStatus",
"filter": "UserStatus = 1"
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 120,
"Data": [
{
"Id": 1,
"UserId": "john.doe@example.com",
"EmailAddress": "john.doe@example.com",
"UserStatus": 1
},
// ... only active users
]
}

Example 4: Filter with Multiple Conditions​

Use Case: Get active profile admins from a specific branch.

Request:

{
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress, IsProfileAdmin, DefaultBranchId",
"filter": "UserStatus = 1 AND IsProfileAdmin = 1 AND DefaultBranchId = 5"
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 3,
"Data": [
{
"Id": 15,
"UserId": "admin1@example.com",
"EmailAddress": "admin1@example.com",
"IsProfileAdmin": true,
"DefaultBranchId": 5
},
{
"Id": 28,
"UserId": "admin2@example.com",
"EmailAddress": "admin2@example.com",
"IsProfileAdmin": true,
"DefaultBranchId": 5
}
]
}

Example 5: Sort Results​

Use Case: Get users sorted by email address.

{
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress",
"order": ["EmailAddress"]
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 150,
"Data": [
{
"Id": 45,
"UserId": "alice@example.com",
"EmailAddress": "alice@example.com"
},
{
"Id": 12,
"UserId": "bob@example.com",
"EmailAddress": "bob@example.com"
},
// ... sorted alphabetically
]
}

Example 6: Pagination (Page 1)​

Use Case: Get the first 10 users from a large dataset.

{
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress",
"page": 1,
"size": 10
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 10,
"Size": 10,
"Pages": 15,
"Data": [
{
"Id": 1,
"UserId": "user1@example.com",
"EmailAddress": "user1@example.com"
},
// ... 10 records total
]
}

Example 7: Pagination (Page 2)​

Use Case: Get the next 10 users.

{
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress",
"page": 2,
"size": 10
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 10,
"Size": 10,
"Pages": 15,
"Data": [
{
"Id": 11,
"UserId": "user11@example.com",
"EmailAddress": "user11@example.com"
},
// ... next 10 records
]
}

Example 8: Load Branches for Dropdown​

Use Case: Get all branches with ID and name for a selection dropdown.

{
"entity": "BranchRepo",
"fields": "Id, BranchName, BranchCode",
"filter": "IsActive = 1",
"order": ["BranchName"]
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 25,
"Data": [
{
"Id": 1,
"BranchName": "Head Office",
"BranchCode": "HQ001"
},
{
"Id": 5,
"BranchName": "Downtown Branch",
"BranchCode": "DTN002"
}
]
}

Example 9: Check if User Exists​

Use Case: Validate that a user with a specific email exists before creating a transaction.

{
"entity": "UserRepo",
"fields": "Id, UserId",
"filter": "EmailAddress = 'john.doe@example.com'"
}

Response (User Found):

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 1,
"Data": [
{
"Id": 15,
"UserId": "john.doe@example.com"
}
]
}

Response (User Not Found):

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 0,
"Data": []
}

Example 10: Filter with IN Clause​

Use Case: Get users from specific branches only.

{
"entity": "UserRepo",
"fields": "Id, UserId, DefaultBranchId",
"filter": "DefaultBranchId IN (1, 3, 5)"
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully.",
"StatusCode": "200",
"Count": 45,
"Data": [
{
"Id": 1,
"UserId": "user1@example.com",
"DefaultBranchId": 1
},
{
"Id": 5,
"UserId": "user5@example.com",
"DefaultBranchId": 3
}
]
}

Security Examples​

Example 11: β”Œ Attempting to Query Password (Blocked)​

Request:

{
"entity": "UserRepo",
"fields": "Id, UserId, Password"
}

Response:

{
"IsSuccessful": false,
"Message": "All requested fields are blocked for security reasons: Password",
"StatusCode": "403"
}

Example 12: Òő ï¸ Requesting Sensitive + Safe Fields​

Request:

{
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress, Password, TwoFASecretKey"
}

Response:

{
"IsSuccessful": true,
"Message": "Data loaded successfully. Note: 2 sensitive field(s) were excluded from results for security reasons.",
"StatusCode": "200",
"Count": 150,
"Data": [
{
"Id": 1,
"UserId": "john.doe@example.com",
"EmailAddress": "john.doe@example.com"
// Password and TwoFASecretKey are excluded
}
]
}

Example 13: β”Œ SQL Injection Attempt (Blocked)​

Request:

{
"entity": "UserRepo",
"filter": "Id = 1 OR 1=1; DROP TABLE Users--"
}

Response:

{
"IsSuccessful": false,
"Message": "Filter contains invalid SQL keywords. Please review your filter expression.",
"StatusCode": "400"
}

Example 14: β”Œ Attempting to Query Unmapped Entity (Blocked)​

Request:

{
"entity": "PasswordHistoryRepo"
}

Response:

{
"IsSuccessful": false,
"Message": "Entity 'PasswordHistoryRepo' is not available for querying. Please use one of the allowed entities.",
"StatusCode": "400"
}

Example 15: β”Œ Invalid Filter Characters (Blocked)​

Request:

{
"entity": "UserRepo",
"filter": "Id = 1 -- Comment out rest"
}

Response:

{
"IsSuccessful": false,
"Message": "Filter contains invalid characters (comments or multiple statements).",
"StatusCode": "400"
}

Integration in Workflows​

Use in Service Task​

{
"taskType": "serviceTask",
"taskId": "loadActiveUsers",
"taskName": "Load Active Users",
"commandType": "App.Commands.BPM.Entities.LoadEntitiesCommand",
"parameters": {
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress, DefaultBranchId",
"filter": "UserStatus = 1 AND IsProfileAdmin = 1",
"order": ["EmailAddress"]
}
}

Use Variable Substitution in Filter​

{
"taskType": "serviceTask",
"taskId": "loadUserByEmail",
"taskName": "Load User By Email",
"commandType": "App.Commands.BPM.Entities.LoadEntitiesCommand",
"parameters": {
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress",
"filter": "EmailAddress = '{{userEmail}}'"
}
}

Store Results in Workflow Context​

After execution, access the loaded data in subsequent tasks:

// Check if users were found
if (context.loadActiveUsers.Count > 0) {
// Get first user
var firstUser = context.loadActiveUsers.Data[0];
var userId = firstUser.Id;
var email = firstUser.EmailAddress;
}

Filter Expression Guidelines​

βœ… Allowed Operations:​

  • Comparison: =, !=, <>, <, >, <=, >=
  • Logical: AND, OR, NOT
  • Patterns: LIKE '%value%'
  • Ranges: BETWEEN x AND y
  • Lists: IN (1, 2, 3)
  • Null checks: IS NULL, IS NOT NULL

β”Œ Blocked Operations:​

  • Data modification: DROP, DELETE, INSERT, UPDATE, TRUNCATE, ALTER, CREATE
  • Execution: EXEC, EXECUTE, sp_*, xp_*
  • Joins: UNION, MERGE
  • Permissions: GRANT, REVOKE
  • Comments: --, /*, */
  • Multiple statements: ;

Γ°ΕΈβ€œΒ Filter Best Practices:​

  1. Use single quotes for strings:

    filter: "EmailAddress = 'user@example.com'"
  2. Combine multiple conditions:

    filter: "UserStatus = 1 AND DefaultBranchId IN (1, 3, 5)"
  3. Use wildcards for partial matches:

    filter: "EmailAddress LIKE '%@example.com'"
  4. Check for NULL values:

    filter: "CorporateProfileId IS NOT NULL"
  5. Escape single quotes in values:

    filter: "UserName = 'O''Brien'"

Performance Considerations​

πŸš€ Optimization Tips:​

  1. Request only needed fields:

    • βœ… "fields": "Id, UserId, EmailAddress"
    • β”Œ "fields": "*" (returns all columns)
  2. Use filters to reduce result set:

    • Add WHERE conditions to limit records returned
    • Filter at database level, not in application code
  3. Use pagination for large datasets:

    • Set reasonable size (e.g., 10-50 records per page)
    • Maximum page size is capped at 1000 records
  4. Sort only when necessary:

    • Sorting adds processing overhead
    • Sort in application if already dealing with small datasets
  5. Index your filter fields:

    • Ensure database columns used in filter are indexed
    • Contact DBA for index optimization

Error Handling​

Common Error Codes​

Status CodeMeaningCommon Causes
400Bad RequestInvalid entity name, malformed filter, invalid pagination parameters
403ForbiddenAttempting to access blocked sensitive fields
500Internal Server ErrorDatabase connection issues, malformed SQL, system errors

Error Response Examples​

Invalid Entity:

{
"IsSuccessful": false,
"Message": "Entity 'InvalidRepo' is not available for querying. Please use one of the allowed entities.",
"StatusCode": "400"
}

Invalid Page Size:

{
"IsSuccessful": false,
"Message": "Page size must be greater than 0.",
"StatusCode": "400"
}

Dangerous SQL Keywords:

{
"IsSuccessful": false,
"Message": "Filter contains invalid SQL keywords. Please review your filter expression.",
"StatusCode": "400"
}

Security Architecture​

Threat Protection​

ThreatProtection Mechanism
SQL InjectionKeyword blacklist, character validation, no dynamic table names
Data BreachSensitive field filtering, whitelisted entities only
DoS AttackPagination limits (max 1000 records), query timeout
Privilege EscalationEntity whitelist prevents access to unauthorized tables
Information DisclosurePost-query sanitization removes sensitive fields from results

Logging & Auditing​

The command logs the following events:

EventLog LevelInformation Logged
Command invocationInformationEntity name
Query executionInformationGenerated SQL query
Successful queryInformationRecord count
Blocked field accessWarningRequested field name
SQL injection attemptWarningDangerous filter content
Invalid entityWarningRequested entity name
ErrorsErrorException details

Best Practices​

βœ… DO:​

  • Explicitly list required fields instead of using *
  • Use pagination for large datasets
  • Add filters to reduce result size
  • Validate returned Count before processing Data
  • Handle empty result sets gracefully (Count = 0)
  • Use workflow variables in filters for dynamic queries

β”Œ DON'T:​

  • Request sensitive fields (automatically blocked anyway)
  • Build complex multi-table joins (use dedicated commands)
  • Use wildcards (*) in production workflows
  • Construct SQL injection patterns (will be rejected)
  • Query unmapped entities (not in whitelist)
  • Assume data exists without checking Count

Migration from Legacy Queries​

If you're migrating from direct SQL queries to LoadEntitiesCommand:

Before (Insecure):​

Code Removed

Implementation details removed for security.

Contact support for implementation guidance.

After (Secure):​

{
"entity": "UserRepo",
"fields": "Id, UserId, EmailAddress",
"filter": "EmailAddress = '{{userInput}}'"
}

Troubleshooting​

Issue: "Entity not available for querying"​

Solution: Check that you're using the correct entity name from the whitelist. Entity names are case-insensitive but must match exactly.

Issue: "All requested fields are blocked"​

Solution: You requested only sensitive fields. Request non-sensitive fields like Id, UserId, EmailAddress instead.

Issue: "Filter contains invalid SQL keywords"​

Solution: Remove keywords like DROP, DELETE, EXEC from your filter. Use only comparison and logical operators.

Issue: "Invalid field name format"​

Solution: Field names can only contain alphanumeric characters, dots, underscores, and brackets. Remove special characters.

Issue: Results return fewer fields than expected​

Solution: Some requested fields may have been blocked for security. Check the response Message for warnings about excluded fields.


  • DoSqlQuery: For more complex queries with joins (use with caution)
  • GetFullTableQuery: Alternative querying mechanism
  • Service-specific commands: For entity-specific operations (CreateUser, UpdateBranch, etc.)

Support & Contact​

For questions about:

  • Adding new entities to whitelist: Contact your system administrator
  • Performance issues: Contact your database administrator
  • Security concerns: Contact your security team
  • Integration help: Refer to Process Engine documentation

Changelog​

VersionDateChanges
2.02024-12-26Added comprehensive security validation, field blocking, SQL injection protection
1.02024-01-01Initial release with basic query functionality

Last Updated: December 26, 2024
Command Path: App.Commands.BPM.Entities.LoadEntitiesCommand
Handler: LoadEntitiesCommandHandler