1use crate::drift_detector::{DriftDetectionConfig, DriftDetector};
7use crate::error::Result;
8use crate::intent_tracker::{
9 ArchitecturalDecision, ArchitecturalEvolution, ArchitecturalSummary, DriftDetection,
10 IntentTracker,
11};
12use crate::models::LearnedPattern;
13use std::sync::Arc;
14use tokio::sync::RwLock;
15
16pub struct IntentTrackingIntegration {
18 intent_tracker: Arc<RwLock<IntentTracker>>,
20 drift_detector: Arc<RwLock<DriftDetector>>,
22}
23
24impl IntentTrackingIntegration {
25 pub fn new() -> Self {
27 Self {
28 intent_tracker: Arc::new(RwLock::new(IntentTracker::new())),
29 drift_detector: Arc::new(RwLock::new(DriftDetector::new())),
30 }
31 }
32
33 pub fn with_drift_config(config: DriftDetectionConfig) -> Self {
35 Self {
36 intent_tracker: Arc::new(RwLock::new(IntentTracker::new())),
37 drift_detector: Arc::new(RwLock::new(DriftDetector::with_config(config))),
38 }
39 }
40
41 pub async fn record_decision(
43 &self,
44 decision_type: String,
45 description: String,
46 rationale: String,
47 ) -> Result<ArchitecturalDecision> {
48 let mut tracker = self.intent_tracker.write().await;
49 tracker.record_decision(decision_type, description, rationale)
50 }
51
52 pub async fn get_decision(&self, decision_id: &str) -> Result<ArchitecturalDecision> {
54 let tracker = self.intent_tracker.read().await;
55 tracker.get_decision(decision_id)
56 }
57
58 pub async fn list_decisions(&self) -> Vec<ArchitecturalDecision> {
60 let tracker = self.intent_tracker.read().await;
61 tracker.list_decisions()
62 }
63
64 pub async fn identify_patterns(&self) -> Result<Vec<LearnedPattern>> {
66 let tracker = self.intent_tracker.read().await;
67 tracker.identify_patterns()
68 }
69
70 pub async fn record_evolution(
72 &self,
73 from_version: String,
74 to_version: String,
75 description: String,
76 ) -> Result<ArchitecturalEvolution> {
77 let mut tracker = self.intent_tracker.write().await;
78 tracker.record_evolution(from_version, to_version, description)
79 }
80
81 pub async fn get_evolution_history(&self) -> Vec<ArchitecturalEvolution> {
83 let tracker = self.intent_tracker.read().await;
84 tracker.get_evolution_history()
85 }
86
87 pub async fn detect_drift(
89 &self,
90 decision_id: &str,
91 drift_type: String,
92 description: String,
93 ) -> Result<DriftDetection> {
94 let mut tracker = self.intent_tracker.write().await;
95 tracker.detect_drift(decision_id, drift_type, description)
96 }
97
98 pub async fn get_drift_detections(&self) -> Vec<DriftDetection> {
100 let tracker = self.intent_tracker.read().await;
101 tracker.get_drift_detections()
102 }
103
104 pub async fn get_drift_for_decision(&self, decision_id: &str) -> Vec<DriftDetection> {
106 let tracker = self.intent_tracker.read().await;
107 tracker.get_drift_for_decision(decision_id)
108 }
109
110 pub async fn update_decision_confidence(
112 &self,
113 decision_id: &str,
114 confidence: f32,
115 ) -> Result<()> {
116 let mut tracker = self.intent_tracker.write().await;
117 tracker.update_decision_confidence(decision_id, confidence)
118 }
119
120 pub async fn increment_occurrence(&self, decision_id: &str) -> Result<()> {
122 let mut tracker = self.intent_tracker.write().await;
123 tracker.increment_occurrence(decision_id)
124 }
125
126 pub async fn get_summary(&self) -> ArchitecturalSummary {
128 let tracker = self.intent_tracker.read().await;
129 tracker.get_summary()
130 }
131
132 pub async fn register_pattern_for_drift_detection(
134 &self,
135 pattern: LearnedPattern,
136 ) -> Result<()> {
137 let mut detector = self.drift_detector.write().await;
138 detector.register_pattern(pattern)
139 }
140
141 pub async fn check_deviation(
143 &self,
144 decision: &ArchitecturalDecision,
145 pattern_type: &str,
146 ) -> Result<Option<DriftDetection>> {
147 let mut detector = self.drift_detector.write().await;
148 detector.check_deviation(decision, pattern_type)
149 }
150
151 pub async fn detect_inconsistency(
153 &self,
154 decision_id: &str,
155 expected_behavior: &str,
156 actual_behavior: &str,
157 ) -> Result<DriftDetection> {
158 let mut detector = self.drift_detector.write().await;
159 detector.detect_inconsistency(decision_id, expected_behavior, actual_behavior)
160 }
161
162 pub async fn detect_violation(
164 &self,
165 decision_id: &str,
166 violation_description: &str,
167 ) -> Result<DriftDetection> {
168 let mut detector = self.drift_detector.write().await;
169 detector.detect_violation(decision_id, violation_description)
170 }
171
172 pub async fn get_detector_drifts(&self) -> Vec<DriftDetection> {
174 let detector = self.drift_detector.read().await;
175 detector.get_drifts()
176 }
177
178 pub async fn get_drifts_by_severity(&self, severity: &str) -> Vec<DriftDetection> {
180 let detector = self.drift_detector.read().await;
181 detector.get_drifts_by_severity(severity)
182 }
183
184 pub async fn get_detector_drifts_for_decision(
186 &self,
187 decision_id: &str,
188 ) -> Vec<DriftDetection> {
189 let detector = self.drift_detector.read().await;
190 detector.get_drifts_for_decision(decision_id)
191 }
192
193 pub async fn clear_detector_drifts(&self) {
195 let mut detector = self.drift_detector.write().await;
196 detector.clear_drifts();
197 }
198
199 pub async fn get_drift_statistics(&self) -> crate::drift_detector::DriftStatistics {
201 let detector = self.drift_detector.read().await;
202 detector.get_statistics()
203 }
204
205 pub async fn perform_comprehensive_drift_detection(&self) -> Result<Vec<DriftDetection>> {
207 let tracker = self.intent_tracker.read().await;
208 let decisions = tracker.list_decisions();
209
210 let mut all_drifts = Vec::new();
211
212 for decision in decisions {
213 let patterns = tracker.identify_patterns()?;
215 for pattern in patterns {
216 let mut detector = self.drift_detector.write().await;
217 if let Ok(Some(drift)) = detector.check_deviation(&decision, &pattern.pattern_type) {
218 all_drifts.push(drift);
219 }
220 }
221 }
222
223 Ok(all_drifts)
224 }
225
226 pub async fn get_comprehensive_report(&self) -> ArchitecturalReport {
228 let summary = self.get_summary().await;
229 let decisions = self.list_decisions().await;
230 let evolution = self.get_evolution_history().await;
231 let drifts = self.get_drift_detections().await;
232 let detector_drifts = self.get_detector_drifts().await;
233 let drift_stats = self.get_drift_statistics().await;
234
235 ArchitecturalReport {
236 summary,
237 total_decisions: decisions.len(),
238 total_evolution_records: evolution.len(),
239 total_drifts: drifts.len() + detector_drifts.len(),
240 drift_statistics: drift_stats,
241 }
242 }
243}
244
245impl Default for IntentTrackingIntegration {
246 fn default() -> Self {
247 Self::new()
248 }
249}
250
251#[derive(Debug, Clone)]
253pub struct ArchitecturalReport {
254 pub summary: ArchitecturalSummary,
256 pub total_decisions: usize,
258 pub total_evolution_records: usize,
260 pub total_drifts: usize,
262 pub drift_statistics: crate::drift_detector::DriftStatistics,
264}
265
266#[cfg(test)]
267mod tests {
268 use super::*;
269
270 #[tokio::test]
271 async fn test_intent_tracking_integration_creation() {
272 let integration = IntentTrackingIntegration::new();
273 let summary = integration.get_summary().await;
274 assert_eq!(summary.total_decisions, 0);
275 }
276
277 #[tokio::test]
278 async fn test_record_decision() {
279 let integration = IntentTrackingIntegration::new();
280 let decision = integration
281 .record_decision(
282 "layering".to_string(),
283 "Implement layered architecture".to_string(),
284 "Separation of concerns".to_string(),
285 )
286 .await
287 .expect("Failed to record decision");
288
289 assert_eq!(decision.decision_type, "layering");
290 let decisions = integration.list_decisions().await;
291 assert_eq!(decisions.len(), 1);
292 }
293
294 #[tokio::test]
295 async fn test_record_evolution() {
296 let integration = IntentTrackingIntegration::new();
297 let evolution = integration
298 .record_evolution(
299 "0.1.0".to_string(),
300 "0.2.0".to_string(),
301 "Added async patterns".to_string(),
302 )
303 .await
304 .expect("Failed to record evolution");
305
306 assert_eq!(evolution.from_version, "0.1.0");
307 let history = integration.get_evolution_history().await;
308 assert_eq!(history.len(), 1);
309 }
310
311 #[tokio::test]
312 async fn test_detect_drift() {
313 let integration = IntentTrackingIntegration::new();
314 let decision = integration
315 .record_decision(
316 "layering".to_string(),
317 "Layered architecture".to_string(),
318 "Separation of concerns".to_string(),
319 )
320 .await
321 .expect("Failed to record decision");
322
323 let drift = integration
324 .detect_drift(
325 &decision.id,
326 "violation".to_string(),
327 "Direct layer bypass detected".to_string(),
328 )
329 .await
330 .expect("Failed to detect drift");
331
332 assert_eq!(drift.severity, "high");
333 let drifts = integration.get_drift_detections().await;
334 assert_eq!(drifts.len(), 1);
335 }
336
337 #[tokio::test]
338 async fn test_get_comprehensive_report() {
339 let integration = IntentTrackingIntegration::new();
340 integration
341 .record_decision(
342 "layering".to_string(),
343 "Layered architecture".to_string(),
344 "Separation of concerns".to_string(),
345 )
346 .await
347 .expect("Failed to record decision");
348
349 let report = integration.get_comprehensive_report().await;
350 assert_eq!(report.total_decisions, 1);
351 }
352}