File size: 2,755 Bytes
5949a90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84e6f45
 
 
 
5949a90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747e613
99375ed
5949a90
 
 
 
 
99375ed
5949a90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import os, sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from typing import List, Optional, Dict, Any
from datetime import datetime
from pydantic import BaseModel


class SourceDocument(BaseModel):
    institution: str
    document_title: str
    url: str
    date: Optional[str] = None
    credibility: str = "official_government"


class SearchResult(BaseModel):
    entity_id: str
    entity_type: str
    name: str
    state: Optional[str] = None
    party: Optional[str] = None
    risk_score: Optional[int] = None
    # BUG-12 FIX: risk_level was missing -- frontend Components.ResultCard renders
    # class="risk-badge risk-badge--${entity.risk_level}" so without this field
    # every badge was always risk-badge--undefined which rendered as LOW visually.
    risk_level: Optional[str] = None
    sources: List[SourceDocument] = []


class SearchResponse(BaseModel):
    query: str
    total: int
    results: List[SearchResult]
    generated_at: str


class RiskFactor(BaseModel):
    name: str
    score: float
    weight: float
    description: str
    evidence: List[str] = []


class RiskResponse(BaseModel):
    entity_id: str
    entity_name: str
    risk_score: int
    risk_level: str
    factors: List[RiskFactor]
    explanation: str
    sources: List[SourceDocument] = []
    generated_at: str


class GraphNode(BaseModel):
    id: str
    label: str
    name: str
    properties: Dict[str, Any] = {}


class GraphEdge(BaseModel):
    source: str
    target: str
    relationship: str
    properties: Dict[str, Any] = {}
    source_document: Optional[str] = None


class GraphResponse(BaseModel):
    entity_id: str
    depth: int
    nodes: List[GraphNode]
    edges: List[GraphEdge]
    generated_at: str


class ProfileSection(BaseModel):
    section: str
    data: List[Dict[str, Any]]
    sources: List[SourceDocument] = []


class ProfileResponse(BaseModel):
    """BUG-22 FIX: added sources field -- profile.py was returning it but model lacked it,
    causing Pydantic ValidationError silently on some entity types."""
    entity_id: str
    entity_type: str
    name: str
    overview: Dict[str, Any] = {}
    sections: List[ProfileSection] = []
    sources: List[SourceDocument] = []
    risk_score: Optional[int] = None
    generated_at: str


class HealthResponse(BaseModel):
    status: str
    neo4j_connected: bool
    version: str
    generated_at: str


class StatsResponse(BaseModel):
    nodes: Dict[str, int]
    relationships: Dict[str, int]
    last_pipeline_run: Optional[str]
    generated_at: str


class FeedItem(BaseModel):
    headline: str
    entity_names: List[str]
    risk_level: str
    source: str
    url: Optional[str]
    detected_at: str
    summary: str