""" Pydantic schemas for Session API endpoints. """ from datetime import datetime from typing import List, Literal, Optional from pydantic import BaseModel, Field class UserAnswerInput(BaseModel): """Input schema for a single user answer.""" item_id: int = Field(..., description="Item/question ID") response: str = Field(..., min_length=1, max_length=10, description="User's answer (A, B, C, D)") time_spent: int = Field(default=0, ge=0, description="Time spent on this question (seconds)") class SessionCompleteRequest(BaseModel): """Request schema for completing a session.""" end_time: datetime = Field(..., description="Session end timestamp") user_answers: List[UserAnswerInput] = Field(..., description="List of user answers") class UserAnswerOutput(BaseModel): """Output schema for a single user answer.""" id: int item_id: int response: str is_correct: bool time_spent: int bobot_earned: float scoring_mode_used: str model_config = {"from_attributes": True} class SessionCompleteResponse(BaseModel): """Response schema for completed session with CTT scores.""" id: int session_id: str wp_user_id: str website_id: int tryout_id: str start_time: datetime end_time: Optional[datetime] is_completed: bool scoring_mode_used: str # CTT scores total_benar: int = Field(description="Total correct answers") total_bobot_earned: float = Field(description="Total weight earned") NM: Optional[int] = Field(description="Nilai Mentah (raw score) [0, 1000]") NN: Optional[int] = Field(description="Nilai Nasional (normalized score) [0, 1000]") # Normalization metadata rataan_used: Optional[float] = Field(description="Mean value used for normalization") sb_used: Optional[float] = Field(description="Standard deviation used for normalization") # User answers user_answers: List[UserAnswerOutput] model_config = {"from_attributes": True} class SessionCreateRequest(BaseModel): """Request schema for creating a new session.""" session_id: str = Field(..., description="Unique session identifier") wp_user_id: str = Field(..., description="WordPress user ID") website_id: int = Field(..., description="Website identifier") tryout_id: str = Field(..., description="Tryout identifier") scoring_mode: Literal["ctt", "irt", "hybrid"] = Field( default="ctt", description="Scoring mode for this session" ) class SessionResponse(BaseModel): """Response schema for session data.""" id: int session_id: str wp_user_id: str website_id: int tryout_id: str start_time: datetime end_time: Optional[datetime] is_completed: bool scoring_mode_used: str # CTT scores (populated after completion) total_benar: int total_bobot_earned: float NM: Optional[int] NN: Optional[int] # IRT scores (populated after completion) theta: Optional[float] theta_se: Optional[float] # Normalization metadata rataan_used: Optional[float] sb_used: Optional[float] model_config = {"from_attributes": True}