File size: 1,852 Bytes
4b445f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// ---------------------------------------------------------------------------
// Ninja Code Guard – shared TypeScript types
// Mirror the Pydantic models in app/models/findings.py
// ---------------------------------------------------------------------------

export type Severity = "critical" | "high" | "medium" | "low";
export type AgentKind = "security" | "performance" | "style";
export type Recommendation = "approve" | "request_changes" | "block";

/** A single finding produced by a domain agent. */
export interface Finding {
  agent: AgentKind;
  file_path: string;
  line_start: number;
  line_end: number;
  severity: Severity;
  category: string;
  title: string;
  description: string;
  suggested_fix: string;
  cwe_id: string | null;
  confidence: number; // 0.0 – 1.0
}

/** Final synthesized review output from the Synthesizer Agent. */
export interface SynthesizedReview {
  health_score: number; // 0 – 100
  executive_summary: string;
  recommendation: Recommendation;
  findings: Finding[];
  critical_count: number;
  high_count: number;
  medium_count: number;
  low_count: number;
  duration_ms: number;
}

/** Database record for a completed PR review. */
export interface PRReviewRecord {
  id: string; // UUID
  repo_full_name: string;
  pr_number: number;
  commit_sha: string;
  health_score: number; // 0 – 100
  critical_count: number;
  high_count: number;
  medium_count: number;
  low_count: number;
  summary: string;
  findings: Finding[];
  duration_ms: number;
  created_at?: string; // ISO date
}

/** Aggregate statistics for a repository. */
export interface RepoStats {
  repo_full_name: string;
  total_reviews: number;
  average_health_score: number;
  total_findings: number;
  recent_scores: number[]; // chronological, most-recent last
  top_categories: { category: string; count: number }[];
}