Улучшение системы оспариваний и исправления

- Оспаривания теперь требуют решения админа после 24ч голосования
  - Можно повторно оспаривать после разрешённых споров
  - Исправлены бонусные очки при перепрохождении после оспаривания
  - Сброс серии при невалидном пруфе
  - Колесо показывает только доступные игры
  - Rate limiting только через backend (RATE_LIMIT_ENABLED)
This commit is contained in:
2025-12-29 22:23:34 +03:00
parent 1cedfeb3ee
commit 89dbe2c018
42 changed files with 5426 additions and 313 deletions

View File

@@ -1,8 +1,13 @@
from datetime import datetime
from typing import TYPE_CHECKING
from pydantic import BaseModel, Field
from app.schemas.user import UserPublic
from app.schemas.challenge import ChallengeResponse
from app.schemas.challenge import ChallengeResponse, GameShort
if TYPE_CHECKING:
from app.schemas.game import PlaythroughInfo
from app.schemas.assignment import BonusAssignmentResponse
class DisputeCreate(BaseModel):
@@ -63,7 +68,10 @@ class DisputeResponse(BaseModel):
class AssignmentDetailResponse(BaseModel):
"""Detailed assignment information with proofs and dispute"""
id: int
challenge: ChallengeResponse
challenge: ChallengeResponse | None # None for playthrough
game: GameShort | None = None # For playthrough
is_playthrough: bool = False
playthrough_info: dict | None = None # For playthrough (description, points, proof_type, proof_hint)
participant: UserPublic
status: str
proof_url: str | None # External URL (YouTube, etc.)
@@ -75,6 +83,7 @@ class AssignmentDetailResponse(BaseModel):
completed_at: datetime | None
can_dispute: bool # True if <24h since completion and not own assignment
dispute: DisputeResponse | None
bonus_challenges: list[dict] | None = None # For playthrough
class Config:
from_attributes = True
@@ -83,7 +92,11 @@ class AssignmentDetailResponse(BaseModel):
class ReturnedAssignmentResponse(BaseModel):
"""Returned assignment that needs to be redone"""
id: int
challenge: ChallengeResponse
challenge: ChallengeResponse | None = None # For challenge assignments
is_playthrough: bool = False
game_id: int | None = None # For playthrough assignments
game_title: str | None = None
game_cover_url: str | None = None
original_completed_at: datetime
dispute_reason: str