Skip to main content

mockforge_core/config/
contracts.rs

1//! Contract, incident, and behavioral configuration types
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6/// Incident management configuration
7#[derive(Debug, Clone, Serialize, Deserialize, Default)]
8#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
9#[serde(default)]
10pub struct IncidentConfig {
11    /// Storage configuration
12    pub storage: IncidentStorageConfig,
13    /// External integrations configuration
14    pub external_integrations: crate::incidents::integrations::ExternalIntegrationConfig,
15    /// Webhook configurations
16    pub webhooks: Vec<crate::incidents::integrations::WebhookConfig>,
17}
18
19/// Incident storage configuration
20#[derive(Debug, Clone, Serialize, Deserialize)]
21#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
22pub struct IncidentStorageConfig {
23    /// Use in-memory cache (default: true)
24    pub use_cache: bool,
25    /// Use database persistence (default: true)
26    pub use_database: bool,
27    /// Retention period for resolved incidents (days)
28    pub retention_days: u32,
29}
30
31impl Default for IncidentStorageConfig {
32    fn default() -> Self {
33        Self {
34            use_cache: true,
35            use_database: true,
36            retention_days: 90,
37        }
38    }
39}
40
41/// Consumer contracts configuration
42#[derive(Debug, Clone, Serialize, Deserialize, Default)]
43#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
44#[serde(default)]
45pub struct ConsumerContractsConfig {
46    /// Whether consumer contracts are enabled
47    pub enabled: bool,
48    /// Auto-register consumers from requests
49    pub auto_register: bool,
50    /// Track field usage
51    pub track_usage: bool,
52}
53
54/// Contracts configuration for fitness rules and contract management
55#[derive(Debug, Clone, Serialize, Deserialize, Default)]
56#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
57#[serde(default)]
58pub struct ContractsConfig {
59    /// Fitness rules for contract validation
60    pub fitness_rules: Vec<FitnessRuleConfig>,
61}
62
63/// Behavioral Economics Engine configuration
64#[derive(Debug, Clone, Serialize, Deserialize, Default)]
65#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
66#[serde(default)]
67pub struct BehavioralEconomicsConfig {
68    /// Whether the behavioral economics engine is enabled
69    pub enabled: bool,
70    /// List of behavior rules
71    #[serde(default)]
72    pub rules: Vec<crate::behavioral_economics::BehaviorRule>,
73    /// Global sensitivity for behavioral changes (0.0 - 1.0)
74    /// A higher sensitivity means mocks react more strongly to conditions.
75    #[serde(default = "default_behavioral_sensitivity")]
76    pub global_sensitivity: f64,
77    /// Interval in milliseconds for re-evaluating time-based conditions
78    #[serde(default = "default_evaluation_interval_ms")]
79    pub evaluation_interval_ms: u64,
80}
81
82fn default_behavioral_sensitivity() -> f64 {
83    0.5
84}
85
86fn default_evaluation_interval_ms() -> u64 {
87    1000 // 1 second
88}
89
90/// Drift Learning configuration
91#[derive(Debug, Clone, Serialize, Deserialize, Default)]
92#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
93#[serde(default)]
94pub struct DriftLearningConfig {
95    /// Enable or disable drift learning
96    pub enabled: bool,
97    /// Learning mode (behavioral, statistical, hybrid)
98    #[serde(default)]
99    pub mode: DriftLearningMode,
100    /// How quickly mocks adapt to new patterns (0.0 - 1.0)
101    #[serde(default = "default_learning_sensitivity")]
102    pub sensitivity: f64,
103    /// How quickly old patterns are forgotten (0.0 - 1.0)
104    #[serde(default = "default_learning_decay")]
105    pub decay: f64,
106    /// Minimum number of samples required to learn a pattern
107    #[serde(default = "default_min_samples")]
108    pub min_samples: u64,
109    /// Enable persona-specific behavior adaptation
110    #[serde(default)]
111    pub persona_adaptation: bool,
112    /// Opt-in configuration for specific personas to learn
113    #[serde(default)]
114    pub persona_learning: HashMap<String, bool>, // persona_id -> enabled
115    /// Opt-in configuration for specific endpoints to learn
116    #[serde(default)]
117    pub endpoint_learning: HashMap<String, bool>, // endpoint_pattern -> enabled
118}
119
120/// Drift learning mode
121#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
122#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
123#[serde(rename_all = "snake_case")]
124pub enum DriftLearningMode {
125    /// Behavioral learning - adapts to behavior patterns
126    #[default]
127    Behavioral,
128    /// Statistical learning - adapts to statistical patterns
129    Statistical,
130    /// Hybrid - combines behavioral and statistical
131    Hybrid,
132}
133
134fn default_learning_sensitivity() -> f64 {
135    0.2
136}
137
138fn default_learning_decay() -> f64 {
139    0.05
140}
141
142fn default_min_samples() -> u64 {
143    10
144}
145
146/// Configuration for a fitness rule (YAML config format)
147#[derive(Debug, Clone, Serialize, Deserialize)]
148#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
149pub struct FitnessRuleConfig {
150    /// Human-readable name for the fitness rule
151    pub name: String,
152    /// Scope where this rule applies (endpoint pattern, service name, or "global")
153    pub scope: String,
154    /// Type of fitness rule
155    #[serde(rename = "type")]
156    pub rule_type: FitnessRuleType,
157    /// Maximum percent increase for response size (for response_size_delta type)
158    #[serde(skip_serializing_if = "Option::is_none")]
159    pub max_percent_increase: Option<f64>,
160    /// Maximum number of fields (for field_count type)
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub max_fields: Option<u32>,
163    /// Maximum schema depth (for schema_complexity type)
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub max_depth: Option<u32>,
166}
167
168/// Type of fitness rule (YAML config format)
169#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
170#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
171#[serde(rename_all = "snake_case")]
172pub enum FitnessRuleType {
173    /// Response size must not increase by more than max_percent_increase
174    ResponseSizeDelta,
175    /// No new required fields allowed
176    NoNewRequiredFields,
177    /// Field count must not exceed max_fields
178    FieldCount,
179    /// Schema complexity (depth) must not exceed max_depth
180    SchemaComplexity,
181}
182
183/// Behavioral cloning configuration
184#[derive(Debug, Clone, Serialize, Deserialize)]
185#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
186#[serde(default)]
187pub struct BehavioralCloningConfig {
188    /// Whether behavioral cloning is enabled
189    pub enabled: bool,
190    /// Path to recorder database (defaults to ./recordings.db)
191    pub database_path: Option<String>,
192    /// Enable middleware to apply learned behavior
193    pub enable_middleware: bool,
194    /// Minimum frequency threshold for sequence learning (0.0 to 1.0)
195    pub min_sequence_frequency: f64,
196    /// Minimum requests per trace for sequence discovery
197    pub min_requests_per_trace: Option<i32>,
198    /// Flow recording configuration
199    #[serde(default)]
200    pub flow_recording: FlowRecordingConfig,
201    /// Scenario replay configuration
202    #[serde(default)]
203    pub scenario_replay: ScenarioReplayConfig,
204}
205
206/// Flow recording configuration
207#[derive(Debug, Clone, Serialize, Deserialize)]
208#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
209#[serde(default)]
210pub struct FlowRecordingConfig {
211    /// Whether flow recording is enabled
212    pub enabled: bool,
213    /// How to group requests into flows (trace_id, session_id, ip_time_window)
214    pub group_by: String,
215    /// Time window in seconds for IP-based grouping
216    pub time_window_seconds: u64,
217}
218
219impl Default for FlowRecordingConfig {
220    fn default() -> Self {
221        Self {
222            enabled: true,
223            group_by: "trace_id".to_string(),
224            time_window_seconds: 300, // 5 minutes
225        }
226    }
227}
228
229/// Scenario replay configuration
230#[derive(Debug, Clone, Serialize, Deserialize)]
231#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
232#[serde(default)]
233pub struct ScenarioReplayConfig {
234    /// Whether scenario replay is enabled
235    pub enabled: bool,
236    /// Default replay mode (strict or flex)
237    pub default_mode: String,
238    /// List of scenario IDs to activate on startup
239    pub active_scenarios: Vec<String>,
240}
241
242impl Default for ScenarioReplayConfig {
243    fn default() -> Self {
244        Self {
245            enabled: true,
246            default_mode: "strict".to_string(),
247            active_scenarios: Vec::new(),
248        }
249    }
250}
251
252impl Default for BehavioralCloningConfig {
253    fn default() -> Self {
254        Self {
255            enabled: false,
256            database_path: None,
257            enable_middleware: false,
258            min_sequence_frequency: 0.1, // 10% default
259            min_requests_per_trace: None,
260            flow_recording: FlowRecordingConfig::default(),
261            scenario_replay: ScenarioReplayConfig::default(),
262        }
263    }
264}