1use rust_decimal::Decimal;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, Default)]
8pub struct EvaluationConfig {
9 pub statistical: StatisticalConfig,
11 pub coherence: CoherenceConfig,
13 pub quality: QualityConfig,
15 pub ml: MlConfig,
17 #[serde(default)]
19 pub privacy: PrivacyEvaluationConfig,
20 pub report: ReportConfig,
22 pub thresholds: EvaluationThresholds,
24 #[serde(default)]
26 pub quality_gates: QualityGateConfig,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct QualityGateConfig {
32 #[serde(default)]
34 pub enabled: bool,
35 #[serde(default = "default_gate_profile")]
37 pub profile: String,
38 #[serde(default)]
40 pub custom_gates: Vec<CustomGateConfig>,
41 #[serde(default)]
43 pub fail_on_violation: bool,
44}
45
46fn default_gate_profile() -> String {
47 "default".to_string()
48}
49
50impl Default for QualityGateConfig {
51 fn default() -> Self {
52 Self {
53 enabled: false,
54 profile: default_gate_profile(),
55 custom_gates: Vec::new(),
56 fail_on_violation: false,
57 }
58 }
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct CustomGateConfig {
64 pub name: String,
66 pub metric: String,
68 pub threshold: f64,
70 #[serde(default)]
72 pub upper_threshold: Option<f64>,
73 #[serde(default = "default_comparison")]
75 pub comparison: String,
76}
77
78fn default_comparison() -> String {
79 "gte".to_string()
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct PrivacyEvaluationConfig {
85 pub mia_enabled: bool,
87 pub linkage_enabled: bool,
89 pub nist_alignment_enabled: bool,
91 pub synqp_enabled: bool,
93 pub mia_auc_threshold: f64,
95 pub max_reidentification_rate: f64,
97 pub min_k_anonymity: usize,
99}
100
101impl Default for PrivacyEvaluationConfig {
102 fn default() -> Self {
103 Self {
104 mia_enabled: false,
105 linkage_enabled: false,
106 nist_alignment_enabled: false,
107 synqp_enabled: false,
108 mia_auc_threshold: 0.6,
109 max_reidentification_rate: 0.05,
110 min_k_anonymity: 5,
111 }
112 }
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct StatisticalConfig {
118 pub benford_enabled: bool,
120 pub amount_distribution_enabled: bool,
122 pub line_item_enabled: bool,
124 pub temporal_enabled: bool,
126 pub drift_detection_enabled: bool,
128 pub significance_level: f64,
130 pub min_sample_size: usize,
132 pub drift_window_size: usize,
134 #[serde(default)]
136 pub anomaly_realism_enabled: bool,
137}
138
139impl Default for StatisticalConfig {
140 fn default() -> Self {
141 Self {
142 benford_enabled: true,
143 amount_distribution_enabled: true,
144 line_item_enabled: true,
145 temporal_enabled: true,
146 drift_detection_enabled: true,
147 significance_level: 0.05,
148 min_sample_size: 100,
149 drift_window_size: 10,
150 anomaly_realism_enabled: false,
151 }
152 }
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct CoherenceConfig {
158 pub balance_enabled: bool,
160 pub subledger_enabled: bool,
162 pub document_chain_enabled: bool,
164 pub intercompany_enabled: bool,
166 pub referential_enabled: bool,
168 pub balance_tolerance: Decimal,
170 #[serde(default)]
172 pub financial_reporting_enabled: bool,
173 #[serde(default)]
175 pub hr_payroll_enabled: bool,
176 #[serde(default)]
178 pub manufacturing_enabled: bool,
179 #[serde(default)]
181 pub bank_reconciliation_enabled: bool,
182 #[serde(default)]
184 pub sourcing_enabled: bool,
185 #[serde(default)]
187 pub cross_process_enabled: bool,
188 #[serde(default)]
190 pub audit_enabled: bool,
191 #[serde(default)]
193 pub tax_enabled: bool,
194 #[serde(default)]
196 pub treasury_enabled: bool,
197 #[serde(default)]
199 pub project_accounting_enabled: bool,
200 #[serde(default)]
202 pub esg_enabled: bool,
203 #[serde(default)]
205 pub sales_quotes_enabled: bool,
206 #[serde(default)]
208 pub country_packs_enabled: bool,
209}
210
211impl Default for CoherenceConfig {
212 fn default() -> Self {
213 Self {
214 balance_enabled: true,
215 subledger_enabled: true,
216 document_chain_enabled: true,
217 intercompany_enabled: true,
218 referential_enabled: true,
219 balance_tolerance: Decimal::new(1, 2), financial_reporting_enabled: false,
221 hr_payroll_enabled: false,
222 manufacturing_enabled: false,
223 bank_reconciliation_enabled: false,
224 sourcing_enabled: false,
225 cross_process_enabled: false,
226 audit_enabled: false,
227 tax_enabled: false,
228 treasury_enabled: false,
229 project_accounting_enabled: false,
230 esg_enabled: false,
231 sales_quotes_enabled: false,
232 country_packs_enabled: false,
233 }
234 }
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct QualityConfig {
240 pub uniqueness_enabled: bool,
242 pub completeness_enabled: bool,
244 pub format_enabled: bool,
246 pub consistency_enabled: bool,
248 pub near_duplicate_threshold: f64,
250}
251
252impl Default for QualityConfig {
253 fn default() -> Self {
254 Self {
255 uniqueness_enabled: true,
256 completeness_enabled: true,
257 format_enabled: true,
258 consistency_enabled: true,
259 near_duplicate_threshold: 0.95,
260 }
261 }
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize)]
266pub struct MlConfig {
267 pub features_enabled: bool,
269 pub labels_enabled: bool,
271 pub splits_enabled: bool,
273 pub graph_enabled: bool,
275 #[serde(default)]
277 pub anomaly_scoring_enabled: bool,
278 #[serde(default)]
280 pub feature_quality_enabled: bool,
281 #[serde(default)]
283 pub gnn_readiness_enabled: bool,
284 #[serde(default)]
286 pub domain_gap_enabled: bool,
287 #[serde(default)]
289 pub temporal_fidelity_enabled: bool,
290 #[serde(default)]
292 pub scheme_detectability_enabled: bool,
293 #[serde(default)]
295 pub cross_modal_enabled: bool,
296 #[serde(default)]
298 pub embedding_readiness_enabled: bool,
299}
300
301impl Default for MlConfig {
302 fn default() -> Self {
303 Self {
304 features_enabled: true,
305 labels_enabled: true,
306 splits_enabled: true,
307 graph_enabled: true,
308 anomaly_scoring_enabled: false,
309 feature_quality_enabled: false,
310 gnn_readiness_enabled: false,
311 domain_gap_enabled: false,
312 temporal_fidelity_enabled: false,
313 scheme_detectability_enabled: false,
314 cross_modal_enabled: false,
315 embedding_readiness_enabled: false,
316 }
317 }
318}
319
320#[derive(Debug, Clone, Serialize, Deserialize)]
322pub struct ReportConfig {
323 pub html_enabled: bool,
325 pub json_enabled: bool,
327 pub charts_enabled: bool,
329 pub baseline_path: Option<String>,
331}
332
333impl Default for ReportConfig {
334 fn default() -> Self {
335 Self {
336 html_enabled: true,
337 json_enabled: true,
338 charts_enabled: true,
339 baseline_path: None,
340 }
341 }
342}
343
344#[derive(Debug, Clone, Default, Serialize, Deserialize)]
346pub struct BankingEvalConfig {
347 #[serde(default)]
349 pub kyc_enabled: bool,
350 #[serde(default)]
352 pub aml_enabled: bool,
353}
354
355#[derive(Debug, Clone, Default, Serialize, Deserialize)]
357pub struct ProcessMiningEvalConfig {
358 #[serde(default)]
360 pub event_sequence_enabled: bool,
361 #[serde(default)]
363 pub variant_analysis_enabled: bool,
364}
365
366#[derive(Debug, Clone, Default, Serialize, Deserialize)]
368pub struct CausalEvalConfig {
369 #[serde(default)]
371 pub enabled: bool,
372}
373
374#[derive(Debug, Clone, Default, Serialize, Deserialize)]
376pub struct EnrichmentEvalConfig {
377 #[serde(default)]
379 pub enabled: bool,
380}
381
382#[derive(Debug, Clone, Serialize, Deserialize)]
384pub struct EvaluationThresholds {
385 pub benford_p_value_min: f64,
388 pub benford_mad_max: f64,
390 pub amount_ks_p_value_min: f64,
392 pub temporal_correlation_min: f64,
394
395 pub drift_magnitude_min: f64,
398 pub drift_hellinger_max: f64,
400 pub drift_psi_max: f64,
402 pub drift_f1_score_min: f64,
404
405 pub balance_tolerance: Decimal,
408 pub subledger_reconciliation_rate_min: f64,
410 pub document_chain_completion_min: f64,
412 pub ic_match_rate_min: f64,
414 pub referential_integrity_min: f64,
416
417 pub duplicate_rate_max: f64,
420 pub completeness_rate_min: f64,
422 pub format_consistency_min: f64,
424
425 #[serde(default = "default_anomaly_separability")]
428 pub min_anomaly_separability: f64,
429 #[serde(default = "default_feature_quality")]
431 pub min_feature_quality: f64,
432 #[serde(default = "default_gnn_readiness")]
434 pub min_gnn_readiness: f64,
435 #[serde(default = "default_domain_gap")]
437 pub max_domain_gap: f64,
438 #[serde(default = "default_temporal_fidelity")]
440 pub min_temporal_fidelity: f64,
441 #[serde(default = "default_scheme_detectability")]
443 pub min_scheme_detectability: f64,
444 #[serde(default = "default_cross_modal")]
446 pub min_cross_modal_consistency: f64,
447 #[serde(default = "default_embedding_readiness")]
449 pub min_embedding_readiness: f64,
450
451 pub anomaly_rate_min: f64,
454 pub anomaly_rate_max: f64,
456 pub label_coverage_min: f64,
458 pub train_ratio_min: f64,
460 pub graph_connectivity_min: f64,
462}
463
464fn default_anomaly_separability() -> f64 {
465 0.70
466}
467fn default_feature_quality() -> f64 {
468 0.60
469}
470fn default_gnn_readiness() -> f64 {
471 0.65
472}
473fn default_domain_gap() -> f64 {
474 0.25
475}
476fn default_temporal_fidelity() -> f64 {
477 0.70
478}
479fn default_scheme_detectability() -> f64 {
480 0.60
481}
482fn default_cross_modal() -> f64 {
483 0.60
484}
485fn default_embedding_readiness() -> f64 {
486 0.50
487}
488
489impl Default for EvaluationThresholds {
490 fn default() -> Self {
491 Self {
492 benford_p_value_min: 0.05,
494 benford_mad_max: 0.015,
495 amount_ks_p_value_min: 0.05,
496 temporal_correlation_min: 0.80,
497
498 min_anomaly_separability: 0.70,
500 min_feature_quality: 0.60,
501 min_gnn_readiness: 0.65,
502 max_domain_gap: 0.25,
503 min_temporal_fidelity: 0.70,
504 min_scheme_detectability: 0.60,
505 min_cross_modal_consistency: 0.60,
506 min_embedding_readiness: 0.50,
507
508 drift_magnitude_min: 0.05,
510 drift_hellinger_max: 0.30,
511 drift_psi_max: 0.25,
512 drift_f1_score_min: 0.50,
513
514 balance_tolerance: Decimal::new(1, 2), subledger_reconciliation_rate_min: 0.99,
517 document_chain_completion_min: 0.90,
518 ic_match_rate_min: 0.95,
519 referential_integrity_min: 0.99,
520
521 duplicate_rate_max: 0.01,
523 completeness_rate_min: 0.95,
524 format_consistency_min: 0.99,
525
526 anomaly_rate_min: 0.01,
528 anomaly_rate_max: 0.20,
529 label_coverage_min: 0.99,
530 train_ratio_min: 0.60,
531 graph_connectivity_min: 0.95,
532 }
533 }
534}
535
536impl EvaluationThresholds {
537 pub fn strict() -> Self {
539 Self {
540 min_anomaly_separability: 0.80,
541 min_feature_quality: 0.70,
542 min_gnn_readiness: 0.75,
543 max_domain_gap: 0.15,
544 min_temporal_fidelity: 0.80,
545 min_scheme_detectability: 0.70,
546 min_cross_modal_consistency: 0.70,
547 min_embedding_readiness: 0.60,
548 benford_p_value_min: 0.10,
549 benford_mad_max: 0.010,
550 amount_ks_p_value_min: 0.10,
551 temporal_correlation_min: 0.90,
552 drift_magnitude_min: 0.03,
553 drift_hellinger_max: 0.20,
554 drift_psi_max: 0.15,
555 drift_f1_score_min: 0.70,
556 balance_tolerance: Decimal::new(1, 4), subledger_reconciliation_rate_min: 0.999,
558 document_chain_completion_min: 0.95,
559 ic_match_rate_min: 0.99,
560 referential_integrity_min: 0.999,
561 duplicate_rate_max: 0.001,
562 completeness_rate_min: 0.99,
563 format_consistency_min: 0.999,
564 anomaly_rate_min: 0.01,
565 anomaly_rate_max: 0.10,
566 label_coverage_min: 0.999,
567 train_ratio_min: 0.70,
568 graph_connectivity_min: 0.99,
569 }
570 }
571
572 pub fn lenient() -> Self {
574 Self {
575 min_anomaly_separability: 0.55,
576 min_feature_quality: 0.45,
577 min_gnn_readiness: 0.50,
578 max_domain_gap: 0.40,
579 min_temporal_fidelity: 0.55,
580 min_scheme_detectability: 0.45,
581 min_cross_modal_consistency: 0.45,
582 min_embedding_readiness: 0.35,
583 benford_p_value_min: 0.01,
584 benford_mad_max: 0.025,
585 amount_ks_p_value_min: 0.01,
586 temporal_correlation_min: 0.60,
587 drift_magnitude_min: 0.10,
588 drift_hellinger_max: 0.50,
589 drift_psi_max: 0.40,
590 drift_f1_score_min: 0.30,
591 balance_tolerance: Decimal::new(1, 1), subledger_reconciliation_rate_min: 0.90,
593 document_chain_completion_min: 0.80,
594 ic_match_rate_min: 0.85,
595 referential_integrity_min: 0.95,
596 duplicate_rate_max: 0.05,
597 completeness_rate_min: 0.90,
598 format_consistency_min: 0.95,
599 anomaly_rate_min: 0.005,
600 anomaly_rate_max: 0.30,
601 label_coverage_min: 0.95,
602 train_ratio_min: 0.50,
603 graph_connectivity_min: 0.90,
604 }
605 }
606}