feat(f3): add reveal scoreboard and next-round transition
This commit is contained in:
@@ -499,6 +499,74 @@ def submit_guess(request: HttpRequest, code: str, round_question_id: int) -> Jso
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@require_GET
|
||||
@login_required
|
||||
def reveal_scoreboard(request: HttpRequest, code: str) -> JsonResponse:
|
||||
session_code = code.strip().upper()
|
||||
|
||||
try:
|
||||
session = GameSession.objects.get(code=session_code)
|
||||
except GameSession.DoesNotExist:
|
||||
return JsonResponse({"error": "Session not found"}, status=404)
|
||||
|
||||
if session.host_id != request.user.id:
|
||||
return JsonResponse({"error": "Only host can view scoreboard"}, status=403)
|
||||
|
||||
if session.status != GameSession.Status.REVEAL:
|
||||
return JsonResponse({"error": "Scoreboard is only available in reveal phase"}, status=400)
|
||||
|
||||
leaderboard = list(
|
||||
Player.objects.filter(session=session)
|
||||
.order_by("-score", "nickname")
|
||||
.values("id", "nickname", "score")
|
||||
)
|
||||
|
||||
return JsonResponse(
|
||||
{
|
||||
"session": {
|
||||
"code": session.code,
|
||||
"status": session.status,
|
||||
"current_round": session.current_round,
|
||||
},
|
||||
"leaderboard": leaderboard,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
def start_next_round(request: HttpRequest, code: str) -> JsonResponse:
|
||||
session_code = code.strip().upper()
|
||||
|
||||
try:
|
||||
session = GameSession.objects.get(code=session_code)
|
||||
except GameSession.DoesNotExist:
|
||||
return JsonResponse({"error": "Session not found"}, status=404)
|
||||
|
||||
if session.host_id != request.user.id:
|
||||
return JsonResponse({"error": "Only host can start next round"}, status=403)
|
||||
|
||||
with transaction.atomic():
|
||||
locked_session = GameSession.objects.select_for_update().get(pk=session.pk)
|
||||
if locked_session.status != GameSession.Status.REVEAL:
|
||||
return JsonResponse({"error": "Next round can only start from reveal phase"}, status=400)
|
||||
|
||||
locked_session.current_round += 1
|
||||
locked_session.status = GameSession.Status.LOBBY
|
||||
locked_session.save(update_fields=["current_round", "status"])
|
||||
|
||||
return JsonResponse(
|
||||
{
|
||||
"session": {
|
||||
"code": session.code,
|
||||
"status": GameSession.Status.LOBBY,
|
||||
"current_round": locked_session.current_round,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
def calculate_scores(request: HttpRequest, code: str, round_question_id: int) -> JsonResponse:
|
||||
|
||||
Reference in New Issue
Block a user