rustkernel_compliance/
messages.rs

1//! Ring message types for compliance kernels.
2//!
3//! This module defines request/response message types for GPU-native
4//! persistent actor communication for compliance algorithms.
5
6use crate::types::{
7    AMLPatternResult, CircularFlowResult, Entity, EntityResolutionResult, KYCFactors, KYCResult,
8    MonitoringResult, MonitoringRule, PEPEntry, PEPResult, RapidMovementResult, ReciprocityResult,
9    SanctionsEntry, SanctionsResult, TimeWindow, Transaction,
10};
11use serde::{Deserialize, Serialize};
12
13// ============================================================================
14// AML Messages
15// ============================================================================
16
17/// Circular flow ratio input for batch execution.
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct CircularFlowInput {
20    /// Transactions to analyze.
21    pub transactions: Vec<Transaction>,
22    /// Minimum amount for a cycle to be flagged.
23    pub min_amount: f64,
24}
25
26impl CircularFlowInput {
27    /// Create a new circular flow input.
28    pub fn new(transactions: Vec<Transaction>, min_amount: f64) -> Self {
29        Self {
30            transactions,
31            min_amount,
32        }
33    }
34}
35
36/// Circular flow output.
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct CircularFlowOutput {
39    /// The analysis result.
40    pub result: CircularFlowResult,
41    /// Computation time in microseconds.
42    pub compute_time_us: u64,
43}
44
45/// Reciprocity flow input for batch execution.
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct ReciprocityFlowInput {
48    /// Transactions to analyze.
49    pub transactions: Vec<Transaction>,
50    /// Time window for analysis (optional).
51    pub window: Option<TimeWindow>,
52    /// Minimum amount to consider.
53    pub min_amount: f64,
54}
55
56impl ReciprocityFlowInput {
57    /// Create a new reciprocity flow input.
58    pub fn new(transactions: Vec<Transaction>, min_amount: f64) -> Self {
59        Self {
60            transactions,
61            window: None,
62            min_amount,
63        }
64    }
65
66    /// Set time window.
67    pub fn with_window(mut self, window: TimeWindow) -> Self {
68        self.window = Some(window);
69        self
70    }
71}
72
73/// Reciprocity flow output.
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct ReciprocityFlowOutput {
76    /// The analysis result.
77    pub result: ReciprocityResult,
78    /// Computation time in microseconds.
79    pub compute_time_us: u64,
80}
81
82/// Rapid movement input for batch execution.
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct RapidMovementInput {
85    /// Transactions to analyze.
86    pub transactions: Vec<Transaction>,
87    /// Time window in hours.
88    pub window_hours: f64,
89    /// Velocity threshold (transactions per hour).
90    pub velocity_threshold: f64,
91    /// Minimum amount threshold.
92    pub amount_threshold: f64,
93}
94
95impl RapidMovementInput {
96    /// Create a new rapid movement input.
97    pub fn new(
98        transactions: Vec<Transaction>,
99        window_hours: f64,
100        velocity_threshold: f64,
101        amount_threshold: f64,
102    ) -> Self {
103        Self {
104            transactions,
105            window_hours,
106            velocity_threshold,
107            amount_threshold,
108        }
109    }
110}
111
112/// Rapid movement output.
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct RapidMovementOutput {
115    /// The analysis result.
116    pub result: RapidMovementResult,
117    /// Computation time in microseconds.
118    pub compute_time_us: u64,
119}
120
121/// AML pattern detection input.
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct AMLPatternInput {
124    /// Transactions to analyze.
125    pub transactions: Vec<Transaction>,
126    /// Structuring threshold amount.
127    pub structuring_threshold: f64,
128    /// Structuring window in hours.
129    pub structuring_window_hours: f64,
130}
131
132impl AMLPatternInput {
133    /// Create a new AML pattern input.
134    pub fn new(transactions: Vec<Transaction>) -> Self {
135        Self {
136            transactions,
137            structuring_threshold: 10_000.0,
138            structuring_window_hours: 24.0,
139        }
140    }
141
142    /// Set structuring threshold.
143    pub fn with_structuring_threshold(mut self, threshold: f64) -> Self {
144        self.structuring_threshold = threshold;
145        self
146    }
147}
148
149/// AML pattern detection output.
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct AMLPatternOutput {
152    /// The detection result.
153    pub result: AMLPatternResult,
154    /// Computation time in microseconds.
155    pub compute_time_us: u64,
156}
157
158// ============================================================================
159// KYC Messages
160// ============================================================================
161
162/// KYC scoring input.
163#[derive(Debug, Clone, Serialize, Deserialize)]
164pub struct KYCScoringInput {
165    /// KYC factors for scoring.
166    pub factors: KYCFactors,
167}
168
169impl KYCScoringInput {
170    /// Create a new KYC scoring input.
171    pub fn new(factors: KYCFactors) -> Self {
172        Self { factors }
173    }
174}
175
176/// KYC scoring output.
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct KYCScoringOutput {
179    /// The scoring result.
180    pub result: KYCResult,
181    /// Computation time in microseconds.
182    pub compute_time_us: u64,
183}
184
185/// Entity resolution input.
186#[derive(Debug, Clone, Serialize, Deserialize)]
187pub struct EntityResolutionInput {
188    /// Query entity.
189    pub query: Entity,
190    /// Candidate entities.
191    pub candidates: Vec<Entity>,
192    /// Minimum match score threshold.
193    pub min_score: f64,
194    /// Maximum number of matches to return.
195    pub max_matches: usize,
196}
197
198impl EntityResolutionInput {
199    /// Create a new entity resolution input.
200    pub fn new(query: Entity, candidates: Vec<Entity>) -> Self {
201        Self {
202            query,
203            candidates,
204            min_score: 0.7,
205            max_matches: 10,
206        }
207    }
208}
209
210/// Entity resolution output.
211#[derive(Debug, Clone, Serialize, Deserialize)]
212pub struct EntityResolutionOutput {
213    /// The resolution result.
214    pub result: EntityResolutionResult,
215    /// Computation time in microseconds.
216    pub compute_time_us: u64,
217}
218
219// ============================================================================
220// Sanctions Messages
221// ============================================================================
222
223/// Sanctions screening input.
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct SanctionsScreeningInput {
226    /// Name to screen.
227    pub name: String,
228    /// Sanctions list to screen against.
229    pub sanctions_list: Vec<SanctionsEntry>,
230    /// Minimum match score threshold.
231    pub min_score: f64,
232    /// Maximum number of matches to return.
233    pub max_matches: usize,
234}
235
236impl SanctionsScreeningInput {
237    /// Create a new sanctions screening input.
238    pub fn new(name: String, sanctions_list: Vec<SanctionsEntry>) -> Self {
239        Self {
240            name,
241            sanctions_list,
242            min_score: 0.7,
243            max_matches: 10,
244        }
245    }
246}
247
248/// Sanctions screening output.
249#[derive(Debug, Clone, Serialize, Deserialize)]
250pub struct SanctionsScreeningOutput {
251    /// The screening result.
252    pub result: SanctionsResult,
253    /// Computation time in microseconds.
254    pub compute_time_us: u64,
255}
256
257/// PEP screening input.
258#[derive(Debug, Clone, Serialize, Deserialize)]
259pub struct PEPScreeningInput {
260    /// Name to screen.
261    pub name: String,
262    /// PEP list to screen against.
263    pub pep_list: Vec<PEPEntry>,
264    /// Minimum match score threshold.
265    pub min_score: f64,
266    /// Maximum number of matches to return.
267    pub max_matches: usize,
268}
269
270impl PEPScreeningInput {
271    /// Create a new PEP screening input.
272    pub fn new(name: String, pep_list: Vec<PEPEntry>) -> Self {
273        Self {
274            name,
275            pep_list,
276            min_score: 0.7,
277            max_matches: 10,
278        }
279    }
280}
281
282/// PEP screening output.
283#[derive(Debug, Clone, Serialize, Deserialize)]
284pub struct PEPScreeningOutput {
285    /// The screening result.
286    pub result: PEPResult,
287    /// Computation time in microseconds.
288    pub compute_time_us: u64,
289}
290
291// ============================================================================
292// Transaction Monitoring Messages
293// ============================================================================
294
295/// Transaction monitoring input.
296#[derive(Debug, Clone, Serialize, Deserialize)]
297pub struct TransactionMonitoringInput {
298    /// Transactions to monitor.
299    pub transactions: Vec<Transaction>,
300    /// Monitoring rules to apply.
301    pub rules: Vec<MonitoringRule>,
302    /// Current timestamp for time window calculations.
303    pub current_time: u64,
304}
305
306impl TransactionMonitoringInput {
307    /// Create a new transaction monitoring input.
308    pub fn new(
309        transactions: Vec<Transaction>,
310        rules: Vec<MonitoringRule>,
311        current_time: u64,
312    ) -> Self {
313        Self {
314            transactions,
315            rules,
316            current_time,
317        }
318    }
319}
320
321/// Transaction monitoring output.
322#[derive(Debug, Clone, Serialize, Deserialize)]
323pub struct TransactionMonitoringOutput {
324    /// The monitoring result.
325    pub result: MonitoringResult,
326    /// Computation time in microseconds.
327    pub compute_time_us: u64,
328}
329
330#[cfg(test)]
331mod tests {
332    use super::*;
333
334    #[test]
335    fn test_circular_flow_input_builder() {
336        let input = CircularFlowInput::new(vec![], 100.0);
337        assert_eq!(input.min_amount, 100.0);
338    }
339
340    #[test]
341    fn test_aml_pattern_input_builder() {
342        let input = AMLPatternInput::new(vec![]).with_structuring_threshold(5000.0);
343        assert_eq!(input.structuring_threshold, 5000.0);
344    }
345}