┌─────────────────────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────────────────────┘
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 │
└───────────────────────────────────────────────────────────────┘
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
| 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 |
| 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 |
| 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 |
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
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
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
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
# 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- 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
- Very Low products have thresholds:
- Monthly: ≤ R4,000
- Annual: ≤ R48,000
- Lump Sum: ≤ R200,000
- Exceeding limits upgrades to Medium
- FPEP: Automatically High Risk (min score 5)
- DPEP: High Risk only if adverse media present
- RCA: Ordinary/related to FPEP treated as high risk
- Any hit on UNSC/OFAC/EU sanctions = IMMEDIATE ESCALATION
- No business relationship allowed
- Must be reviewed by AML Compliance Officer
- 2+ STR/SAR in 12 months = Non-discretionary +2 points
- Relationship maintained after STR = +3 points
- High Risk: 6 months
- Medium+ Risk: 12 months
- Medium Risk: 12 months
- Low Risk: 24 months
- All risk data is sensitive - ensure proper access controls
- Audit trail maintained in
risk_assessment_history - PII encryption recommended for production
// 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'],- All risk calculations logged
- All approvals/rejections logged
- Configuration changes tracked
- Access to high-risk profiles logged
// 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();
});-- 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);# Process risk calculations in background
php artisan queue:work --queue=risk_rating,default --tries=3// 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');- Total risk profiles
- Distribution by risk class
- Pending AML approvals
- Overdue reviews
- Average risk score trend
- Calculation performance
- 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
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
Issue: Risk score seems incorrect Solution:
- Check
risk_assessment_historyfor calculation details - Review
profile_indicatorsfor breakdown - Verify configuration data (countries, industries, products)
Issue: Notifications not sending Solution:
- Check queue worker is running
- Verify mail configuration
- Check notification logs
Issue: Reviews not triggering Solution:
- Verify cron is running
php artisan schedule:run - Check
next_review_datevalues - Review command logs
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
---