|
|
|
@@ -32,9 +32,11 @@ def list_puzzles(request):
|
|
|
|
|
@paginate
|
|
|
|
|
def list_submissions(request):
|
|
|
|
|
"""Get paginated list of submissions"""
|
|
|
|
|
return Submission.objects.prefetch_related(
|
|
|
|
|
"responses__files", "responses__puzzle"
|
|
|
|
|
).filter(user=request.user)
|
|
|
|
|
return (
|
|
|
|
|
Submission.objects.prefetch_related("responses__files", "responses__puzzle")
|
|
|
|
|
.filter(user=request.user)
|
|
|
|
|
.filter()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/submissions/{submission_id}", response=SubmissionOut)
|
|
|
|
@@ -172,27 +174,29 @@ def validate_response(request, response_id: int, data: ValidationIn):
|
|
|
|
|
if not request.user.is_authenticated or not request.user.is_staff:
|
|
|
|
|
return 403, {"detail": "Admin access required"}
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
response = PuzzleResponse.objects.select_related("puzzle").get(id=response_id)
|
|
|
|
|
response = get_object_or_404(PuzzleResponse, id=response_id)
|
|
|
|
|
|
|
|
|
|
# Update validated values
|
|
|
|
|
if data.validated_cost is not None:
|
|
|
|
|
response.validated_cost = data.validated_cost
|
|
|
|
|
if data.validated_cycles is not None:
|
|
|
|
|
response.validated_cycles = data.validated_cycles
|
|
|
|
|
if data.validated_area is not None:
|
|
|
|
|
response.validated_area = data.validated_area
|
|
|
|
|
if data.puzzle is not None:
|
|
|
|
|
puzzle = get_object_or_404(SteamCollectionItem, id=data.puzzle)
|
|
|
|
|
response.puzzle = puzzle
|
|
|
|
|
|
|
|
|
|
# Mark as no longer needing validation if we have all values
|
|
|
|
|
if all([response.final_cost, response.final_cycles, response.final_area]):
|
|
|
|
|
response.needs_manual_validation = False
|
|
|
|
|
# Update validated values
|
|
|
|
|
if data.validated_cost is not None:
|
|
|
|
|
response.validated_cost = data.validated_cost
|
|
|
|
|
|
|
|
|
|
response.save()
|
|
|
|
|
if data.validated_cycles is not None:
|
|
|
|
|
response.validated_cycles = data.validated_cycles
|
|
|
|
|
|
|
|
|
|
return response
|
|
|
|
|
if data.validated_area is not None:
|
|
|
|
|
response.validated_area = data.validated_area
|
|
|
|
|
|
|
|
|
|
except PuzzleResponse.DoesNotExist:
|
|
|
|
|
raise Http404("Response not found")
|
|
|
|
|
# Mark as no longer needing validation if we have all values
|
|
|
|
|
if all([response.final_cost, response.final_cycles, response.final_area]):
|
|
|
|
|
response.needs_manual_validation = False
|
|
|
|
|
|
|
|
|
|
response.save()
|
|
|
|
|
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/responses/needs-validation", response=List[PuzzleResponseOut])
|
|
|
|
@@ -204,6 +208,7 @@ def list_responses_needing_validation(request):
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
PuzzleResponse.objects.filter(needs_manual_validation=True)
|
|
|
|
|
.filter(puzzle__collection__is_active=True)
|
|
|
|
|
.select_related("puzzle", "submission")
|
|
|
|
|
.prefetch_related("files")
|
|
|
|
|
)
|
|
|
|
@@ -216,26 +221,22 @@ def validate_submission(request, submission_id: str):
|
|
|
|
|
if not request.user.is_authenticated or not request.user.is_staff:
|
|
|
|
|
return 403, {"detail": "Admin access required"}
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
submission = Submission.objects.get(id=submission_id)
|
|
|
|
|
submission = get_object_or_404(Submission, id=submission_id)
|
|
|
|
|
|
|
|
|
|
submission.is_validated = True
|
|
|
|
|
submission.validated_by = request.user
|
|
|
|
|
submission.validated_at = timezone.now()
|
|
|
|
|
submission.save()
|
|
|
|
|
submission.is_validated = True
|
|
|
|
|
submission.validated_by = request.user
|
|
|
|
|
submission.validated_at = timezone.now()
|
|
|
|
|
submission.save()
|
|
|
|
|
|
|
|
|
|
# Also mark all responses as not needing validation
|
|
|
|
|
submission.responses.update(needs_manual_validation=False)
|
|
|
|
|
# Also mark all responses as not needing validation
|
|
|
|
|
submission.responses.update(needs_manual_validation=False)
|
|
|
|
|
|
|
|
|
|
# Reload with relations
|
|
|
|
|
submission = Submission.objects.prefetch_related(
|
|
|
|
|
"responses__files", "responses__puzzle"
|
|
|
|
|
).get(id=submission.id)
|
|
|
|
|
# Reload with relations
|
|
|
|
|
submission = Submission.objects.prefetch_related(
|
|
|
|
|
"responses__files", "responses__puzzle"
|
|
|
|
|
).get(id=submission.id)
|
|
|
|
|
|
|
|
|
|
return submission
|
|
|
|
|
|
|
|
|
|
except Submission.DoesNotExist:
|
|
|
|
|
raise Http404("Submission not found")
|
|
|
|
|
return submission
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.delete("/submissions/{submission_id}")
|
|
|
|
@@ -245,13 +246,9 @@ def delete_submission(request, submission_id: str):
|
|
|
|
|
if not request.user.is_authenticated or not request.user.is_staff:
|
|
|
|
|
return 403, {"detail": "Admin access required"}
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
submission = Submission.objects.get(id=submission_id)
|
|
|
|
|
submission.delete()
|
|
|
|
|
return {"detail": "Submission deleted successfully"}
|
|
|
|
|
|
|
|
|
|
except Submission.DoesNotExist:
|
|
|
|
|
raise Http404("Submission not found")
|
|
|
|
|
submission = get_object_or_404(Submission, id=submission_id)
|
|
|
|
|
submission.delete()
|
|
|
|
|
return {"detail": "Submission deleted successfully"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/stats")
|
|
|
|
@@ -270,7 +267,7 @@ def get_stats(request):
|
|
|
|
|
"total_responses": total_responses,
|
|
|
|
|
"needs_validation": needs_validation,
|
|
|
|
|
"validated_submissions": validated_submissions,
|
|
|
|
|
"validation_rate": validated_submissions / total_submissions
|
|
|
|
|
if total_submissions > 0
|
|
|
|
|
"validation_rate": (total_responses - needs_validation) / total_responses
|
|
|
|
|
if total_responses
|
|
|
|
|
else 0,
|
|
|
|
|
}
|
|
|
|
|