from datetime import datetime from pydantic import BaseModel from app.schemas.game import GameResponse, GameShort, PlaythroughInfo from app.schemas.challenge import ChallengeResponse class ProofFileResponse(BaseModel): """Информация о файле-доказательстве""" id: int file_type: str # image или video order_index: int created_at: datetime class Config: from_attributes = True class AssignmentBase(BaseModel): pass class CompleteAssignment(BaseModel): proof_url: str | None = None comment: str | None = None class BonusAssignmentResponse(BaseModel): """Ответ с информацией о бонусном челлендже""" id: int challenge: ChallengeResponse status: str # pending, completed proof_url: str | None = None proof_image_url: str | None = None # Legacy, for backward compatibility proof_files: list[ProofFileResponse] = [] # Multiple uploaded files proof_comment: str | None = None points_earned: int = 0 completed_at: datetime | None = None class Config: from_attributes = True class AssignmentResponse(BaseModel): id: int challenge: ChallengeResponse | None # None для playthrough game: GameShort | None = None # Заполняется для playthrough is_playthrough: bool = False playthrough_info: PlaythroughInfo | None = None # Заполняется для playthrough status: str proof_url: str | None = None proof_comment: str | None = None points_earned: int streak_at_completion: int | None = None started_at: datetime completed_at: datetime | None = None drop_penalty: int = 0 # Calculated penalty if dropped bonus_challenges: list[BonusAssignmentResponse] = [] # Для playthrough class Config: from_attributes = True class SpinResult(BaseModel): assignment_id: int game: GameResponse challenge: ChallengeResponse | None # None для playthrough is_playthrough: bool = False playthrough_info: PlaythroughInfo | None = None # Заполняется для playthrough bonus_challenges: list[ChallengeResponse] = [] # Для playthrough - список доступных бонусных челленджей can_drop: bool drop_penalty: int class CompleteResult(BaseModel): points_earned: int streak_bonus: int total_points: int new_streak: int class DropResult(BaseModel): penalty: int total_points: int new_drop_count: int class EventAssignmentResponse(BaseModel): """Response for event-specific assignment (Common Enemy)""" assignment: AssignmentResponse | None event_id: int | None challenge_id: int | None is_completed: bool class Config: from_attributes = True class CompleteBonusAssignment(BaseModel): """Запрос на завершение бонусного челленджа""" proof_url: str | None = None comment: str | None = None class BonusCompleteResult(BaseModel): """Результат завершения бонусного челленджа""" bonus_assignment_id: int points_earned: int total_bonus_points: int # Сумма очков за все бонусные челленджи class AvailableGamesCount(BaseModel): """Количество доступных игр для спина""" available: int total: int