PreLoanQuoteRequestValidationCommand (Command Chain)
Overview​
cmdBankLingoPreLoanQuoteRequestValidation is the required pre-submission validation chain for CreateSelfServiceLoanRequestCommand.
The chain is executed before the loan quote record is created, so validation failures stop the request before any data is persisted. It receives the full request.Data payload as context, which allows validation to cover every field included by the UI or API client.
This pattern is intentionally aligned with the existing offer-letter chain execution model: the command itself orchestrates the flow, while the configured command chain performs the validation gate.
Why it exists​
The create self-service loan request flow is multi-step and includes several business rules before persistence, including:
- product validation
- required payload checks
- loan amount and tenor checks
- guarantor structure validation
- identity and address completeness checks
- staff referral validation
- duplicate application guard checks
- branch assignment and routing prerequisites
Moving this logic into a dedicated command chain keeps the create command focused on persistence and downstream orchestration, while making the validation reusable and configurable.
Invocation pattern​
The chain is executed from CreateSelfServiceLoanRequestCommand before the system starts creating LoanQuote records.
var validationChain = await _commandService.GetCommandByNameAsync("cmdBankLingoPreLoanQuoteRequestValidation");
if (validationChain == null)
{
return new CommandExecutionResponse
{
IsSuccessful = false,
StatusCode = "CONFIG_MISSING",
Message = "The command chain 'cmdBankLingoPreLoanQuoteRequestValidation' is not configured. Configure it before creating the loan request.",
Data = new { commandName = "cmdBankLingoPreLoanQuoteRequestValidation", context = request.Data }
};
}
var validationResult = await _commandExecutor.ExecuteAsync(
new CommandRequest
{
Cmd = validationChain.Name,
Data = request.Data
},
_tokenContext.CurrentUser,
cancellationToken);
if (!WasCommandExecutionSuccessful(validationResult))
{
return validationResult;
}
Expected payload shape​
The chain expects the full loan request context, passed in request.Data.
{
"productCode": "PAYROLL-01",
"loanAmount": 500000,
"loanPurpose": "Business expansion",
"loanTenor": 12,
"loanTenorType": 2,
"referredByType": 1,
"referralCode": "E59K6H",
"guarantors": [
{
"name": "Jane Doe",
"emailAddress": "jane.doe@example.com",
"mobileNumber": "08012345678",
"relationship": "Spouse",
"address": "12 Lekki Phase 1, Lagos"
}
],
"identityInformation": {
"idNumber": "12345678901",
"idType": 1,
"issueDate": "2020-01-01",
"expiryDate": "2030-01-01",
"base64Doc": "BASE64_STRING",
"docExtension": ".png"
},
"addressInformation": {
"addressLine1": "12 Lekki Phase 1",
"state": "Lagos",
"city": "Lekki",
"country": "Nigeria"
},
"employmentInformation": {
"employmentType": 1,
"employerName": "Example Company",
"salaryAccountNumber": "0123456789",
"salaryBankCode": "058",
"salaryPaymentDay": 25
}
}
Validation responsibilities​
The chain should validate the full context before persistence, including:
- product code lookup and configuration availability
- required fields and supported enum values
- amount ranges and requested tenor rules
- guarantor completeness and contact validation
- identity document requirements
- address and employment information completeness
- staff referral code existence and branch assignment
- duplicate application checks
- branch resolution prerequisites for the selected user or referral flow
- salary account validation using both
salaryBankCodeandsalaryAccountNumberbefore the quote is saved
Success response​
When validation passes, the chain should return a successful response envelope so the create command can continue.
{
"ok": true,
"statusCode": "00",
"message": "Loan quote pre-validation succeeded.",
"outData": {
"validated": true
}
}
Failure response​
When validation fails, the chain should return the normal command execution failure payload and stop the request immediately.
{
"ok": false,
"statusCode": "08",
"message": "Referral code is required when referred by type is Staff",
"outData": {
"validationErrors": [
{
"field": "referralCode",
"message": "Referral code is required when referred by type is Staff"
}
]
}
}
Configuration requirement​
This chain must exist in the configured command-chain registry with the name:
cmdBankLingoPreLoanQuoteRequestValidation
If it is missing, the create command returns a CONFIG_MISSING response and refuses to proceed.
Related commands​
CreateSelfServiceLoanRequestCommandSendLoanOfferCommandInitiateApproveLoanRequestCommand