Spaces:
Sleeping
Sleeping
| """ | |
| Type definitions for the AI PR Reviewer system | |
| """ | |
| from dataclasses import dataclass, field | |
| from enum import Enum | |
| from typing import Optional, List, Dict, Any | |
| from datetime import datetime | |
| class Verdict(str, Enum): | |
| """Review verdict types""" | |
| PASS = "PASS" | |
| PARTIAL = "PARTIAL" | |
| FAIL = "FAIL" | |
| NEEDS_REVIEW = "NEEDS_REVIEW" | |
| class RequirementStatus(str, Enum): | |
| """Status of a requirement in the PR""" | |
| PASS = "PASS" | |
| FAIL = "FAIL" | |
| PARTIAL = "PARTIAL" | |
| NOT_TESTABLE = "NOT_TESTABLE" | |
| class RiskLevel(str, Enum): | |
| """Risk severity levels""" | |
| CRITICAL = "CRITICAL" | |
| HIGH = "HIGH" | |
| MEDIUM = "MEDIUM" | |
| LOW = "LOW" | |
| INFO = "INFO" | |
| class RiskType(str, Enum): | |
| """Types of risks that can be detected""" | |
| SECURITY = "SECURITY" | |
| PERFORMANCE = "PERFORMANCE" | |
| EDGE_CASE = "EDGE_CASE" | |
| CODE_QUALITY = "CODE_QUALITY" | |
| TESTING = "TESTING" | |
| class JiraTicket: | |
| """Represents a Jira ticket""" | |
| key: str | |
| summary: str | |
| description: str | |
| issue_type: str | |
| status: str | |
| assignee: Optional[str] = None | |
| labels: List[str] = field(default_factory=list) | |
| components: List[str] = field(default_factory=list) | |
| raw_data: Dict[str, Any] = field(default_factory=dict) | |
| class Requirement: | |
| """Represents a single requirement extracted from Jira""" | |
| id: str | |
| text: str | |
| category: str | |
| priority: str | |
| acceptance_criteria: List[str] = field(default_factory=list) | |
| status: RequirementStatus = RequirementStatus.NOT_TESTABLE | |
| evidence: List[str] = field(default_factory=list) | |
| def to_dict(self) -> Dict[str, Any]: | |
| return { | |
| "id": self.id, | |
| "text": self.text, | |
| "category": self.category, | |
| "priority": self.priority, | |
| "acceptance_criteria": self.acceptance_criteria, | |
| "status": self.status.value, | |
| "evidence": self.evidence, | |
| } | |
| class CodeMapping: | |
| """Maps a requirement to specific code locations""" | |
| requirement_id: str | |
| file_path: str | |
| line_number: int | |
| code_snippet: str | |
| description: str | |
| def to_dict(self) -> Dict[str, Any]: | |
| return { | |
| "requirement_id": self.requirement_id, | |
| "file_path": self.file_path, | |
| "line_number": self.line_number, | |
| "code_snippet": self.code_snippet, | |
| "description": self.description, | |
| } | |
| class DiffFile: | |
| """Represents a file changed in the PR""" | |
| filename: str | |
| status: str # added, modified, deleted | |
| additions: int | |
| deletions: int | |
| patch: str | |
| old_content: Optional[str] = None | |
| new_content: Optional[str] = None | |
| class PRDiff: | |
| """Represents the PR diff""" | |
| pr_number: int | |
| title: str | |
| description: str | |
| author: str | |
| branch: str | |
| base_branch: str | |
| files_changed: List[DiffFile] = field(default_factory=list) | |
| commit_messages: List[str] = field(default_factory=list) | |
| def total_additions(self) -> int: | |
| return sum(f.additions for f in self.files_changed) | |
| def total_deletions(self) -> int: | |
| return sum(f.deletions for f in self.files_changed) | |
| class Risk: | |
| """Represents a detected risk""" | |
| type: RiskType | |
| level: RiskLevel | |
| title: str | |
| description: str | |
| file_path: Optional[str] = None | |
| line_number: Optional[int] = None | |
| suggestion: Optional[str] = None | |
| cwe_id: Optional[str] = None # Common Weakness Enumeration | |
| def to_dict(self) -> Dict[str, Any]: | |
| return { | |
| "type": self.type.value, | |
| "level": self.level.value, | |
| "title": self.title, | |
| "description": self.description, | |
| "file_path": self.file_path, | |
| "line_number": self.line_number, | |
| "suggestion": self.suggestion, | |
| "cwe_id": self.cwe_id, | |
| } | |
| class GeneratedTest: | |
| """Represents an AI-generated test""" | |
| name: str | |
| requirement_id: str | |
| test_code: str | |
| framework: str | |
| passed: Optional[bool] = None | |
| error: Optional[str] = None | |
| def to_dict(self) -> Dict[str, Any]: | |
| return { | |
| "name": self.name, | |
| "requirement_id": self.requirement_id, | |
| "test_code": self.test_code, | |
| "framework": self.framework, | |
| "passed": self.passed, | |
| "error": self.error, | |
| } | |
| class ReviewResult: | |
| """Final review result""" | |
| jira_ticket: JiraTicket | |
| pr_diff: PRDiff | |
| requirements: List[Requirement] = field(default_factory=list) | |
| code_mappings: List[CodeMapping] = field(default_factory=list) | |
| risks: List[Risk] = field(default_factory=list) | |
| generated_tests: List[GeneratedTest] = field(default_factory=list) | |
| verdict: Verdict = Verdict.NEEDS_REVIEW | |
| summary: str = "" | |
| suggestions: List[str] = field(default_factory=list) | |
| reviewed_at: datetime = field(default_factory=datetime.now) | |
| def passed_requirements(self) -> int: | |
| return sum(1 for r in self.requirements if r.status == RequirementStatus.PASS) | |
| def failed_requirements(self) -> int: | |
| return sum(1 for r in self.requirements if r.status == RequirementStatus.FAIL) | |
| def critical_risks(self) -> int: | |
| return sum(1 for r in self.risks if r.level == RiskLevel.CRITICAL) | |
| def to_dict(self) -> Dict[str, Any]: | |
| return { | |
| "jira_ticket": { | |
| "key": self.jira_ticket.key, | |
| "summary": self.jira_ticket.summary, | |
| "description": self.jira_ticket.description, | |
| }, | |
| "pr_diff": { | |
| "pr_number": self.pr_diff.pr_number, | |
| "title": self.pr_diff.title, | |
| "author": self.pr_diff.author, | |
| "files_changed": len(self.pr_diff.files_changed), | |
| }, | |
| "requirements": [r.to_dict() for r in self.requirements], | |
| "code_mappings": [c.to_dict() for c in self.code_mappings], | |
| "risks": [r.to_dict() for r in self.risks], | |
| "generated_tests": [t.to_dict() for t in self.generated_tests], | |
| "verdict": self.verdict.value, | |
| "summary": self.summary, | |
| "suggestions": self.suggestions, | |
| "reviewed_at": self.reviewed_at.isoformat(), | |
| "stats": { | |
| "passed_requirements": self.passed_requirements, | |
| "failed_requirements": self.failed_requirements, | |
| "critical_risks": self.critical_risks, | |
| "total_risks": len(self.risks), | |
| }, | |
| } | |