""" Pydantic Models for Request/Response """ from typing import Optional, Dict, Any, List from datetime import datetime from enum import Enum from pydantic import BaseModel, Field, validator class TaskStatus(str, Enum): """Task status enum""" PENDING = "pending" PROCESSING = "processing" COMPLETED = "completed" FAILED = "failed" class Level(int, Enum): """Public speaking level enum""" LEVEL_1 = 1 LEVEL_2 = 2 LEVEL_3 = 3 LEVEL_4 = 4 LEVEL_5 = 5 class VideoUploadRequest(BaseModel): """Video upload request model""" level: Level = Field(..., description="Public speaking level (1-5)") user_id: Optional[str] = Field(None, description="Optional user ID for tracking") class TaskCreateResponse(BaseModel): """Task creation response""" task_id: str = Field(..., description="Unique task identifier") status: TaskStatus = Field(default=TaskStatus.PENDING) message: str = Field(default="Task created successfully") created_at: datetime = Field(default_factory=datetime.utcnow) class TaskProgress(BaseModel): """Task progress information""" current_step: str = Field(..., description="Current processing step") percentage: float = Field(..., ge=0, le=100, description="Progress percentage") message: str = Field(..., description="Progress message") class IndicatorResult(BaseModel): """Individual indicator result""" score: Optional[float] = Field(None, description="Indicator score") raw_data: Dict[str, Any] = Field(default_factory=dict, description="Raw analysis data") detected: Optional[bool] = Field(None, description="Detection status (for boolean indicators)") class MainIndicators(BaseModel): """Main indicators for scoring""" tempo: Optional[IndicatorResult] = None artikulasi: Optional[IndicatorResult] = None kontak_mata: Optional[IndicatorResult] = None kesesuaian_topik: Optional[IndicatorResult] = None struktur_kalimat: Optional[IndicatorResult] = None class BonusIndicators(BaseModel): """Bonus indicators for additional points""" jeda: Optional[IndicatorResult] = None first_impression: Optional[IndicatorResult] = None face_expression: Optional[IndicatorResult] = None gesture: Optional[IndicatorResult] = None kata_pengisi: Optional[IndicatorResult] = None kata_tidak_senonoh: Optional[IndicatorResult] = None class VideoMetadata(BaseModel): """Video metadata information""" duration: float = Field(..., description="Video duration in seconds") fps: int = Field(..., description="Frames per second") resolution: str = Field(..., description="Video resolution (e.g., '1920x1080')") file_size: int = Field(..., description="File size in bytes") class AnalysisResult(BaseModel): """Complete analysis result - New clean format""" video_info: Dict[str, Any] = Field(..., description="Video information") analysis_results: Dict[str, Any] = Field(..., description="Analysis results for eye_contact, facial_expression, gesture") overall: Dict[str, Any] = Field(..., description="Overall summary with strengths and improvements") processing_time: float = Field(..., description="Total processing time in seconds") timestamp: datetime = Field(default_factory=datetime.utcnow) class TaskStatusResponse(BaseModel): """Task status response""" task_id: str status: TaskStatus progress: Optional[TaskProgress] = None result: Optional[AnalysisResult] = None error: Optional[str] = None created_at: datetime completed_at: Optional[datetime] = None class HealthResponse(BaseModel): """Health check response""" status: str = Field(default="healthy") version: str = Field(default="1.0.0") redis_connected: bool timestamp: datetime = Field(default_factory=datetime.utcnow) class ErrorResponse(BaseModel): """Error response model""" error: str = Field(..., description="Error message") detail: Optional[str] = Field(None, description="Detailed error information") timestamp: datetime = Field(default_factory=datetime.utcnow)