Skip to content

Instantly share code, notes, and snippets.

@Konyuka
Last active November 28, 2025 06:23
Show Gist options
  • Select an option

  • Save Konyuka/a640c3008d34a3ae081ace0500d91d71 to your computer and use it in GitHub Desktop.

Select an option

Save Konyuka/a640c3008d34a3ae081ace0500d91d71 to your computer and use it in GitHub Desktop.
Risk Rating Service - Complete Architecture

Risk Rating Service - Complete Architecture

System Architecture Overview

┌─────────────────────────────────────────────────────────────────────────┐
│                           RISK RATING SERVICE                            │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│                          PRESENTATION LAYER                              │
├─────────────────────────────────────────────────────────────────────────┤
│  API Controllers:                                                        │
│  • RiskRatingController        → Main risk calculation endpoints        │
│  • RiskConfigController        → Configuration management               │
│  • RiskExportController        → Data export & reporting                │
│                                                                          │
│  UI Components:                                                          │
│  • Risk Dashboard Widget       → Summary statistics                     │
│  • Account Risk Profile View   → Detailed risk breakdown                │
│  • Risk History Timeline       → Audit trail                            │
└─────────────────────────────────────────────────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────────────┐
│                          SERVICE LAYER                                   │
├─────────────────────────────────────────────────────────────────────────┤
│  Core Services:                                                          │
│  • RiskRatingService           → Main orchestrator                      │
│  • RiskExportService           → Data export & reporting                │
│                                                                          │
│  Calculators (Strategy Pattern):                                        │
│  • PartyRiskCalculator         → Customer type risk (Sheet 2)           │
│  • CountryRiskCalculator       → Geographic risk (Sheet 5)              │
│  • IndustryRiskCalculator      → Industry/business risk (Sheet 6)       │
│  • ProductRiskCalculator       → Product risk (Sheets 7-14)             │
│  • SecondaryRiskCalculator     → PEP, sanctions, adverse media          │
│                                                                          │
│  Helper Services:                                                        │
│  • RiskClassifier              → Risk class determination               │
│  • RiskRatingHelper            → Utility functions                      │
└─────────────────────────────────────────────────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────────────┐
│                          DATA LAYER                                      │
├─────────────────────────────────────────────────────────────────────────┤
│  Core Models:                                                            │
│  • CustomerRiskProfile         → Main risk rating record                │
│  • ProfileIndicator            → Individual risk indicators             │
│  • RiskAssessmentHistory       → Audit trail                            │
│                                                                          │
│  Configuration Models:                                                   │
│  • RiskCountryClassification   → Country risk matrix (A/B/C/D)          │
│  • RiskIndustry                → Industry risk matrix                   │
│  • RiskProduct                 → Product risk matrix                    │
│  • RiskProductIndustryScore    → Product-industry combinations          │
│                                                                          │
│  Screening Models:                                                       │
│  • PepScreeningResult          → PEP status tracking                    │
│  • AdverseMediaScreening       → Media monitoring                       │
│  • SanctionsScreening          → Sanctions list checks                  │
│  • StrSarReport                → STR/SAR filings                        │
│                                                                          │
│  Supporting Models:                                                      │
│  • CustomerProductHolding      → Product ownership                      │
│  • RelatedPartyRisk            → Beneficiaries, associates              │
└─────────────────────────────────────────────────────────────────────────┘
                                    ↓
┌─────────────────────────────────────────────────────────────────────────┐
│                          INTEGRATION LAYER                               │
├─────────────────────────────────────────────────────────────────────────┤
│  Events & Listeners:                                                     │
│  • RiskRatingCalculated Event  → Triggered on calculation               │
│  • NotifyHighRiskAccount       → AML notifications                      │
│  • LogRiskRatingCalculation    → Audit logging                          │
│                                                                          │
│  Observers:                                                              │
│  • AccountObserver             → Auto-recalculate on changes            │
│                                                                          │
│  Background Jobs:                                                        │
│  • BatchRiskRatingJob          → Bulk calculations                      │
│  • RecalculateRiskRatingJob    → Single recalculation                   │
│                                                                          │
│  Console Commands:                                                       │
│  • ReviewRiskRatings           → Scheduled review checker               │
│                                                                          │
│  Notifications:                                                          │
│  • HighRiskAccountCreated      → New high-risk alerts                   │
│  • RiskReviewDue               → Review reminders                       │
│  • RiskClassChanged            → Risk change alerts                     │
└─────────────────────────────────────────────────────────────────────────┘

Risk Calculation Flow

Account Creation/Update
        ↓
┌───────────────────────────────────────────────────────────────┐
│ 1. RiskRatingService::calculateRiskRating()                   │
└───────────────────────────────────────────────────────────────┘
        ↓
┌───────────────────────────────────────────────────────────────┐
│ 2. PRIMARY RISK CALCULATION (Profile Indicators)             │
├───────────────────────────────────────────────────────────────┤
│   a) PartyRiskCalculator                                      │
│      → Customer Type (Individual/Institutional/Trust)         │
│      → Score: 0-2                                             │
│                                                               │
│   b) CountryRiskCalculator                                    │
│      → Country Classification (A/B/C/D)                       │
│      → Score: 0-5                                             │
│                                                               │
│   c) IndustryRiskCalculator                                   │
│      → Industry Base Score                                    │
│      → Risk Indicators (Import/Export, Cash, etc.)            │
│      → Score: 0-5                                             │
│                                                               │
│   d) ProductRiskCalculator                                    │
│      → Product Base Score                                     │
│      → Contribution Thresholds                                │
│      → Product-Industry Matrix                                │
│      → Score: 0.5-2                                           │
│                                                               │
│   e) Distribution Risk (from PartyRiskCalculator)             │
│      → Face-to-face vs Non-face-to-face                       │
│      → Score: 0-1                                             │
└───────────────────────────────────────────────────────────────┘
        ↓
    Total Primary Score = Sum of all components
        ↓
┌───────────────────────────────────────────────────────────────┐
│ 3. SECONDARY RISK CALCULATION (Risk Indicators)              │
├───────────────────────────────────────────────────────────────┤
│   a) PEP Status Check                                         │
│      → FPEP = Default to High Risk (5)                        │
│      → DPEP + Adverse Media = Default to High Risk            │
│                                                               │
│   b) Customer Conduct                                         │
│      → STR/SAR Reports                                        │
│      → Score: 0-3                                             │
│                                                               │
│   c) Adverse Media                                            │
│      → Financial Crime Related                                │
│      → Score: 0-3                                             │
│                                                               │
│   d) Sanctions Screening                                      │
│      → UNSC/OFAC/EU Lists                                     │
│      → Score: 0 or ESCALATE                                   │
│                                                               │
│   e) Related Parties                                          │
│      → Beneficiaries Risk                                     │
│      → Score: Variable                                        │
└───────────────────────────────────────────────────────────────┘
        ↓
    Total Secondary Score = Sum of indicators
        ↓
┌───────────────────────────────────────────────────────────────┐
│ 4. RISK CLASSIFICATION                                        │
├───────────────────────────────────────────────────────────────┤
│   Total Score = Primary Score + Secondary Score               │
│                                                               │
│   Risk Classes:                                               │
│   • Score 7+      = High Risk (Enhanced DD)                   │
│   • Score 6-6.9   = High Risk (Enhanced DD)                   │
│   • Score 5-5.9   = High Risk (Enhanced DD)                   │
│   • Score 4-4.9   = Medium+ Risk (Enhanced Light DD)          │
│   • Score 3-3.9   = Medium Risk (Standard DD)                 │
│   • Score 2-2.9   = Low Risk (Simplified DD)                  │
│                                                               │
│   Special Rules:                                              │
│   • FPEP → Minimum score 5 (High Risk)                        │
│   • DPEP + Adverse Media → Minimum score 5                    │
│   • Sanctions Hit → ESCALATE to AML Office                    │
└───────────────────────────────────────────────────────────────┘
        ↓
┌───────────────────────────────────────────────────────────────┐
│ 5. SAVE & NOTIFY                                              │
├───────────────────────────────────────────────────────────────┤
│   a) Save CustomerRiskProfile                                 │
│   b) Create ProfileIndicators                                 │
│   c) Log RiskAssessmentHistory                                │
│   d) Fire RiskRatingCalculated Event                          │
│   e) Send Notifications (if High Risk)                        │
│   f) Set Next Review Date                                     │
└───────────────────────────────────────────────────────────────┘

Data Model Relationships

Account (Existing Model)
    ├── hasOne: currentRiskProfile (CustomerRiskProfile)
    ├── hasMany: riskProfiles (CustomerRiskProfile - historical)
    ├── hasMany: productHoldings (CustomerProductHolding)
    ├── hasMany: pepScreenings (PepScreeningResult)
    ├── hasMany: adverseMediaScreenings (AdverseMediaScreening)
    ├── hasMany: sanctionsScreenings (SanctionsScreening)
    └── hasMany: strSarReports (StrSarReport)

CustomerRiskProfile
    ├── belongsTo: account (Account)
    ├── belongsTo: industry (RiskIndustry)
    ├── hasMany: profileIndicators (ProfileIndicator)
    ├── hasMany: relatedParties (RelatedPartyRisk)
    └── hasMany: assessmentHistory (RiskAssessmentHistory)

RiskProduct
    ├── hasMany: productHoldings (CustomerProductHolding)
    └── belongsToMany: industries (RiskIndustry) → through RiskProductIndustryScore

RiskIndustry
    ├── hasMany: customerProfiles (CustomerRiskProfile)
    └── belongsToMany: products (RiskProduct) → through RiskProductIndustryScore

Risk Score Matrix (Quick Reference)

Profile Indicators (Primary Risk)

Component Sheet(s) Min Score Max Score Notes
Party Risk 2 0 2 Customer type
Country Risk 5 0 5 A=0, B=1, C=3, D=5
Distribution Risk 2 0 1 Face-to-face vs remote
Industry Risk 6 0 5 Base + indicators
Product Risk 7-14 0.5 2 Very Low to High
Total Primary 0.5 15

Secondary Indicators (Additional Risk)

Indicator Score Action
FPEP N/A Default total to 5 minimum
DPEP + Adverse Media N/A Default total to 5 minimum
STR/SAR (2+ in 12m) +2 Add to total
STR maintained +3 Add to total
Adverse Media +3 Add to total
Sanctions List N/A ESCALATE - No dealings

Risk Classification

Total Score Risk Class Due Diligence AML Approval Review Period
7.0+ High Enhanced Required 6 months
6.0-6.9 High Enhanced Required 6 months
5.0-5.9 High Enhanced Required 6 months
4.0-4.9 Medium+ Enhanced Light Not Required 12 months
3.0-3.9 Medium Standard Not Required 12 months
2.0-2.9 Low Simplified Not Required 24 months

File Structure

app/
├── Console/
│   └── Commands/
│       └── ReviewRiskRatings.php
├── Events/
│   └── RiskRatingCalculated.php
├── Helpers/
│   └── RiskRatingHelper.php
├── Http/
│   └── Controllers/
│       ├── RiskRatingController.php
│       ├── RiskConfigController.php
│       └── RiskExportController.php
├── Jobs/
│   ├── BatchRiskRatingJob.php
│   └── RecalculateRiskRatingJob.php
├── Listeners/
│   ├── NotifyHighRiskAccount.php
│   └── LogRiskRatingCalculation.php
├── Notifications/
│   ├── HighRiskAccountCreated.php
│   ├── RiskReviewDue.php
│   └── RiskClassChanged.php
├── Observers/
│   └── AccountObserver.php
├── Providers/
│   └── RiskRatingServiceProvider.php
├── RiskRating/                          ← Models namespace
│   ├── AdverseMediaScreening.php
│   ├── CustomerProductHolding.php
│   ├── CustomerRiskProfile.php
│   ├── PepScreeningResult.php
│   ├── ProfileIndicator.php
│   ├── RelatedPartyRisk.php
│   ├── RiskAssessmentHistory.php
│   ├── RiskCountryClassification.php
│   ├── RiskIndustry.php
│   ├── RiskProduct.php
│   ├── RiskProductIndustryScore.php
│   ├── SanctionsScreening.php
│   └── StrSarReport.php
└── Services/
    └── RiskRating/
        ├── Calculators/
        │   ├── CountryRiskCalculator.php
        │   ├── IndustryRiskCalculator.php
        │   ├── PartyRiskCalculator.php
        │   ├── ProductRiskCalculator.php
        │   └── SecondaryRiskCalculator.php
        ├── RiskClassifier.php
        ├── RiskExportService.php
        └── RiskRatingService.php

database/
├── migrations/
│   ├── 2024_01_01_000001_create_customer_risk_profiles_table.php
│   ├── 2024_01_01_000002_create_profile_indicators_table.php
│   ├── 2024_01_01_000003_create_risk_assessment_history_table.php
│   ├── 2024_01_01_000004_create_risk_country_classifications_table.php
│   ├── 2024_01_01_000005_create_risk_industries_table.php
│   ├── 2024_01_01_000006_create_risk_products_table.php
│   ├── 2024_01_01_000007_create_risk_product_industry_scores_table.php
│   ├── 2024_01_01_000008_create_customer_product_holdings_table.php
│   ├── 2024_01_01_000009_create_related_party_risks_table.php
│   ├── 2024_01_01_000010_create_pep_screening_results_table.php
│   ├── 2024_01_01_000011_create_adverse_media_screenings_table.php
│   ├── 2024_01_01_000012_create_sanctions_screenings_table.php
│   └── 2024_01_01_000013_create_str_sar_reports_table.php
└── seeds/
    ├── RiskCountryClassificationsSeeder.php
    ├── RiskIndustriesSeeder.php
    └── RiskProductsSeeder.php

resources/
└── views/
    └── risk-rating/
        ├── widgets/
        │   └── summary.blade.php
        └── partials/
            └── risk-profile.blade.php

routes/
└── api.php                              ← API routes defined here

API Endpoints Quick Reference

Calculate & Manage Risk

POST   /api/risk-rating/calculate              Calculate new risk rating
POST   /api/risk-rating/{id}/recalculate       Recalculate existing
POST   /api/risk-rating/batch-calculate        Bulk calculation
GET    /api/risk-rating/{id}                   Get current rating
GET    /api/risk-rating/{id}/history           Get rating history
POST   /api/risk-rating/{id}/approve           Approve high-risk account

Query & Reports

GET    /api/risk-rating/review-required        Accounts needing review
GET    /api/risk-rating/high-risk              High-risk accounts
GET    /api/risk-rating/statistics             Dashboard statistics
POST   /api/risk-rating/export/csv             Export to CSV
GET    /api/risk-rating/export/report          Generate report

Configuration

GET    /api/risk-rating/config/countries       List countries
PUT    /api/risk-rating/config/countries/{id}  Update country
GET    /api/risk-rating/config/industries      List industries
POST   /api/risk-rating/config/industries      Create industry
GET    /api/risk-rating/config/products        List products
POST   /api/risk-rating/config/products        Create product
GET    /api/risk-rating/config/product-industry-matrix  Get matrix
POST   /api/risk-rating/config/product-industry-matrix  Update matrix

Environment Variables

# Queue Configuration
QUEUE_CONNECTION=database

# Mail Configuration (for notifications)
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=aml@yourcompany.com
MAIL_FROM_NAME="${APP_NAME} AML"

# Risk Rating Specific
RISK_RATING_HIGH_APPROVAL_REQUIRED=true
RISK_RATING_AUTO_RECALCULATE=true
RISK_RATING_NOTIFICATION_ENABLED=true

Key Business Rules

1. Country Classification

  • Country A: FATF members (except USA) = 0 points
  • Country B: Non-FATF + USA = 1 point
  • Country C: FATF Grey List = 3 points
  • Country D: FATF Black List = 5 points

2. Product Contribution Limits

  • Very Low products have thresholds:
    • Monthly: ≤ R4,000
    • Annual: ≤ R48,000
    • Lump Sum: ≤ R200,000
  • Exceeding limits upgrades to Medium

3. PEP Rules

  • FPEP: Automatically High Risk (min score 5)
  • DPEP: High Risk only if adverse media present
  • RCA: Ordinary/related to FPEP treated as high risk

4. Sanctions List

  • Any hit on UNSC/OFAC/EU sanctions = IMMEDIATE ESCALATION
  • No business relationship allowed
  • Must be reviewed by AML Compliance Officer

5. STR/SAR Reporting

  • 2+ STR/SAR in 12 months = Non-discretionary +2 points
  • Relationship maintained after STR = +3 points

6. Review Periods

  • High Risk: 6 months
  • Medium+ Risk: 12 months
  • Medium Risk: 12 months
  • Low Risk: 24 months

Security Considerations

Data Protection

  • All risk data is sensitive - ensure proper access controls
  • Audit trail maintained in risk_assessment_history
  • PII encryption recommended for production

Access Control

// Recommended permissions
'risk_rating.calculate'     => ['admin', 'compliance'],
'risk_rating.approve'       => ['aml_officer'],
'risk_rating.view'          => ['admin', 'compliance', 'relationship_manager'],
'risk_rating.export'        => ['admin', 'compliance'],
'risk_rating.config.manage' => ['admin'],

Audit Logging

  • All risk calculations logged
  • All approvals/rejections logged
  • Configuration changes tracked
  • Access to high-risk profiles logged

Performance Optimization

Caching Strategy

// Cache country classifications (rarely change)
Cache::remember('risk_countries', 86400, function() {
    return RiskCountryClassification::all();
});

// Cache industry matrix (rarely change)
Cache::remember('risk_industries', 86400, function() {
    return RiskIndustry::all();
});

Database Indexing

-- Already defined in migrations
CREATE INDEX idx_account_id ON customer_risk_profiles(account_id);
CREATE INDEX idx_is_current ON customer_risk_profiles(is_current);
CREATE INDEX idx_risk_class ON customer_risk_profiles(risk_class);
CREATE INDEX idx_review_date ON customer_risk_profiles(next_review_date);

Queue Processing

# Process risk calculations in background
php artisan queue:work --queue=risk_rating,default --tries=3

Monitoring & Alerts

Health Checks

// Check for overdue reviews
$overdue = CustomerRiskProfile::current()
    ->whereDate('next_review_date', '<', now())
    ->count();

// Check for pending AML approvals
$pendingApprovals = CustomerRiskProfile::current()
    ->where('requires_aml_approval', true)
    ->count();

// Check average calculation time
$avgTime = RiskAssessmentHistory::where('created_at', '>=', now()->subDay())
    ->avg('calculation_time_ms');

Key Metrics

  • Total risk profiles
  • Distribution by risk class
  • Pending AML approvals
  • Overdue reviews
  • Average risk score trend
  • Calculation performance

Compliance Checklist

  • All 13 database tables created
  • Country classifications seeded (update regularly per FATF)
  • Industry classifications configured
  • Product classifications configured
  • Product-industry matrix populated
  • PEP screening integration active
  • Sanctions screening integration active
  • Adverse media monitoring configured
  • Notification system tested
  • Review schedule automated
  • Audit trail verified
  • User permissions configured
  • Documentation completed
  • Training materials prepared
  • Go-live approval obtained

Support & Maintenance

Regular Maintenance Tasks

Monthly:

  • Review and update country classifications (check FATF updates)
  • Review high-risk accounts
  • Check for overdue reviews

Quarterly:

  • Audit risk calculation accuracy
  • Review and update industry risk indicators
  • Update product classifications if new products launched

Annually:

  • Full review of risk framework alignment
  • Update risk matrices based on regulatory changes
  • System performance review

Troubleshooting Guide

Issue: Risk score seems incorrect Solution:

  1. Check risk_assessment_history for calculation details
  2. Review profile_indicators for breakdown
  3. Verify configuration data (countries, industries, products)

Issue: Notifications not sending Solution:

  1. Check queue worker is running
  2. Verify mail configuration
  3. Check notification logs

Issue: Reviews not triggering Solution:

  1. Verify cron is running php artisan schedule:run
  2. Check next_review_date values
  3. Review command logs

Version History

v1.0.0 - Initial Implementation

  • All 13 tables implemented
  • Core calculation engine
  • API endpoints
  • Notification system
  • Export functionality

Document Version: 1.0
Last Updated: 2024-01-01
Author: Development Team
Classification: Internal Use Only


---
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment