{
  "job_id": "affy-demo-2026-06-01",
  "status": "complete",
  "created_at": "2026-06-01T09:14:22Z",
  "completed_at": "2026-06-01T09:14:49Z",
  "processing_time_ms": 27340,
  "applicant": {
    "name_on_statement": "SIPHO J MOKOENA",
    "bank": "capitec",
    "branch_code": "470010",
    "account_type": "savings",
    "statement_periods": [
      { "start": "2026-03-01", "end": "2026-03-31" },
      { "start": "2026-04-01", "end": "2026-04-30" },
      { "start": "2026-05-01", "end": "2026-05-31" }
    ]
  },

  "extraction_summary": {
    "total_transactions": 287,
    "classified": 274,
    "classification_rate": 0.955,
    "unclassified": 13,
    "months_covered": 3,
    "pages_processed": 18,
    "extraction_method": "regex",
    "vision_fallback_used": false,
    "balance_reconciled": true,
    "opening_balance": 2341.50,
    "closing_balance": 3102.88
  },

  "tamper_check": {
    "overall_status": "clear",
    "fraud_score": 12,
    "threshold": 61,
    "checks_run": 18,
    "checks_passed": 17,
    "checks_failed": 1,
    "killer_check_failed": false,
    "detail": [
      { "check": "creation_date_postdates_period", "category": "metadata", "passed": true, "score": 0, "killer": false },
      { "check": "software_version_anomaly", "category": "metadata", "passed": true, "score": 0, "killer": false },
      { "check": "author_field_blank_or_generic", "category": "metadata", "passed": false, "score": 5, "killer": false, "note": "Author field is blank — common for Capitec exports" },
      { "check": "modified_vs_creation_conflict", "category": "metadata", "passed": true, "score": 0, "killer": true },
      { "check": "timezone_locale_mismatch", "category": "metadata", "passed": true, "score": 0, "killer": false },
      { "check": "mixed_font_families", "category": "font_layout", "passed": true, "score": 0, "killer": false },
      { "check": "character_spacing_inconsistency", "category": "font_layout", "passed": true, "score": 0, "killer": false },
      { "check": "pixel_alignment_irregularity", "category": "font_layout", "passed": true, "score": 0, "killer": false },
      { "check": "whitespace_patching", "category": "font_layout", "passed": true, "score": 0, "killer": true },
      { "check": "resolution_inconsistency", "category": "font_layout", "passed": true, "score": 0, "killer": false },
      { "check": "gross_minus_deductions_mismatch", "category": "mathematical", "passed": true, "score": 0, "killer": true },
      { "check": "ytd_accumulation_error", "category": "mathematical", "passed": true, "score": 0, "killer": false },
      { "check": "balance_forward_mismatch", "category": "mathematical", "passed": true, "score": 0, "killer": true },
      { "check": "running_balance_arithmetic_error", "category": "mathematical", "passed": true, "score": 0, "killer": false },
      { "check": "statement_period_gap_overlap", "category": "sequence", "passed": true, "score": 0, "killer": false },
      { "check": "transaction_dates_outside_period", "category": "sequence", "passed": true, "score": 0, "killer": false },
      { "check": "page_numbering_anomaly", "category": "sequence", "passed": true, "score": 0, "killer": false },
      { "check": "reference_number_format_invalid", "category": "sequence", "passed": true, "score": 0, "killer": false }
    ]
  },

  "income": {
    "gross_monthly_avg": 18450.00,
    "net_monthly_avg": 15210.00,
    "salary_detected": true,
    "salary_recurrence": "3/3 months",
    "salary_employer": "SHOPRITE HOLDINGS",
    "salary_stability_cov": 0.03,
    "additional_income": [
      { "source": "IRREGULAR DEPOSIT", "monthly_avg": 1200.00, "frequency": "1/3 months" }
    ],
    "statutory_deductions": {
      "paye": 2140.00,
      "uif": 155.00,
      "pension": 945.00
    }
  },

  "expenses_by_category": [
    { "category": "housing", "monthly_avg": 3500.00, "transaction_count": 3, "pct_of_income": 0.230 },
    { "category": "food_groceries", "monthly_avg": 2890.00, "transaction_count": 34, "pct_of_income": 0.190 },
    { "category": "transport", "monthly_avg": 1650.00, "transaction_count": 18, "pct_of_income": 0.109 },
    { "category": "utilities", "monthly_avg": 980.00, "transaction_count": 6, "pct_of_income": 0.064 },
    { "category": "debt_repayments", "monthly_avg": 2350.00, "transaction_count": 8, "pct_of_income": 0.155 },
    { "category": "insurance", "monthly_avg": 890.00, "transaction_count": 3, "pct_of_income": 0.059 },
    { "category": "communication", "monthly_avg": 420.00, "transaction_count": 6, "pct_of_income": 0.028 },
    { "category": "entertainment_dining", "monthly_avg": 680.00, "transaction_count": 12, "pct_of_income": 0.045 },
    { "category": "gambling", "monthly_avg": 450.00, "transaction_count": 5, "pct_of_income": 0.030, "flagged": true },
    { "category": "medical", "monthly_avg": 340.00, "transaction_count": 2, "pct_of_income": 0.022 },
    { "category": "clothing_personal", "monthly_avg": 560.00, "transaction_count": 7, "pct_of_income": 0.037 },
    { "category": "education", "monthly_avg": 0.00, "transaction_count": 0, "pct_of_income": 0.000 },
    { "category": "other", "monthly_avg": 890.00, "transaction_count": 13, "pct_of_income": 0.059 }
  ],

  "debt_obligations": {
    "identified_lenders": [
      { "name": "WONGA FINANCE", "type": "short_term_lender", "monthly_avg": 950.00 },
      { "name": "ABSA VEHICLE FINANCE", "type": "vehicle_finance", "monthly_avg": 1400.00 }
    ],
    "total_monthly_debt": 2350.00,
    "debt_service_ratio": 0.155
  },

  "counterparties": {
    "employers": ["SHOPRITE HOLDINGS"],
    "short_term_lenders": ["WONGA FINANCE"],
    "insurers": ["OLD MUTUAL", "OUTSURANCE"],
    "gambling_operators": ["HOLLYWOODBETS"],
    "government": ["SARS"],
    "telecoms": ["VODACOM", "MTN"]
  },

  "affordability": {
    "calc_version": "GG41604-2018",
    "regulation": "Regulation 23A",
    "net_income": 15210.00,
    "considered_expenses": 14600.00,
    "nca_minimum_norm": 2384.58,
    "consumer_declared_expenses": 14600.00,
    "expenses_used": "consumer_declared",
    "existing_debt_obligations": 2350.00,
    "disposable_income": -1740.00,
    "max_instalment_35pct": 0.00,
    "max_loan_amount": 0.00,
    "outcome": "insufficient_disposable_income",
    "note": "Consumer expenses exceed net income minus debt obligations. No further credit recommended under Reg 23A."
  },

  "behavioural_score": {
    "score": 612,
    "max_score": 850,
    "band": "fair",
    "bands": {
      "limited": { "min": 300, "max": 449 },
      "developing": { "min": 450, "max": 549 },
      "fair": { "min": 550, "max": 649 },
      "good": { "min": 650, "max": 749 },
      "strong": { "min": 750, "max": 850 }
    },
    "families": {
      "income": {
        "weight": 0.30,
        "score_pct": 0.78,
        "factors": {
          "salary_recurrence": { "value": "3/3", "bin": "90-100%", "points_pct": 1.0 },
          "salary_stability_cov": { "value": 0.03, "bin": "<0.10", "points_pct": 1.0 },
          "irregular_income_share": { "value": 0.065, "bin": "5-15%", "points_pct": 0.40 }
        }
      },
      "cash_buffer": {
        "weight": 0.25,
        "score_pct": 0.54,
        "factors": {
          "avg_daily_balance": { "value": 1842.30, "bin": "R1000-R3000", "points_pct": 0.55 },
          "low_balance_days": { "value": 8, "bin": "5-10 days", "points_pct": 0.52 }
        }
      },
      "discipline": {
        "weight": 0.25,
        "score_pct": 0.62,
        "factors": {
          "returned_debit_orders": { "value": 1, "bin": "1-2", "points_pct": 0.65 },
          "lender_stacking": { "value": 1, "bin": "1 lender", "points_pct": 0.85 },
          "debt_service_ratio": { "value": 0.155, "bin": "10-20%", "points_pct": 0.75 }
        }
      },
      "red_flags": {
        "weight": 0.20,
        "score_pct": 0.85,
        "factors": {
          "gambling_share_of_wallet": { "value": 0.030, "bin": "<5%", "points_pct": 0.90 },
          "cash_dominance": { "value": 0.12, "bin": "10-20%", "points_pct": 0.75 }
        }
      }
    },
    "reason_codes": [
      {
        "code": "01",
        "severity": "medium",
        "text": "Debt service is 30-50% of salary. Less room before a new instalment overcommits the applicant."
      },
      {
        "code": "02",
        "severity": "low",
        "text": "Gambling is under 5% of income. Present but not material to affordability."
      },
      {
        "code": "03",
        "severity": "medium",
        "text": "Cash buffer averages R1,842 between pay cycles. Limited cushion for unexpected expenses."
      },
      {
        "code": "04",
        "severity": "info",
        "text": "One short-term lender detected (Wonga Finance). Monitor for stacking if additional credit is extended."
      }
    ]
  },

  "cross_sell_signals": [
    { "signal": "short_term_lender_detected", "opportunity": "consolidation_loan", "detail": "Wonga Finance R950/mo — candidate for consolidation at lower rate" },
    { "signal": "insurance_premiums_mapped", "opportunity": "broker_review", "detail": "Old Mutual + Outsurance totalling R890/mo — review for coverage gaps or savings" },
    { "signal": "gambling_detected", "opportunity": "wellness_referral", "detail": "Hollywoodbets R450/mo (3% of income) — below intervention threshold, flag for monitoring" }
  ],

  "eligibility": {
    "debt_review": { "status": "clear", "signal": "none" },
    "lender_stacking": { "status": "amber", "concurrent_lenders": 1, "threshold": "soft" },
    "gambling": { "status": "green", "share_of_salary": 0.030, "threshold": 0.20, "blocked": false }
  }
}
