459 lines
13 KiB
Rust
459 lines
13 KiB
Rust
//! AI验证器模块
|
||
//!
|
||
//! 实现KYC、AML、风险评估和智能决策引擎
|
||
|
||
use crate::compliance_layer::*;
|
||
use crate::error::*;
|
||
use serde::{Deserialize, Serialize};
|
||
use std::collections::HashMap;
|
||
use async_trait::async_trait;
|
||
|
||
/// 合规数据
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct ComplianceData {
|
||
/// 用户ID
|
||
pub user_id: String,
|
||
/// 资产ID
|
||
pub asset_id: Option<String>,
|
||
/// 数据字段
|
||
pub fields: HashMap<String, serde_json::Value>,
|
||
/// 元数据
|
||
pub metadata: HashMap<String, String>,
|
||
}
|
||
|
||
impl ComplianceData {
|
||
/// 创建新的合规数据
|
||
pub fn new(user_id: String) -> Self {
|
||
Self {
|
||
user_id,
|
||
asset_id: None,
|
||
fields: HashMap::new(),
|
||
metadata: HashMap::new(),
|
||
}
|
||
}
|
||
|
||
/// 设置资产ID
|
||
pub fn with_asset_id(mut self, asset_id: String) -> Self {
|
||
self.asset_id = Some(asset_id);
|
||
self
|
||
}
|
||
|
||
/// 添加字段
|
||
pub fn add_field<T: Serialize>(&mut self, key: String, value: T) -> Result<()> {
|
||
self.fields.insert(key, serde_json::to_value(value)?);
|
||
Ok(())
|
||
}
|
||
|
||
/// 获取字段
|
||
pub fn get_field<T: for<'de> Deserialize<'de>>(&self, key: &str) -> Result<Option<T>> {
|
||
match self.fields.get(key) {
|
||
Some(value) => Ok(Some(serde_json::from_value(value.clone())?)),
|
||
None => Ok(None),
|
||
}
|
||
}
|
||
|
||
/// 添加元数据
|
||
pub fn add_metadata(&mut self, key: String, value: String) {
|
||
self.metadata.insert(key, value);
|
||
}
|
||
}
|
||
|
||
/// AI验证器trait
|
||
#[async_trait]
|
||
pub trait AIValidator: Send + Sync {
|
||
/// 验证数据
|
||
async fn validate(&self, data: &ComplianceData) -> Result<ComplianceResult>;
|
||
|
||
/// 获取验证器名称
|
||
fn name(&self) -> &str;
|
||
|
||
/// 获取验证器版本
|
||
fn version(&self) -> &str;
|
||
}
|
||
|
||
/// KYC验证器
|
||
pub struct KYCValidator {
|
||
/// 最小置信度阈值
|
||
min_confidence: f64,
|
||
}
|
||
|
||
impl KYCValidator {
|
||
/// 创建新的KYC验证器
|
||
pub fn new() -> Self {
|
||
Self {
|
||
min_confidence: 0.8,
|
||
}
|
||
}
|
||
|
||
/// 设置最小置信度
|
||
pub fn with_min_confidence(mut self, confidence: f64) -> Self {
|
||
self.min_confidence = confidence;
|
||
self
|
||
}
|
||
|
||
/// 验证身份文件
|
||
fn verify_identity_documents(&self, data: &ComplianceData) -> Result<f64> {
|
||
// 模拟AI模型验证身份文件
|
||
// 实际实现应调用真实的AI模型
|
||
let has_passport: bool = data.get_field("has_passport")?.unwrap_or(false);
|
||
let has_id_card: bool = data.get_field("has_id_card")?.unwrap_or(false);
|
||
let has_driver_license: bool = data.get_field("has_driver_license")?.unwrap_or(false);
|
||
|
||
let mut confidence = 0.0;
|
||
if has_passport { confidence += 0.4; }
|
||
if has_id_card { confidence += 0.3; }
|
||
if has_driver_license { confidence += 0.3; }
|
||
|
||
Ok(confidence)
|
||
}
|
||
|
||
/// 验证地址证明
|
||
fn verify_address_proof(&self, data: &ComplianceData) -> Result<f64> {
|
||
let has_utility_bill: bool = data.get_field("has_utility_bill")?.unwrap_or(false);
|
||
let has_bank_statement: bool = data.get_field("has_bank_statement")?.unwrap_or(false);
|
||
|
||
let mut confidence = 0.0;
|
||
if has_utility_bill { confidence += 0.5; }
|
||
if has_bank_statement { confidence += 0.5; }
|
||
|
||
Ok(confidence)
|
||
}
|
||
}
|
||
|
||
impl Default for KYCValidator {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
#[async_trait]
|
||
impl AIValidator for KYCValidator {
|
||
async fn validate(&self, data: &ComplianceData) -> Result<ComplianceResult> {
|
||
let identity_confidence = self.verify_identity_documents(data)?;
|
||
let address_confidence = self.verify_address_proof(data)?;
|
||
|
||
let confidence = (identity_confidence + address_confidence) / 2.0;
|
||
|
||
let (status, risk_level) = if confidence >= self.min_confidence {
|
||
(ComplianceStatus::Passed, RiskLevel::Low)
|
||
} else if confidence >= 0.6 {
|
||
(ComplianceStatus::ConditionalPass, RiskLevel::Medium)
|
||
} else if confidence >= 0.4 {
|
||
(ComplianceStatus::ManualReview, RiskLevel::High)
|
||
} else {
|
||
(ComplianceStatus::Failed, RiskLevel::Critical)
|
||
};
|
||
|
||
let mut issues = Vec::new();
|
||
if identity_confidence < 0.5 {
|
||
issues.push(ComplianceIssue {
|
||
code: "KYC001".to_string(),
|
||
description: "身份文件验证不足".to_string(),
|
||
severity: IssueSeverity::Warning,
|
||
regulations: vec!["KYC规范".to_string()],
|
||
});
|
||
}
|
||
|
||
Ok(ComplianceResult {
|
||
layer: ComplianceLayer::IdentityVerification,
|
||
status,
|
||
confidence,
|
||
risk_level,
|
||
details: format!("KYC验证完成,置信度: {:.2}", confidence),
|
||
issues,
|
||
recommendations: vec!["建议提供更多身份证明文件".to_string()],
|
||
timestamp: chrono::Utc::now(),
|
||
})
|
||
}
|
||
|
||
fn name(&self) -> &str {
|
||
"KYC Validator"
|
||
}
|
||
|
||
fn version(&self) -> &str {
|
||
"1.0.0"
|
||
}
|
||
}
|
||
|
||
/// AML验证器
|
||
pub struct AMLValidator {
|
||
/// 风险阈值
|
||
risk_threshold: f64,
|
||
}
|
||
|
||
impl AMLValidator {
|
||
/// 创建新的AML验证器
|
||
pub fn new() -> Self {
|
||
Self {
|
||
risk_threshold: 0.7,
|
||
}
|
||
}
|
||
|
||
/// 检查黑名单
|
||
fn check_blacklist(&self, data: &ComplianceData) -> Result<bool> {
|
||
// 模拟检查黑名单
|
||
let is_blacklisted: bool = data.get_field("is_blacklisted")?.unwrap_or(false);
|
||
Ok(is_blacklisted)
|
||
}
|
||
|
||
/// 检查交易模式
|
||
fn check_transaction_pattern(&self, data: &ComplianceData) -> Result<f64> {
|
||
// 模拟AI模型分析交易模式
|
||
let transaction_count: u32 = data.get_field("transaction_count")?.unwrap_or(0);
|
||
let high_value_count: u32 = data.get_field("high_value_count")?.unwrap_or(0);
|
||
|
||
let risk_score = if transaction_count > 100 && high_value_count > 10 {
|
||
0.8
|
||
} else if transaction_count > 50 {
|
||
0.5
|
||
} else {
|
||
0.2
|
||
};
|
||
|
||
Ok(risk_score)
|
||
}
|
||
}
|
||
|
||
impl Default for AMLValidator {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
#[async_trait]
|
||
impl AIValidator for AMLValidator {
|
||
async fn validate(&self, data: &ComplianceData) -> Result<ComplianceResult> {
|
||
let is_blacklisted = self.check_blacklist(data)?;
|
||
let risk_score = self.check_transaction_pattern(data)?;
|
||
|
||
let (status, risk_level, confidence) = if is_blacklisted {
|
||
(ComplianceStatus::Failed, RiskLevel::Critical, 0.0)
|
||
} else if risk_score >= self.risk_threshold {
|
||
(ComplianceStatus::ManualReview, RiskLevel::High, 0.3)
|
||
} else if risk_score >= 0.5 {
|
||
(ComplianceStatus::ConditionalPass, RiskLevel::Medium, 0.6)
|
||
} else {
|
||
(ComplianceStatus::Passed, RiskLevel::Low, 0.9)
|
||
};
|
||
|
||
let mut issues = Vec::new();
|
||
if is_blacklisted {
|
||
issues.push(ComplianceIssue {
|
||
code: "AML001".to_string(),
|
||
description: "用户在黑名单中".to_string(),
|
||
severity: IssueSeverity::Critical,
|
||
regulations: vec!["反洗钱法".to_string()],
|
||
});
|
||
}
|
||
|
||
Ok(ComplianceResult {
|
||
layer: ComplianceLayer::IdentityVerification,
|
||
status,
|
||
confidence,
|
||
risk_level,
|
||
details: format!("AML验证完成,风险评分: {:.2}", risk_score),
|
||
issues,
|
||
recommendations: if risk_score > 0.5 {
|
||
vec!["建议进行人工审核".to_string()]
|
||
} else {
|
||
vec![]
|
||
},
|
||
timestamp: chrono::Utc::now(),
|
||
})
|
||
}
|
||
|
||
fn name(&self) -> &str {
|
||
"AML Validator"
|
||
}
|
||
|
||
fn version(&self) -> &str {
|
||
"1.0.0"
|
||
}
|
||
}
|
||
|
||
/// 风险评估引擎
|
||
pub struct RiskAssessmentEngine {
|
||
/// 风险因子权重
|
||
risk_weights: HashMap<String, f64>,
|
||
}
|
||
|
||
impl RiskAssessmentEngine {
|
||
/// 创建新的风险评估引擎
|
||
pub fn new() -> Self {
|
||
let mut risk_weights = HashMap::new();
|
||
risk_weights.insert("kyc_risk".to_string(), 0.3);
|
||
risk_weights.insert("aml_risk".to_string(), 0.3);
|
||
risk_weights.insert("asset_risk".to_string(), 0.2);
|
||
risk_weights.insert("legal_risk".to_string(), 0.2);
|
||
|
||
Self { risk_weights }
|
||
}
|
||
|
||
/// 计算综合风险评分
|
||
pub fn calculate_risk(&self, data: &ComplianceData) -> Result<f64> {
|
||
let mut total_risk = 0.0;
|
||
|
||
for (factor, weight) in &self.risk_weights {
|
||
let risk: f64 = data.get_field(factor)?.unwrap_or(0.0);
|
||
total_risk += risk * weight;
|
||
}
|
||
|
||
Ok(total_risk)
|
||
}
|
||
|
||
/// 评估风险等级
|
||
pub fn assess_risk_level(&self, risk_score: f64) -> RiskLevel {
|
||
if risk_score >= 0.8 {
|
||
RiskLevel::Critical
|
||
} else if risk_score >= 0.6 {
|
||
RiskLevel::High
|
||
} else if risk_score >= 0.4 {
|
||
RiskLevel::Medium
|
||
} else {
|
||
RiskLevel::Low
|
||
}
|
||
}
|
||
}
|
||
|
||
impl Default for RiskAssessmentEngine {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
/// 智能决策引擎
|
||
pub struct DecisionEngine {
|
||
/// 决策规则
|
||
rules: Vec<DecisionRule>,
|
||
}
|
||
|
||
#[derive(Debug, Clone)]
|
||
pub struct DecisionRule {
|
||
/// 规则ID
|
||
pub id: String,
|
||
/// 规则名称
|
||
pub name: String,
|
||
/// 条件
|
||
pub condition: String,
|
||
/// 动作
|
||
pub action: DecisionAction,
|
||
}
|
||
|
||
#[derive(Debug, Clone)]
|
||
pub enum DecisionAction {
|
||
/// 批准
|
||
Approve,
|
||
/// 拒绝
|
||
Reject,
|
||
/// 人工审核
|
||
ManualReview,
|
||
/// 有条件批准
|
||
ConditionalApprove(String),
|
||
}
|
||
|
||
impl DecisionEngine {
|
||
/// 创建新的决策引擎
|
||
pub fn new() -> Self {
|
||
Self {
|
||
rules: Vec::new(),
|
||
}
|
||
}
|
||
|
||
/// 添加规则
|
||
pub fn add_rule(&mut self, rule: DecisionRule) {
|
||
self.rules.push(rule);
|
||
}
|
||
|
||
/// 执行决策
|
||
pub fn make_decision(&self, results: &[ComplianceResult]) -> DecisionAction {
|
||
// 检查是否有任何层级失败
|
||
if results.iter().any(|r| r.status == ComplianceStatus::Failed) {
|
||
return DecisionAction::Reject;
|
||
}
|
||
|
||
// 检查是否有高风险或极高风险
|
||
if results.iter().any(|r| r.risk_level >= RiskLevel::High) {
|
||
return DecisionAction::ManualReview;
|
||
}
|
||
|
||
// 检查是否有需要人工审核的
|
||
if results.iter().any(|r| r.status == ComplianceStatus::ManualReview) {
|
||
return DecisionAction::ManualReview;
|
||
}
|
||
|
||
// 检查是否有条件通过
|
||
if results.iter().any(|r| r.status == ComplianceStatus::ConditionalPass) {
|
||
return DecisionAction::ConditionalApprove("需要满足额外条件".to_string());
|
||
}
|
||
|
||
// 所有层级都通过
|
||
DecisionAction::Approve
|
||
}
|
||
}
|
||
|
||
impl Default for DecisionEngine {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[tokio::test]
|
||
async fn test_kyc_validator() {
|
||
let validator = KYCValidator::new();
|
||
let mut data = ComplianceData::new("user123".to_string());
|
||
data.add_field("has_passport".to_string(), true).unwrap();
|
||
data.add_field("has_id_card".to_string(), true).unwrap();
|
||
data.add_field("has_utility_bill".to_string(), true).unwrap();
|
||
data.add_field("has_bank_statement".to_string(), true).unwrap();
|
||
|
||
let result = validator.validate(&data).await.unwrap();
|
||
assert_eq!(result.status, ComplianceStatus::Passed);
|
||
}
|
||
|
||
#[tokio::test]
|
||
async fn test_aml_validator() {
|
||
let validator = AMLValidator::new();
|
||
let mut data = ComplianceData::new("user123".to_string());
|
||
data.add_field("is_blacklisted".to_string(), false).unwrap();
|
||
data.add_field("transaction_count".to_string(), 10u32).unwrap();
|
||
|
||
let result = validator.validate(&data).await.unwrap();
|
||
assert_eq!(result.status, ComplianceStatus::Passed);
|
||
}
|
||
|
||
#[test]
|
||
fn test_risk_assessment() {
|
||
let engine = RiskAssessmentEngine::new();
|
||
let mut data = ComplianceData::new("user123".to_string());
|
||
data.add_field("kyc_risk".to_string(), 0.2).unwrap();
|
||
data.add_field("aml_risk".to_string(), 0.3).unwrap();
|
||
|
||
let risk = engine.calculate_risk(&data).unwrap();
|
||
assert!(risk > 0.0 && risk < 1.0);
|
||
}
|
||
|
||
#[test]
|
||
fn test_decision_engine() {
|
||
let engine = DecisionEngine::new();
|
||
let results = vec![
|
||
ComplianceResult {
|
||
layer: ComplianceLayer::IdentityVerification,
|
||
status: ComplianceStatus::Passed,
|
||
confidence: 0.9,
|
||
risk_level: RiskLevel::Low,
|
||
details: "Test".to_string(),
|
||
issues: vec![],
|
||
recommendations: vec![],
|
||
timestamp: chrono::Utc::now(),
|
||
}
|
||
];
|
||
|
||
let decision = engine.make_decision(&results);
|
||
matches!(decision, DecisionAction::Approve);
|
||
}
|
||
}
|