Skip to content

Loan affordability ​

A personal-loan application decided on affordability: the applicant answers a short flow, four rules check identity, repayments against income, the amount and repeat applications, and borderline files go to an underwriter. Pack: examples/policies/loan-affordability/.

A pattern for expressing a lending & credit policy, not compliance guidance: the thresholds, lists and fields are placeholders chosen to make the example run; a real policy comes from the business's own rules. It calls no app, so it runs in an empty workspace as it is.

The decision it automates ​

Whether to offer the loan, refer it to an underwriter, or decline it, at the moment the application is submitted.

Data expected ​

  • The applicant as a subject (kind user) with identityVerified, the result of your identity check, written by your backend before it starts the run.
  • The flow's answers under submission: amount, purpose, employment, employerName, monthlyIncome and an optional payslip.
  • loan.application events posted through POST /events for each application, so the velocity rule can count them.

Steps and rules ​

StepTypeWhy
collectwait_for_collectionThe loan-application flow; employed applicants are asked for their employer and a payslip.
rulesevaluate_rulesThe loan-affordability rule set under max_severity: a failed block rule declines, a failed warn rule refers.
routebranchrules.outcome == manual_review opens a case.
reviewcreate_caseloan_underwriting, 48-hour SLA.
decideemit_decisionFrom the rules, or the reviewer's decision.

The rule set loan-affordability (useCase: underwriting) uses max_severity: a failed block rule rejects, a failed warn rule sends the run to review, and the weights add up to the score.

RuleTypeSeverity, weightFails when
loan_identity_verifiedcomparisonblock, 100subject.identityVerified is not true
loan_affordabilityexpressionwarn, 40amount / 36 is more than 35% of monthlyIncome
loan_amount_referralscore thresholdwarn, 20amount is above 25 000
loan_repeat_applicationsvelocitywarn, 20more than one loan.application event in 30 days

What a reviewer sees ​

A loan_underwriting case with the application, the optional payslip and each rule's result. The underwriter's decision and note become the decision and its reasons.

How to adapt it ​

Read the term from the flow instead of assuming 36 months, add a call_app step for your credit bureau (an app you build with the SDK) and rules over its answer, and backtest a new affordability limit over past applications before publishing it. A doc-verify-mock step on the payslip shows the asynchronous document path (Individual KYC with documents).

Run it ​

bash
pnpm policy:import examples/policies/loan-affordability --publish

The fixture asks for 12 000 on an income of 900: repayments of 333 a month are above the 315 that 35% allows, so the affordability rule fails, a loan_underwriting case opens, the check approves it and the run completes with a manual approve.

Released under the Apache-2.0 License.