from pydantic import BaseModel from datetime import datetime from typing import List, Optional class PredictionResponse(BaseModel): id: str original_image_url: str prediction_image_url: str overlay_image_url: str confidence_score: float predicted_area_percentage: float has_stroke: bool processing_time: float created_at: datetime doctor_expectation: Optional[bool] = None # Doctor's diagnosis: True=expects stroke, False=expects normal, None=not provided stroke_type: Optional[str] = None # Doctor's case type classification: "normal", "ischemia", "bleeding", or None class PaginationInfo(BaseModel): page: int limit: int total: int totalPages: int hasNext: bool hasPrev: bool class PredictionHistoryResponse(BaseModel): items: List[PredictionResponse] pagination: PaginationInfo class SystemInfo(BaseModel): model_loaded: bool device: str config_validation: bool mongodb_connected: bool cloudinary_configured: bool timestamp: datetime class HealthCheck(BaseModel): status: str model_loaded: bool device: str optional_services: dict timestamp: datetime class TrendData(BaseModel): """Trend data comparing current period to previous period""" total_predictions: Optional[float] = 0.0 stroke_detected: Optional[float] = 0.0 normal_cases: Optional[float] = 0.0 detection_rate: Optional[float] = 0.0 average_confidence: Optional[float] = 0.0 class DetailedAnalytics(BaseModel): """Detailed analytics metrics""" detection_accuracy: float = 0.0 detection_accuracy_trend: float = 0.0 average_processing_time: float = 0.0 processing_time_trend: float = 0.0 false_positive_rate: float = 0.0 false_positive_trend: float = 0.0 false_negative_rate: float = 0.0 false_negative_trend: float = 0.0 class PerformanceMetrics(BaseModel): """ML model performance metrics""" sensitivity: float = 0.0 # True Positive Rate specificity: float = 0.0 # True Negative Rate positive_predictive_value: float = 0.0 # Precision negative_predictive_value: float = 0.0 f1_score: float = 0.0 auc_roc: float = 0.0 class SystemHealth(BaseModel): """System health and performance metrics""" api_response_time_ms: float = 0.0 model_inference_time_s: float = 0.0 error_rate: float = 0.0 memory_usage_percent: float = 0.0 cpu_usage_percent: float = 0.0 storage_usage_percent: float = 0.0 uptime_percentage: float = 100.0 class StrokeTypeBreakdown(BaseModel): """Breakdown of cases by doctor-classified stroke type""" normal_count: int = 0 ischemia_count: int = 0 bleeding_count: int = 0 unclassified_count: int = 0 # Cases where doctor did not provide stroke_type normal_percentage: float = 0.0 ischemia_percentage: float = 0.0 bleeding_percentage: float = 0.0 class StrokeTypeAccuracy(BaseModel): """AI accuracy breakdown per stroke type category""" normal_accuracy: float = 0.0 # AI correctly predicted no stroke for doctor-classified normal ischemia_accuracy: float = 0.0 # AI correctly predicted stroke for doctor-classified ischemia bleeding_accuracy: float = 0.0 # AI correctly predicted stroke for doctor-classified bleeding class Statistics(BaseModel): # Core statistics total_predictions: int stroke_detected: int normal_cases: int stroke_detection_rate: float average_confidence: float # Stroke type breakdown (optional) stroke_type_breakdown: Optional[StrokeTypeBreakdown] = None # AI accuracy per stroke type (optional) stroke_type_accuracy: Optional[StrokeTypeAccuracy] = None # Trend data (optional) trends: Optional[TrendData] = None # Detailed analytics (optional) detailed_analytics: Optional[DetailedAnalytics] = None # Performance metrics (optional) performance_metrics: Optional[PerformanceMetrics] = None # System health (optional) system_health: Optional[SystemHealth] = None