| from datetime import datetime, timezone |
| from enum import Enum |
| from typing import Any |
|
|
| from pydantic import BaseModel, Field, HttpUrl |
|
|
|
|
| class Severity(str, Enum): |
| critical = "CRITICAL" |
| high = "HIGH" |
| medium = "MEDIUM" |
| low = "LOW" |
|
|
|
|
| class AuditRequest(BaseModel): |
| repo_url: HttpUrl |
|
|
|
|
| class SourceFile(BaseModel): |
| path: str |
| absolute_path: str |
| size_bytes: int |
| language: str | None = None |
|
|
|
|
| class CodeChunk(BaseModel): |
| file_path: str |
| language: str | None = None |
| line_start: int |
| line_end: int |
| content: str |
|
|
|
|
| class Finding(BaseModel): |
| title: str |
| severity: Severity |
| file_path: str |
| line_start: int = Field(ge=1) |
| line_end: int = Field(ge=1) |
| description: str |
| why_it_matters: str |
| suggested_fix: str |
| agent_source: str |
|
|
|
|
| class AgentOutput(BaseModel): |
| agent_name: str |
| findings: list[Finding] = Field(default_factory=list) |
| metadata: dict[str, Any] = Field(default_factory=dict) |
|
|
|
|
| class RepoScanResult(BaseModel): |
| repo_url: str |
| local_path: str |
| files: list[SourceFile] |
| skipped_files: int = 0 |
| warnings: list[str] = Field(default_factory=list) |
|
|
|
|
| class AuditReport(BaseModel): |
| repo_url: str |
| scanned_file_count: int |
| skipped_file_count: int |
| findings: list[Finding] |
| severity_summary: dict[Severity, int] |
| total_findings_count: int = 0 |
| displayed_findings_count: int = 0 |
| hidden_findings_count: int = 0 |
| agent_finding_counts: dict[str, int] = Field(default_factory=dict) |
| generated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) |
| agents_run: list[str] |
| warnings: list[str] = Field(default_factory=list) |
|
|
|
|
| class AuditProgress(BaseModel): |
| message: str |
| stage: str |
|
|