ricecoder_agents/agents/
backend.rs

1//! Backend Development Agent
2//!
3//! This module provides a specialized agent for backend development tasks,
4//! including API design pattern recommendations, architecture guidance, database
5//! design recommendations, scalability guidance, security pattern recommendations,
6//! and observability setup guidance.
7
8use crate::agents::Agent;
9use crate::domain::{DomainAgent, DomainCapability, DomainKnowledge, TechRecommendation};
10use crate::error::Result;
11use crate::models::{AgentInput, AgentOutput, Finding, Severity, TaskType};
12use async_trait::async_trait;
13use uuid::Uuid;
14
15/// Backend Development Agent
16///
17/// A specialized agent for backend development that provides recommendations for:
18/// - API design patterns (REST, GraphQL, gRPC)
19/// - Architecture guidance (microservices, monolithic, serverless)
20/// - Database design (relational, NoSQL, graph)
21/// - Scalability guidance (caching, load balancing, horizontal scaling)
22/// - Security patterns (auth, authorization, data protection)
23/// - Observability setup (logging, metrics, tracing)
24///
25/// # Examples
26///
27/// ```ignore
28/// use ricecoder_agents::agents::BackendAgent;
29///
30/// let agent = BackendAgent::new();
31/// assert_eq!(agent.id(), "backend-agent");
32/// assert_eq!(agent.domain(), "backend");
33/// ```
34#[derive(Debug, Clone)]
35pub struct BackendAgent {
36    domain_agent: DomainAgent,
37}
38
39impl BackendAgent {
40    /// Create a new Backend Development Agent
41    ///
42    /// Initializes the agent with backend-specific capabilities and knowledge.
43    ///
44    /// # Returns
45    ///
46    /// A new `BackendAgent` instance
47    pub fn new() -> Self {
48        let capabilities = vec![
49            DomainCapability {
50                name: "API Design".to_string(),
51                description: "Recommendations for REST, GraphQL, or gRPC API design patterns"
52                    .to_string(),
53                technologies: vec!["REST".to_string(), "GraphQL".to_string(), "gRPC".to_string()],
54                patterns: vec![],
55            },
56            DomainCapability {
57                name: "Architecture Guidance".to_string(),
58                description:
59                    "Recommendations for microservices, monolithic, or serverless architectures"
60                        .to_string(),
61                technologies: vec![
62                    "Microservices".to_string(),
63                    "Monolithic".to_string(),
64                    "Serverless".to_string(),
65                ],
66                patterns: vec![],
67            },
68            DomainCapability {
69                name: "Database Design".to_string(),
70                description:
71                    "Recommendations for relational, NoSQL, or graph database selection and schema design"
72                        .to_string(),
73                technologies: vec![
74                    "PostgreSQL".to_string(),
75                    "MongoDB".to_string(),
76                    "Neo4j".to_string(),
77                ],
78                patterns: vec![],
79            },
80            DomainCapability {
81                name: "Scalability".to_string(),
82                description:
83                    "Recommendations for caching, load balancing, and horizontal scaling strategies"
84                        .to_string(),
85                technologies: vec![
86                    "Redis".to_string(),
87                    "Memcached".to_string(),
88                    "Load Balancers".to_string(),
89                ],
90                patterns: vec![],
91            },
92            DomainCapability {
93                name: "Security".to_string(),
94                description:
95                    "Recommendations for authentication, authorization, and data protection patterns"
96                        .to_string(),
97                technologies: vec![
98                    "OAuth 2.0".to_string(),
99                    "JWT".to_string(),
100                    "TLS".to_string(),
101                ],
102                patterns: vec![],
103            },
104            DomainCapability {
105                name: "Observability".to_string(),
106                description: "Recommendations for logging, metrics, and tracing implementation"
107                    .to_string(),
108                technologies: vec![
109                    "ELK Stack".to_string(),
110                    "Prometheus".to_string(),
111                    "Jaeger".to_string(),
112                ],
113                patterns: vec![],
114            },
115        ];
116
117        let knowledge = DomainKnowledge {
118            best_practices: vec![],
119            technology_recommendations: vec![
120                TechRecommendation {
121                    technology: "REST".to_string(),
122                    domain: "backend".to_string(),
123                    use_cases: vec![
124                        "Web APIs".to_string(),
125                        "Mobile backends".to_string(),
126                        "Simple CRUD operations".to_string(),
127                    ],
128                    pros: vec![
129                        "Simple and well-understood".to_string(),
130                        "Stateless design".to_string(),
131                        "Excellent caching support".to_string(),
132                    ],
133                    cons: vec![
134                        "Over-fetching and under-fetching".to_string(),
135                        "Versioning complexity".to_string(),
136                        "Multiple requests for related data".to_string(),
137                    ],
138                    alternatives: vec!["GraphQL".to_string(), "gRPC".to_string()],
139                },
140                TechRecommendation {
141                    technology: "GraphQL".to_string(),
142                    domain: "backend".to_string(),
143                    use_cases: vec![
144                        "Complex data queries".to_string(),
145                        "Mobile-first applications".to_string(),
146                        "Real-time data".to_string(),
147                    ],
148                    pros: vec![
149                        "Precise data fetching".to_string(),
150                        "Single endpoint".to_string(),
151                        "Strong typing".to_string(),
152                    ],
153                    cons: vec![
154                        "Steep learning curve".to_string(),
155                        "Query complexity".to_string(),
156                        "Caching challenges".to_string(),
157                    ],
158                    alternatives: vec!["REST".to_string(), "gRPC".to_string()],
159                },
160                TechRecommendation {
161                    technology: "gRPC".to_string(),
162                    domain: "backend".to_string(),
163                    use_cases: vec![
164                        "Microservices communication".to_string(),
165                        "High-performance systems".to_string(),
166                        "Real-time streaming".to_string(),
167                    ],
168                    pros: vec![
169                        "High performance".to_string(),
170                        "Streaming support".to_string(),
171                        "Language-agnostic".to_string(),
172                    ],
173                    cons: vec![
174                        "Steep learning curve".to_string(),
175                        "Browser support limitations".to_string(),
176                        "Debugging complexity".to_string(),
177                    ],
178                    alternatives: vec!["REST".to_string(), "GraphQL".to_string()],
179                },
180                TechRecommendation {
181                    technology: "PostgreSQL".to_string(),
182                    domain: "backend".to_string(),
183                    use_cases: vec![
184                        "Relational data".to_string(),
185                        "ACID transactions".to_string(),
186                        "Complex queries".to_string(),
187                    ],
188                    pros: vec![
189                        "Reliable".to_string(),
190                        "Feature-rich".to_string(),
191                        "Open source".to_string(),
192                    ],
193                    cons: vec![
194                        "Vertical scaling limitations".to_string(),
195                        "Complex setup".to_string(),
196                    ],
197                    alternatives: vec!["MySQL".to_string(), "MariaDB".to_string()],
198                },
199                TechRecommendation {
200                    technology: "MongoDB".to_string(),
201                    domain: "backend".to_string(),
202                    use_cases: vec![
203                        "Document storage".to_string(),
204                        "Flexible schema".to_string(),
205                        "Rapid development".to_string(),
206                    ],
207                    pros: vec![
208                        "Flexible schema".to_string(),
209                        "Horizontal scaling".to_string(),
210                        "Easy to use".to_string(),
211                    ],
212                    cons: vec![
213                        "No ACID transactions".to_string(),
214                        "Higher memory usage".to_string(),
215                    ],
216                    alternatives: vec!["CouchDB".to_string(), "Firebase".to_string()],
217                },
218                TechRecommendation {
219                    technology: "Neo4j".to_string(),
220                    domain: "backend".to_string(),
221                    use_cases: vec![
222                        "Graph data".to_string(),
223                        "Relationship queries".to_string(),
224                        "Recommendation engines".to_string(),
225                    ],
226                    pros: vec![
227                        "Powerful graph queries".to_string(),
228                        "Relationship performance".to_string(),
229                        "Intuitive modeling".to_string(),
230                    ],
231                    cons: vec![
232                        "Specialized use case".to_string(),
233                        "Smaller ecosystem".to_string(),
234                    ],
235                    alternatives: vec!["ArangoDB".to_string(), "TigerGraph".to_string()],
236                },
237                TechRecommendation {
238                    technology: "Redis".to_string(),
239                    domain: "backend".to_string(),
240                    use_cases: vec![
241                        "Caching".to_string(),
242                        "Session storage".to_string(),
243                        "Real-time analytics".to_string(),
244                    ],
245                    pros: vec![
246                        "Lightning fast".to_string(),
247                        "Versatile data structures".to_string(),
248                        "Pub/Sub support".to_string(),
249                    ],
250                    cons: vec![
251                        "In-memory only".to_string(),
252                        "Data persistence complexity".to_string(),
253                    ],
254                    alternatives: vec!["Memcached".to_string(), "Hazelcast".to_string()],
255                },
256                TechRecommendation {
257                    technology: "Memcached".to_string(),
258                    domain: "backend".to_string(),
259                    use_cases: vec![
260                        "Simple caching".to_string(),
261                        "Session storage".to_string(),
262                        "Object caching".to_string(),
263                    ],
264                    pros: vec![
265                        "Simple and lightweight".to_string(),
266                        "Fast".to_string(),
267                        "Distributed".to_string(),
268                    ],
269                    cons: vec![
270                        "Limited data structures".to_string(),
271                        "No persistence".to_string(),
272                    ],
273                    alternatives: vec!["Redis".to_string(), "Hazelcast".to_string()],
274                },
275                TechRecommendation {
276                    technology: "Microservices".to_string(),
277                    domain: "backend".to_string(),
278                    use_cases: vec![
279                        "Large applications".to_string(),
280                        "Independent scaling".to_string(),
281                        "Team autonomy".to_string(),
282                    ],
283                    pros: vec![
284                        "Independent scaling".to_string(),
285                        "Technology flexibility".to_string(),
286                        "Team autonomy".to_string(),
287                    ],
288                    cons: vec![
289                        "Operational complexity".to_string(),
290                        "Network latency".to_string(),
291                        "Data consistency challenges".to_string(),
292                    ],
293                    alternatives: vec!["Monolithic".to_string(), "Serverless".to_string()],
294                },
295                TechRecommendation {
296                    technology: "Monolithic".to_string(),
297                    domain: "backend".to_string(),
298                    use_cases: vec![
299                        "Small to medium applications".to_string(),
300                        "Simple deployments".to_string(),
301                        "Rapid development".to_string(),
302                    ],
303                    pros: vec![
304                        "Simple deployment".to_string(),
305                        "Easier debugging".to_string(),
306                        "Better performance".to_string(),
307                    ],
308                    cons: vec![
309                        "Scaling limitations".to_string(),
310                        "Technology lock-in".to_string(),
311                        "Deployment coupling".to_string(),
312                    ],
313                    alternatives: vec!["Microservices".to_string(), "Serverless".to_string()],
314                },
315                TechRecommendation {
316                    technology: "Serverless".to_string(),
317                    domain: "backend".to_string(),
318                    use_cases: vec![
319                        "Event-driven workloads".to_string(),
320                        "Sporadic traffic".to_string(),
321                        "Rapid prototyping".to_string(),
322                    ],
323                    pros: vec![
324                        "No infrastructure management".to_string(),
325                        "Auto-scaling".to_string(),
326                        "Pay-per-use".to_string(),
327                    ],
328                    cons: vec![
329                        "Cold start latency".to_string(),
330                        "Vendor lock-in".to_string(),
331                        "Debugging complexity".to_string(),
332                    ],
333                    alternatives: vec!["Microservices".to_string(), "Monolithic".to_string()],
334                },
335                TechRecommendation {
336                    technology: "OAuth 2.0".to_string(),
337                    domain: "backend".to_string(),
338                    use_cases: vec![
339                        "Third-party authentication".to_string(),
340                        "Delegated access".to_string(),
341                        "Social login".to_string(),
342                    ],
343                    pros: vec![
344                        "Industry standard".to_string(),
345                        "Secure delegation".to_string(),
346                        "Wide adoption".to_string(),
347                    ],
348                    cons: vec![
349                        "Complex implementation".to_string(),
350                        "Token management".to_string(),
351                    ],
352                    alternatives: vec!["OpenID Connect".to_string(), "SAML".to_string()],
353                },
354                TechRecommendation {
355                    technology: "JWT".to_string(),
356                    domain: "backend".to_string(),
357                    use_cases: vec![
358                        "Stateless authentication".to_string(),
359                        "API authentication".to_string(),
360                        "Token-based auth".to_string(),
361                    ],
362                    pros: vec![
363                        "Stateless".to_string(),
364                        "Self-contained".to_string(),
365                        "Cross-domain support".to_string(),
366                    ],
367                    cons: vec![
368                        "Token revocation challenges".to_string(),
369                        "Token size".to_string(),
370                    ],
371                    alternatives: vec!["Session tokens".to_string(), "OAuth 2.0".to_string()],
372                },
373                TechRecommendation {
374                    technology: "TLS".to_string(),
375                    domain: "backend".to_string(),
376                    use_cases: vec![
377                        "Secure communication".to_string(),
378                        "Data encryption".to_string(),
379                        "HTTPS".to_string(),
380                    ],
381                    pros: vec![
382                        "Industry standard".to_string(),
383                        "Wide support".to_string(),
384                        "Proven security".to_string(),
385                    ],
386                    cons: vec![
387                        "Performance overhead".to_string(),
388                        "Certificate management".to_string(),
389                    ],
390                    alternatives: vec!["SSL".to_string()],
391                },
392                TechRecommendation {
393                    technology: "ELK Stack".to_string(),
394                    domain: "backend".to_string(),
395                    use_cases: vec![
396                        "Log aggregation".to_string(),
397                        "Log analysis".to_string(),
398                        "Centralized logging".to_string(),
399                    ],
400                    pros: vec![
401                        "Powerful search".to_string(),
402                        "Real-time analysis".to_string(),
403                        "Open source".to_string(),
404                    ],
405                    cons: vec![
406                        "Resource intensive".to_string(),
407                        "Complex setup".to_string(),
408                    ],
409                    alternatives: vec!["Splunk".to_string(), "Datadog".to_string()],
410                },
411                TechRecommendation {
412                    technology: "Prometheus".to_string(),
413                    domain: "backend".to_string(),
414                    use_cases: vec![
415                        "Metrics collection".to_string(),
416                        "System monitoring".to_string(),
417                        "Alerting".to_string(),
418                    ],
419                    pros: vec![
420                        "Time-series database".to_string(),
421                        "Powerful queries".to_string(),
422                        "Open source".to_string(),
423                    ],
424                    cons: vec![
425                        "Pull-based model".to_string(),
426                        "Limited long-term storage".to_string(),
427                    ],
428                    alternatives: vec!["Grafana".to_string(), "InfluxDB".to_string()],
429                },
430                TechRecommendation {
431                    technology: "Jaeger".to_string(),
432                    domain: "backend".to_string(),
433                    use_cases: vec![
434                        "Distributed tracing".to_string(),
435                        "Request tracing".to_string(),
436                        "Performance analysis".to_string(),
437                    ],
438                    pros: vec![
439                        "Distributed tracing".to_string(),
440                        "OpenTelemetry support".to_string(),
441                        "Open source".to_string(),
442                    ],
443                    cons: vec![
444                        "Complex setup".to_string(),
445                        "Storage requirements".to_string(),
446                    ],
447                    alternatives: vec!["Zipkin".to_string(), "Datadog".to_string()],
448                },
449            ],
450            patterns: vec![],
451            anti_patterns: vec![],
452        };
453
454        let domain_agent = DomainAgent {
455            id: "backend-agent".to_string(),
456            domain: "backend".to_string(),
457            capabilities,
458            knowledge,
459        };
460
461        BackendAgent { domain_agent }
462    }
463
464    /// Get the domain of this agent
465    pub fn domain(&self) -> &str {
466        &self.domain_agent.domain
467    }
468
469    /// Get the capabilities of this agent
470    pub fn capabilities(&self) -> &[DomainCapability] {
471        &self.domain_agent.capabilities
472    }
473
474    /// Get the knowledge of this agent
475    pub fn knowledge(&self) -> &DomainKnowledge {
476        &self.domain_agent.knowledge
477    }
478
479    /// Get the underlying domain agent
480    pub fn domain_agent(&self) -> &DomainAgent {
481        &self.domain_agent
482    }
483}
484
485impl Default for BackendAgent {
486    fn default() -> Self {
487        Self::new()
488    }
489}
490
491#[async_trait]
492impl Agent for BackendAgent {
493    fn id(&self) -> &str {
494        &self.domain_agent.id
495    }
496
497    fn name(&self) -> &str {
498        "Backend Development Agent"
499    }
500
501    fn description(&self) -> &str {
502        "Specialized agent for backend development with expertise in API design, architecture, database design, scalability, security, and observability"
503    }
504
505    fn supports(&self, task_type: TaskType) -> bool {
506        // Backend agent supports code review and other backend-related tasks
507        matches!(
508            task_type,
509            TaskType::CodeReview
510                | TaskType::Refactoring
511                | TaskType::Documentation
512                | TaskType::SecurityAnalysis
513        )
514    }
515
516    async fn execute(&self, input: AgentInput) -> Result<AgentOutput> {
517        // For now, return a basic output
518        // This will be enhanced with actual backend-specific logic
519        let mut output = AgentOutput::default();
520
521        // Add findings based on the task type
522        match input.task.task_type {
523            TaskType::CodeReview => {
524                output.findings.push(Finding {
525                    id: Uuid::new_v4().to_string(),
526                    severity: Severity::Info,
527                    category: "backend-best-practices".to_string(),
528                    message: "Backend development best practices applied".to_string(),
529                    location: None,
530                    suggestion: None,
531                });
532            }
533            _ => {}
534        }
535
536        Ok(output)
537    }
538}
539
540#[cfg(test)]
541mod tests {
542    use super::*;
543
544    #[test]
545    fn test_backend_agent_creation() {
546        let agent = BackendAgent::new();
547        assert_eq!(agent.id(), "backend-agent");
548        assert_eq!(agent.domain(), "backend");
549        assert_eq!(agent.name(), "Backend Development Agent");
550    }
551
552    #[test]
553    fn test_backend_agent_capabilities() {
554        let agent = BackendAgent::new();
555        let capabilities = agent.capabilities();
556        assert_eq!(capabilities.len(), 6);
557
558        // Check first capability
559        assert_eq!(capabilities[0].name, "API Design");
560        assert_eq!(capabilities[0].technologies.len(), 3);
561        assert!(capabilities[0]
562            .technologies
563            .contains(&"REST".to_string()));
564        assert!(capabilities[0]
565            .technologies
566            .contains(&"GraphQL".to_string()));
567        assert!(capabilities[0]
568            .technologies
569            .contains(&"gRPC".to_string()));
570    }
571
572    #[test]
573    fn test_backend_agent_knowledge() {
574        let agent = BackendAgent::new();
575        let knowledge = agent.knowledge();
576        assert!(!knowledge.technology_recommendations.is_empty());
577        assert_eq!(knowledge.technology_recommendations.len(), 17);
578    }
579
580    #[test]
581    fn test_backend_agent_technology_recommendations() {
582        let agent = BackendAgent::new();
583        let knowledge = agent.knowledge();
584
585        // Check REST recommendation
586        let rest_rec = knowledge
587            .technology_recommendations
588            .iter()
589            .find(|r| r.technology == "REST")
590            .expect("REST recommendation not found");
591
592        assert_eq!(rest_rec.domain, "backend");
593        assert!(!rest_rec.use_cases.is_empty());
594        assert!(!rest_rec.pros.is_empty());
595        assert!(!rest_rec.cons.is_empty());
596        assert!(!rest_rec.alternatives.is_empty());
597    }
598
599    #[test]
600    fn test_backend_agent_supports_task_types() {
601        let agent = BackendAgent::new();
602        assert!(agent.supports(TaskType::CodeReview));
603        assert!(agent.supports(TaskType::Refactoring));
604        assert!(agent.supports(TaskType::Documentation));
605        assert!(agent.supports(TaskType::SecurityAnalysis));
606        assert!(!agent.supports(TaskType::TestGeneration));
607    }
608
609    #[test]
610    fn test_backend_agent_default() {
611        let agent1 = BackendAgent::new();
612        let agent2 = BackendAgent::default();
613        assert_eq!(agent1.id(), agent2.id());
614        assert_eq!(agent1.domain(), agent2.domain());
615    }
616
617    #[test]
618    fn test_backend_agent_clone() {
619        let agent1 = BackendAgent::new();
620        let agent2 = agent1.clone();
621        assert_eq!(agent1.id(), agent2.id());
622        assert_eq!(agent1.domain(), agent2.domain());
623        assert_eq!(agent1.capabilities().len(), agent2.capabilities().len());
624    }
625
626    #[test]
627    fn test_backend_agent_all_api_patterns_present() {
628        let agent = BackendAgent::new();
629        let knowledge = agent.knowledge();
630
631        let api_patterns = vec!["REST", "GraphQL", "gRPC"];
632        for pattern in api_patterns {
633            let found = knowledge
634                .technology_recommendations
635                .iter()
636                .any(|r| r.technology == pattern);
637            assert!(found, "API pattern {} not found in recommendations", pattern);
638        }
639    }
640
641    #[test]
642    fn test_backend_agent_all_databases_present() {
643        let agent = BackendAgent::new();
644        let knowledge = agent.knowledge();
645
646        let databases = vec!["PostgreSQL", "MongoDB", "Neo4j"];
647        for db in databases {
648            let found = knowledge
649                .technology_recommendations
650                .iter()
651                .any(|r| r.technology == db);
652            assert!(found, "Database {} not found in recommendations", db);
653        }
654    }
655
656    #[test]
657    fn test_backend_agent_all_architectures_present() {
658        let agent = BackendAgent::new();
659        let knowledge = agent.knowledge();
660
661        let architectures = vec!["Microservices", "Monolithic", "Serverless"];
662        for arch in architectures {
663            let found = knowledge
664                .technology_recommendations
665                .iter()
666                .any(|r| r.technology == arch);
667            assert!(found, "Architecture {} not found in recommendations", arch);
668        }
669    }
670
671    #[test]
672    fn test_backend_agent_all_caching_solutions_present() {
673        let agent = BackendAgent::new();
674        let knowledge = agent.knowledge();
675
676        let caching = vec!["Redis", "Memcached"];
677        for cache in caching {
678            let found = knowledge
679                .technology_recommendations
680                .iter()
681                .any(|r| r.technology == cache);
682            assert!(found, "Caching solution {} not found in recommendations", cache);
683        }
684    }
685
686    #[test]
687    fn test_backend_agent_all_security_technologies_present() {
688        let agent = BackendAgent::new();
689        let knowledge = agent.knowledge();
690
691        let security = vec!["OAuth 2.0", "JWT", "TLS"];
692        for tech in security {
693            let found = knowledge
694                .technology_recommendations
695                .iter()
696                .any(|r| r.technology == tech);
697            assert!(found, "Security technology {} not found in recommendations", tech);
698        }
699    }
700
701    #[test]
702    fn test_backend_agent_all_observability_tools_present() {
703        let agent = BackendAgent::new();
704        let knowledge = agent.knowledge();
705
706        let observability = vec!["ELK Stack", "Prometheus", "Jaeger"];
707        for tool in observability {
708            let found = knowledge
709                .technology_recommendations
710                .iter()
711                .any(|r| r.technology == tool);
712            assert!(found, "Observability tool {} not found in recommendations", tool);
713        }
714    }
715
716    #[test]
717    fn test_backend_agent_rest_alternatives() {
718        let agent = BackendAgent::new();
719        let knowledge = agent.knowledge();
720
721        let rest_rec = knowledge
722            .technology_recommendations
723            .iter()
724            .find(|r| r.technology == "REST")
725            .expect("REST recommendation not found");
726
727        assert!(rest_rec.alternatives.contains(&"GraphQL".to_string()));
728        assert!(rest_rec.alternatives.contains(&"gRPC".to_string()));
729    }
730
731    #[test]
732    fn test_backend_agent_postgresql_alternatives() {
733        let agent = BackendAgent::new();
734        let knowledge = agent.knowledge();
735
736        let pg_rec = knowledge
737            .technology_recommendations
738            .iter()
739            .find(|r| r.technology == "PostgreSQL")
740            .expect("PostgreSQL recommendation not found");
741
742        assert!(pg_rec.alternatives.contains(&"MySQL".to_string()));
743        assert!(pg_rec.alternatives.contains(&"MariaDB".to_string()));
744    }
745
746    #[test]
747    fn test_backend_agent_redis_alternatives() {
748        let agent = BackendAgent::new();
749        let knowledge = agent.knowledge();
750
751        let redis_rec = knowledge
752            .technology_recommendations
753            .iter()
754            .find(|r| r.technology == "Redis")
755            .expect("Redis recommendation not found");
756
757        assert!(redis_rec.alternatives.contains(&"Memcached".to_string()));
758        assert!(redis_rec.alternatives.contains(&"Hazelcast".to_string()));
759    }
760
761    #[tokio::test]
762    async fn test_backend_agent_execute() {
763        use crate::models::{
764            AgentConfig, AgentTask, ProjectContext, TaskOptions, TaskScope, TaskTarget,
765        };
766        use std::path::PathBuf;
767
768        let agent = BackendAgent::new();
769        let input = AgentInput {
770            task: AgentTask {
771                id: "task-1".to_string(),
772                task_type: TaskType::CodeReview,
773                target: TaskTarget {
774                    files: vec![PathBuf::from("api.rs")],
775                    scope: TaskScope::File,
776                },
777                options: TaskOptions::default(),
778            },
779            context: ProjectContext {
780                name: "backend-project".to_string(),
781                root: PathBuf::from("/tmp/backend-project"),
782            },
783            config: AgentConfig::default(),
784        };
785
786        let result = agent.execute(input).await;
787        assert!(result.is_ok());
788
789        let output = result.unwrap();
790        assert!(!output.findings.is_empty());
791    }
792}