feat(phase2): Add achievements and replay systems
Achievement System:
- Add Achievement model with condition types (streak, steal, specialist, etc.)
- Add AchievementManager service for tracking and awarding achievements
- Add Pydantic schemas for achievements (AchievementResponse, PlayerStats, etc.)
- Seed 18 achievements from design doc
- Add GET /api/game/achievements endpoint
Replay System:
- Add ReplayManager service for saving/loading game replays
- Add GET /api/replay/{code} and /api/replay/session/{id} endpoints
- Format replays for frontend consumption
Phase 2 tasks completed:
- F2.1: Achievement model and migration
- F2.2: Pydantic schemas
- F2.3: AchievementManager service
- F2.4: ReplayManager service
- F2.5: API endpoints
- F2.6: Seed 18 achievements data
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
50
backend/app/schemas/achievement.py
Normal file
50
backend/app/schemas/achievement.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, List
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class AchievementBase(BaseModel):
|
||||
name: str
|
||||
description: str
|
||||
icon: str
|
||||
condition_type: str
|
||||
condition_value: int = 1
|
||||
category_id: Optional[int] = None
|
||||
|
||||
|
||||
class AchievementCreate(AchievementBase):
|
||||
pass
|
||||
|
||||
|
||||
class AchievementResponse(AchievementBase):
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class PlayerAchievement(BaseModel):
|
||||
"""Logro desbloqueado por un jugador (almacenado en localStorage)"""
|
||||
achievement_id: int
|
||||
unlocked_at: datetime
|
||||
game_session_id: Optional[int] = None
|
||||
|
||||
|
||||
class AchievementUnlock(BaseModel):
|
||||
"""Evento emitido cuando se desbloquea un logro"""
|
||||
player_name: str
|
||||
achievement: AchievementResponse
|
||||
unlocked_at: datetime
|
||||
|
||||
|
||||
class PlayerStats(BaseModel):
|
||||
"""Estadisticas de jugador para calculo de logros"""
|
||||
player_name: str
|
||||
current_streak: int = 0
|
||||
total_correct: int = 0
|
||||
total_steals: int = 0
|
||||
successful_steals: int = 0
|
||||
category_correct: dict[int, int] = {} # category_id -> count
|
||||
fastest_answer_seconds: Optional[float] = None
|
||||
questions_500_correct: int = 0
|
||||
Reference in New Issue
Block a user