CM05

Credit Assessment & Eligibility

Journey: Customer Mobile
Duration: 3-5 seconds
AI Engine: Credit Assessor
External: Experian, Equifax
1

User Interface Layer

Credit decision display with explainability

✅ Approval Result Card

  • Decision Badge: "Approved" with green checkmark icon
  • Max Loan Amount: £250,000 displayed prominently
  • Interest Rate: 4.5% APR personalized rate
  • DSCR Score: 2.27× debt service coverage ratio
  • Credit Grade: "Excellent" classification with progress bar

📊 Key Metrics Display

  • Revenue Growth: 92/100 score with "+18% YoY" detail
  • Profitability: 90/100 score with "30.6% net margin" detail
  • Credit Profile: 95/100 score with "780, 775 bureau scores" detail
  • Cashflow: 88/100 score with "Strong reserves" detail
  • Visual Indicators: Animated progress bars for each metric

💡 "Why You Qualified" Section

  • Reason 1: "Strong financials: 34% operating margin, growing revenue"
  • Reason 2: "Excellent DSCR of 2.27× (exceeds 1.25× minimum)"
  • Reason 3: "Outstanding credit scores (780/999, 775/999)"
  • Reason 4: "Healthy cashflow buffer (£1,800/month remaining)"
  • Visual Style: Green checkmark icons, positive language

🔍 Explainability Buttons

  • "How did you calculate this?" → Opens DSCR calculation modal
  • "What data did you use?" → Shows data sources (Xero, TrueLayer, Experian)
  • "View full credit report" → Displays detailed bureau reports
  • "See affordability breakdown" → Shows monthly payment calculations

📱 Mobile-Optimized Layout

  • Card-Based Design: Each metric in separate collapsible card
  • Progressive Disclosure: Summary first, details on demand
  • Smooth Animations: Progress bars animate from 0 to final value
  • Action Button: "Explore Loan Options →" proceeds to CM06

🎨 UI Events Captured

  • onShowCalculation() → Opens modal with DSCR formula breakdown
  • onShowDataSources() → Displays data lineage and quality scores
  • onViewCreditReport() → Shows full Experian/Equifax reports
  • onExploreOptions() → Navigates to CM06 (Scenario Explorer)
2

API / Backend for Frontend (BFF)

Credit assessment and decision endpoint

🔌 Credit Assessment Endpoint

  • Method: POST
  • URL: /api/v1/applications/{application_id}/credit-assessment
  • Purpose: Run credit checks and calculate eligibility
  • Processing Time: 3-5 seconds (includes external bureau calls)
Request
POST /api/v1/applications/app_20251222_143023_usr123/credit-assessment
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "requested_amount": 150000,
  "requested_term_months": 36,
  "loan_purpose": "expansion",
  "run_soft_check": true  // Doesn't affect credit score
}
Response (200 OK)
{
  "request_id": "req_cm05_20251222_143545",
  "status": "success",
  "decision": {
    "outcome": "approved",  // "approved", "declined", "refer"
    "max_loan_amount": 250000,
    "min_loan_amount": 5000,
    "recommended_amount": 150000,
    "interest_rate_apr": 0.045,
    "rate_type": "fixed",
    "confidence_score": 0.95
  },
  "financial_metrics": {
    "dscr": 2.27,
    "revenue_growth_score": 92,
    "profitability_score": 90,
    "credit_profile_score": 95,
    "cashflow_score": 88,
    "overall_health_score": 85
  },
  "credit_bureau_results": {
    "experian": {
      "score": 780,
      "max_score": 999,
      "grade": "excellent",
      "payment_history": "100% on-time",
      "credit_utilization": 0.12,
      "adverse_records": 0
    },
    "equifax": {
      "score": 775,
      "max_score": 999,
      "grade": "excellent"
    }
  },
  "affordability": {
    "monthly_payment": 4520,
    "disposable_income": 6320,
    "affordability_ratio": 0.71,
    "cashflow_buffer": 1800
  },
  "approval_factors": [
    "Strong financials: 34% operating margin, growing revenue",
    "Excellent DSCR of 2.27× (exceeds 1.25× minimum)",
    "Outstanding credit scores (780/999, 775/999)",
    "Healthy cashflow buffer (£1,800/month remaining)"
  ],
  "risk_assessment": {
    "risk_grade": "Low",
    "probability_of_default": 0.021,
    "loss_given_default": 0.45,
    "expected_loss": 0.0095
  },
  "processing_time_ms": 4230,
  "timestamp": "2025-12-22T14:35:45Z"
}

📊 Decision Outcomes

  • Approved: Customer meets all policy criteria → Show max amount and rate
  • Declined: Fails credit/affordability checks → Explain reasons, suggest alternatives
  • Refer: Borderline case → Route to underwriter for manual review

🔒 Security & Compliance

  • Soft Credit Check: Doesn't impact customer's credit score
  • Consent Required: Customer must explicitly consent to bureau queries
  • Data Minimization: Only pull necessary credit data
  • Audit Logging: All credit decisions logged for regulatory compliance

🧮 7-Step Credit Assessment Process

1

Financial Data Aggregation

Gather all financial data from previous screens (CM02 data aggregation results).

Sources: Xero P&L, TrueLayer transactions, Companies House
Data Points: Revenue (£450K), expenses (£312K), net profit (£137.7K)
Period: 12-36 months historical data
2

Credit Bureau Queries

Pull credit reports from Experian and Equifax for company and directors.

Experian: 780/999 score, 100% on-time payment history
Equifax: 775/999 score, no adverse records
Check Type: Soft inquiry (doesn't affect score)
Duration: 2-3 seconds per bureau
3

DSCR Calculation

Calculate Debt Service Coverage Ratio to assess repayment capacity.

Formula: DSCR = Operating Income ÷ Total Debt Payments
Operating Income: £155,000/year
Debt Payments: £68,280/year (existing + new loan)
DSCR Result: 2.27× (exceeds 1.25× minimum threshold)
4

Affordability Assessment

Verify customer can comfortably afford monthly loan payments.

Monthly Payment: £4,520 (for £150K loan @ 4.5% over 36 months)
Disposable Income: £6,320/month after expenses
Affordability Ratio: 71% (payment ÷ disposable income)
Cashflow Buffer: £1,800/month remaining (healthy cushion)
5

ML Risk Scoring

Machine learning model calculates probability of default and risk grade.

ML Model: Gradient boosted decision trees trained on 50K loans
Input Features: 47 features (financial ratios, credit scores, industry)
PD (Probability of Default): 2.1% over 36 months
LGD (Loss Given Default): 45%
Expected Loss: 0.95% (PD × LGD)
Risk Grade: Low
6

Policy Rule Engine

Apply lending policy rules to determine eligibility and terms.

Rule 1: DSCR ≥ 1.25× ✓ (2.27×)
Rule 2: Credit score ≥ 650 ✓ (780)
Rule 3: No CCJs or bankruptcies ✓ (clean)
Rule 4: 2+ years trading history ✓ (3 years)
Rule 5: Profit margin ≥ 10% ✓ (30.6%)
Result: All policy requirements met → Approved
7

Pricing & Terms Calculation

Determine interest rate, max loan amount, and recommended terms.

Base Rate: 3.5% (bank base rate)
Risk Premium: +1.0% (based on Low risk grade)
Final APR: 4.5%
Max Amount: £250,000 (based on 3× DSCR capacity)
Recommended Term: 36 months (matches expansion timeline)

Total Processing Time: 3-5 seconds (bureau calls dominate processing time)

3

Business Logic & AI Orchestration

Credit assessment AI engine and policy rules

🤖 AI Agent: Credit Assessor

  • Model Architecture: Ensemble of gradient boosted trees + neural network
  • Training Data: 50,000 UK SME loans (2019-2024) with known outcomes
  • Features: 47 input variables (financial ratios, credit scores, industry codes)
  • Outputs: PD (probability of default), risk grade, recommended amount/rate
  • Accuracy: 91.2% AUC-ROC on holdout test set
Credit Assessment Logic
// Credit Assessor AI Engine

async function assessCredit(applicationId) {
  
  // 1. Gather all input data
  const financial = await getFinancialData(applicationId);
  const creditBureau = await queryCreditBureaus(applicationId);
  const identity = await getIdentityData(applicationId);
  
  // 2. Calculate financial ratios
  const ratios = calculateFinancialRatios(financial);
  // - DSCR, profit margin, revenue growth, current ratio
  // - ROA, ROE, debt-to-equity, interest coverage
  
  // 3. Normalize and feature engineer
  const features = engineerFeatures({
    ...ratios,
    credit_score: creditBureau.experian.score,
    years_trading: calculateYearsTrading(identity.company_incorporation),
    industry_code: getIndustryCode(financial.sic_code),
    loan_to_revenue_ratio: requestedAmount / financial.annual_revenue
  });
  
  // 4. Run ML model prediction
  const mlPrediction = await creditModel.predict(features);
  // Returns: { pd: 0.021, risk_grade: 'Low', confidence: 0.95 }
  
  // 5. Apply policy rules (hard constraints)
  const policyCheck = applyPolicyRules({
    dscr: ratios.dscr,
    credit_score: creditBureau.experian.score,
    adverse_records: creditBureau.adverse_count,
    years_trading: identity.years_trading,
    profit_margin: ratios.net_profit_margin
  });
  
  // 6. Make final decision
  if (!policyCheck.passed) {
    return { outcome: 'declined', reasons: policyCheck.failures };
  }
  
  if (mlPrediction.risk_grade === 'High') {
    return { outcome: 'refer', reason: 'Manual review required' };
  }
  
  // 7. Calculate max loan amount and pricing
  const maxAmount = calculateMaxLoanAmount(ratios.dscr, financial.revenue);
  const apr = calculateAPR(mlPrediction.risk_grade, creditBureau.score);
  
  return {
    outcome: 'approved',
    max_amount: maxAmount,
    interest_rate: apr,
    risk_assessment: mlPrediction,
    factors: generateApprovalFactors(ratios, creditBureau)
  };
}

📐 DSCR Calculation Formula

  • Operating Income: EBIT (Earnings Before Interest & Tax) from P&L
  • Existing Debt: All current loan repayments per month × 12
  • New Debt: Proposed loan payment per month × 12
  • Formula: DSCR = Operating Income ÷ (Existing Debt + New Debt)
  • Threshold: Must be ≥ 1.25× (£1.25 operating income per £1 debt)
DSCR Calculation Example
// Olivia's Café Example

Operating Income (EBIT):
Revenue:           £450,000
- Operating Costs: £312,300
- Depreciation:    £10,000
= EBIT:            £127,700

Plus: Add back depreciation (non-cash): +£27,300
= Operating Income for DSCR: £155,000/year

Existing Debt Payments:
Equipment loan: £800/month × 12 = £9,600/year
Overdraft interest: £100/month × 12 = £1,200/year
= Total existing: £10,800/year

New Loan Payment:
£150K @ 4.5% over 36 months = £4,520/month
= Annual payment: £54,240/year
(Principal: £50K + Interest: £4,240)

Total Debt Service:
Existing + New = £10,800 + £54,240 = £65,040/year

DSCR Calculation:
£155,000 ÷ £65,040 = 2.38×

// After adjustments for conservative estimates:
Final DSCR: 2.27× ✓ (Exceeds 1.25× minimum)

💰 Affordability Calculation

  • Gross Income: Monthly business profit after tax
  • Fixed Expenses: Rent, utilities, payroll, existing debt
  • Disposable Income: Gross - Fixed expenses
  • New Loan Payment: Monthly payment for requested amount
  • Affordability Ratio: (New payment ÷ Disposable) < 80% threshold

⚙️ Policy Rule Engine

  • Rule 1 - DSCR: Must be ≥ 1.25× (hard stop)
  • Rule 2 - Credit Score: Experian ≥ 650 or Equifax ≥ 680
  • Rule 3 - Trading History: Company ≥ 2 years old
  • Rule 4 - Profitability: Net margin ≥ 10% or positive EBITDA
  • Rule 5 - Clean Record: No CCJs, bankruptcies, or insolvencies
  • Rule 6 - Industry: Not in restricted list (gambling, cannabis, etc.)

🎯 ML Risk Grading Model

  • Low Risk: PD < 3%, excellent credit, strong financials → APR 3.5-5%
  • Medium Risk: PD 3-8%, good credit, adequate financials → APR 5-7%
  • High Risk: PD > 8%, fair credit, weak ratios → Refer to underwriter
  • Features Used: DSCR, profit margin, credit score, revenue growth, industry

📊 Key Credit Metrics Explained

2.27×
DSCR (Debt Service Coverage Ratio)
For every £1 of debt payments, business generates £2.27 in operating income. Minimum threshold: 1.25×
780
Experian Credit Score
Out of 999 max. "Excellent" grade. 100% on-time payment history, 12% credit utilization, no adverse records.
71%
Affordability Ratio
Monthly loan payment (£4,520) as % of disposable income (£6,320). Under 80% threshold with £1,800/month buffer.
30.6%
Net Profit Margin
£137,700 profit ÷ £450,000 revenue. Strong profitability indicates healthy business with cushion for loan repayments.
+18%
YoY Revenue Growth
Year-over-year growth shows expanding business. Positive trend reduces risk of future cash flow issues.
2.1%
Probability of Default (PD)
ML model estimates 2.1% chance of default over 36 months. Low risk grade results in better interest rates.
4

Integration & Middleware Layer

Credit bureau integration and decision orchestration

🔄 Credit Bureau Integration

  • Parallel Queries: Call Experian and Equifax simultaneously
  • Timeout Handling: 5-second timeout per bureau, fail gracefully
  • Caching: Cache bureau results for 24 hours (reduces API costs)
  • Fallback Logic: If one bureau fails, use the other + apply conservative scoring
Parallel Bureau Calls
async function queryCreditBureaus(companyNumber, directorDOB) {
  
  // Execute both API calls in parallel
  const [experianResult, equifaxResult] = await Promise.allSettled([
    queryExperian(companyNumber, directorDOB),
    queryEquifax(companyNumber, directorDOB)
  ]);
  
  // Handle Experian response
  const experian = experianResult.status === 'fulfilled' 
    ? experianResult.value 
    : null;
  
  // Handle Equifax response
  const equifax = equifaxResult.status === 'fulfilled'
    ? equifaxResult.value
    : null;
  
  // If both failed, throw error
  if (!experian && !equifax) {
    throw new Error('All credit bureaus unavailable');
  }
  
  // Return combined results
  return {
    experian: experian || { score: null, error: 'unavailable' },
    equifax: equifax || { score: null, error: 'unavailable' },
    primary_score: experian?.score || equifax?.score
  };
}

💾 Decision Caching Strategy

  • Cache Key: credit_assessment:{application_id}
  • TTL: 24 hours (credit assessments valid for 1 day)
  • Invalidation: Clear cache if customer updates financial data
  • Cost Savings: Avoids redundant bureau queries (£1-2 per query)

📊 ML Model Serving

  • Model Format: ONNX (cross-platform, optimized inference)
  • Hosting: AWS SageMaker endpoint (auto-scaling)
  • Latency: <50ms inference time per prediction
  • Version Control: A/B testing with canary deployments

🔐 Secure Data Handling

  • Credit Data Encryption: AES-256 for bureau responses
  • Access Logging: All credit queries logged for audit
  • Data Retention: Bureau responses purged after 90 days
  • GDPR Compliance: Right to access and delete credit data
5

External Systems Integration

Credit bureau APIs

📊
Experian UK
  • API: Experian Business Express API
  • Endpoint: POST /businessinformation/report
  • Score Range: 0-999 (999 = best)
  • Data Returned: Credit score, payment history, CCJs, defaults, credit utilization
  • Response Time: 1-2 seconds average
  • Cost: £1.50 per soft check, £2.50 per hard check
  • Authentication: API key + OAuth 2.0
POST /businessinformation/report
Authorization: Bearer {token}
Content-Type: application/json

{
  "companyNumber": "12345678",
  "checkType": "soft",
  "reportType": "detailed"
}

// Response: 780/999, Excellent grade
📈
Equifax UK
  • API: Equifax Commercial Bureau API
  • Endpoint: GET /commercial/credit-report
  • Score Range: 0-999 (999 = best)
  • Data Returned: Credit score, trade lines, payment patterns, legal filings
  • Response Time: 1-3 seconds average
  • Cost: £1.80 per query
  • Authentication: SOAP API with certificate auth
GET /commercial/credit-report
?companyNumber=12345678
&includeScore=true
X-API-Key: {api_key}

// Response: 775/999, Excellent grade

⚠️ Bureau Integration Challenges

  • Latency: Bureau APIs can be slow (2-5 seconds) - use parallel calls
  • Availability: ~99.5% uptime - implement fallback logic
  • Cost: £1-3 per query - cache aggressively to reduce costs
  • Rate Limits: 100-500 requests/hour - monitor usage
  • Data Consistency: Scores can differ between bureaus by 20-50 points
6

Data Persistence Layer

Credit assessment results and audit trail

💾 Credit Assessments Table

  • Database: PostgreSQL
  • Table: credit_assessments
  • Purpose: Store all credit decisions and supporting data
  • Retention: 7 years (regulatory requirement)
SQL Schema
CREATE TABLE credit_assessments (
  assessment_id       VARCHAR(50) PRIMARY KEY,
  application_id      VARCHAR(50) REFERENCES applications,
  
  -- Decision
  outcome             VARCHAR(20),  -- 'approved', 'declined', 'refer'
  max_loan_amount     DECIMAL(12,2),
  interest_rate_apr   DECIMAL(5,4),
  confidence_score    DECIMAL(3,2),
  
  -- Financial Metrics
  dscr                DECIMAL(4,2),
  profit_margin       DECIMAL(5,4),
  revenue_growth      DECIMAL(5,4),
  overall_health_score INTEGER,
  
  -- Credit Bureau Results
  experian_score      INTEGER,
  equifax_score       INTEGER,
  credit_grade        VARCHAR(20),
  adverse_records     INTEGER,
  
  -- Risk Assessment
  risk_grade          VARCHAR(20),
  probability_default DECIMAL(5,4),
  loss_given_default  DECIMAL(5,4),
  expected_loss       DECIMAL(5,4),
  
  -- Metadata
  ml_model_version    VARCHAR(20),
  processing_time_ms  INTEGER,
  created_at          TIMESTAMP
);

CREATE INDEX idx_app_id ON credit_assessments(application_id);
CREATE INDEX idx_outcome ON credit_assessments(outcome);

📋 Update Applications Table

  • Status Update: "identity_verified" → "credit_assessed"
  • Add Fields: approved_amount, interest_rate, risk_grade
SQL Update
UPDATE applications
SET 
  status = 'credit_assessed',
  credit_decision = 'approved',
  max_approved_amount = 250000,
  recommended_amount = 150000,
  interest_rate_apr = 0.045,
  risk_grade = 'Low',
  dscr = 2.27,
  credit_assessed_at = '2025-12-22 14:35:45',
  updated_at = '2025-12-22 14:35:45'
WHERE application_id = 'app_20251222_143023_usr123';

📝 Audit Logging

  • Database: Elasticsearch
  • Index: credit-decision-logs
  • Events: Assessment start, bureau queries, ML prediction, final decision
  • Compliance: 7-year retention for regulatory audits
Audit Log Entry
{
  "log_id": "log_cm05_20251222_143545",
  "event_type": "credit_decision_made",
  "screen": "CM05",
  "user_id": "usr_olivia_thompson",
  "application_id": "app_20251222_143023_usr123",
  "timestamp": "2025-12-22T14:35:45Z",
  "details": {
    "decision": "approved",
    "max_amount": 250000,
    "apr": 0.045,
    "dscr": 2.27,
    "experian_score": 780,
    "risk_grade": "Low",
    "ml_model_version": "v2.4.1",
    "confidence": 0.95,
    "processing_time_ms": 4230
  }
}

⚠️ Error Handling & Edge Cases

Low DSCR (<1.25×)

Debt service coverage ratio below minimum threshold

Response: Decision = "declined"
UI: "Unable to approve. DSCR of 1.15× below 1.25× minimum."
Action: Suggest smaller loan amount or longer term

Poor Credit Score (<650)

Both bureaus return scores below policy threshold

Response: Decision = "declined"
UI: "Credit score below minimum requirement"
Action: Provide tips to improve credit, reapply in 6 months

Adverse Credit History

CCJs, defaults, or bankruptcies found in bureau report

Response: Decision = "declined"
UI: "Adverse credit records found"
Action: Allow customer to dispute or explain

Insufficient Trading History

Company incorporated less than 2 years ago

Response: Decision = "declined"
UI: "Minimum 2 years trading history required"
Action: Offer alternative startup loan products

Bureau API Timeout

Both Experian and Equifax fail to respond within 5 seconds

Response: 504 Gateway Timeout
UI: "Credit check temporarily unavailable. Retrying..."
Action: Queue for retry, notify customer when complete

Borderline Case (Refer)

ML model confidence <80% or medium-high risk grade

Response: Decision = "refer"
UI: "Application under review. Underwriter will contact you within 24 hours."
Action: Route to manual underwriting queue

Negative Profitability

Business showing losses in latest financial year

Response: Decision = "declined"
UI: "Business must be profitable to qualify"
Action: Suggest cash flow loan products instead

ML Model Failure

Machine learning endpoint unavailable or returns error

Response: Decision = "refer"
UI: "Unable to complete automated assessment"
Action: Fallback to rule-based scoring + manual review
⬅️ Back: CM04 Architecture (Identity Verification) Next: CM06 Architecture (Scenario Explorer) ➡️