Coverage for src/alprina_cli/api/routes/insights.py: 47%

51 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2025-11-14 11:27 +0100

1""" 

2Insights API Routes 

3""" 

4from fastapi import APIRouter, HTTPException, Depends 

5from pydantic import BaseModel 

6from typing import List, Optional 

7from ...services.insights_service import InsightsService 

8from ..middleware.auth import get_current_user 

9 

10router = APIRouter(prefix="/insights", tags=["insights"]) 

11insights_service = InsightsService() 

12 

13 

14class WeeklySummaryResponse(BaseModel): 

15 """Weekly summary response model""" 

16 critical_findings: int 

17 high_findings: int 

18 total_scans: int 

19 total_vulnerabilities: int 

20 period: str 

21 

22 

23class MostScannedTargetResponse(BaseModel): 

24 """Most scanned target response model""" 

25 target: Optional[str] 

26 scan_count: Optional[int] 

27 

28 

29class SecurityTrendResponse(BaseModel): 

30 """Security trend response model""" 

31 trend: str # improving, declining, stable 

32 direction: str # up, down, none 

33 change_percentage: int 

34 message: str 

35 current_score: Optional[int] = None 

36 previous_score: Optional[int] = None 

37 

38 

39class RecommendationResponse(BaseModel): 

40 """Recommendation response model""" 

41 priority: str # critical, high, medium, low, info 

42 title: str 

43 description: str 

44 action: str 

45 action_url: str 

46 

47 

48class VulnerableTargetResponse(BaseModel): 

49 """Vulnerable target response model""" 

50 target: str 

51 critical: int 

52 high: int 

53 medium: int 

54 low: int 

55 total_vulnerabilities: int 

56 scan_count: int 

57 last_scan: Optional[str] 

58 

59 

60@router.get("/summary", response_model=WeeklySummaryResponse) 

61async def get_weekly_summary(user: dict = Depends(get_current_user)): 

62 """ 

63 Get weekly security summary for the authenticated user 

64 

65 Returns statistics for the last 7 days including: 

66 - Critical findings count 

67 - High severity findings count 

68 - Total scans performed 

69 - Total vulnerabilities found 

70 """ 

71 try: 

72 summary = insights_service.get_weekly_summary(user_id=user['id']) 

73 return summary 

74 

75 except Exception as e: 

76 raise HTTPException(status_code=500, detail=f"Error fetching weekly summary: {str(e)}") 

77 

78 

79@router.get("/most-scanned", response_model=MostScannedTargetResponse) 

80async def get_most_scanned_target( 

81 days: int = 30, 

82 user: dict = Depends(get_current_user) 

83): 

84 """ 

85 Get the most frequently scanned target 

86 

87 - **days**: Number of days to look back (default: 30) 

88 """ 

89 try: 

90 result = insights_service.get_most_scanned_target(user_id=user['id'], days=days) 

91 

92 if result is None: 

93 return {"target": None, "scan_count": None} 

94 

95 return result 

96 

97 except Exception as e: 

98 raise HTTPException(status_code=500, detail=f"Error fetching most scanned target: {str(e)}") 

99 

100 

101@router.get("/trend", response_model=SecurityTrendResponse) 

102async def get_security_trend(user: dict = Depends(get_current_user)): 

103 """ 

104 Get security trend analysis 

105 

106 Compares current week vs previous week to determine if security posture 

107 is improving, declining, or stable. 

108 """ 

109 try: 

110 trend = insights_service.get_security_trend(user_id=user['id']) 

111 return trend 

112 

113 except Exception as e: 

114 raise HTTPException(status_code=500, detail=f"Error calculating security trend: {str(e)}") 

115 

116 

117@router.get("/recommendations", response_model=List[RecommendationResponse]) 

118async def get_recommendations(user: dict = Depends(get_current_user)): 

119 """ 

120 Get personalized security recommendations 

121 

122 Returns actionable recommendations based on scan history, 

123 vulnerability patterns, and security posture. 

124 """ 

125 try: 

126 recommendations = insights_service.get_recommendations(user_id=user['id']) 

127 return recommendations 

128 

129 except Exception as e: 

130 raise HTTPException(status_code=500, detail=f"Error generating recommendations: {str(e)}") 

131 

132 

133@router.get("/vulnerable-targets", response_model=List[VulnerableTargetResponse]) 

134async def get_vulnerable_targets( 

135 limit: int = 5, 

136 user: dict = Depends(get_current_user) 

137): 

138 """ 

139 Get targets with the most vulnerabilities 

140 

141 - **limit**: Number of targets to return (default: 5) 

142 

143 Returns targets sorted by severity-weighted vulnerability count. 

144 """ 

145 try: 

146 targets = insights_service.get_top_vulnerable_targets(user_id=user['id'], limit=limit) 

147 return targets 

148 

149 except Exception as e: 

150 raise HTTPException(status_code=500, detail=f"Error fetching vulnerable targets: {str(e)}")