feat: Implement initial schema and add various API, service, and management command enhancements across the application.

This commit is contained in:
pacnpal
2026-01-01 15:13:01 -05:00
parent c95f99ca10
commit b243b17af7
413 changed files with 11164 additions and 17433 deletions

View File

@@ -1,6 +1,7 @@
"""
Leaderboard views for user rankings
"""
from datetime import timedelta
from django.db.models import Count, Sum
@@ -15,7 +16,7 @@ from apps.reviews.models import Review
from apps.rides.models import RideCredit
@api_view(['GET'])
@api_view(["GET"])
@permission_classes([AllowAny])
def leaderboard(request):
"""
@@ -26,25 +27,25 @@ def leaderboard(request):
- period: 'all' | 'monthly' | 'weekly' (default: all)
- limit: int (default: 25, max: 100)
"""
category = request.query_params.get('category', 'credits')
period = request.query_params.get('period', 'all')
limit = min(int(request.query_params.get('limit', 25)), 100)
category = request.query_params.get("category", "credits")
period = request.query_params.get("period", "all")
limit = min(int(request.query_params.get("limit", 25)), 100)
# Calculate date filter based on period
date_filter = None
if period == 'weekly':
if period == "weekly":
date_filter = timezone.now() - timedelta(days=7)
elif period == 'monthly':
elif period == "monthly":
date_filter = timezone.now() - timedelta(days=30)
if category == 'credits':
if category == "credits":
return _get_credits_leaderboard(date_filter, limit)
elif category == 'reviews':
elif category == "reviews":
return _get_reviews_leaderboard(date_filter, limit)
elif category == 'contributions':
elif category == "contributions":
return _get_contributions_leaderboard(date_filter, limit)
else:
return Response({'error': 'Invalid category'}, status=400)
return Response({"detail": "Invalid category"}, status=400)
def _get_credits_leaderboard(date_filter, limit):
@@ -55,26 +56,34 @@ def _get_credits_leaderboard(date_filter, limit):
queryset = queryset.filter(created_at__gte=date_filter)
# Aggregate credits per user
users_data = queryset.values('user_id', 'user__username', 'user__display_name').annotate(
total_credits=Coalesce(Sum('count'), 0),
unique_rides=Count('ride', distinct=True),
).order_by('-total_credits')[:limit]
users_data = (
queryset.values("user_id", "user__username", "user__display_name")
.annotate(
total_credits=Coalesce(Sum("count"), 0),
unique_rides=Count("ride", distinct=True),
)
.order_by("-total_credits")[:limit]
)
results = []
for rank, entry in enumerate(users_data, 1):
results.append({
'rank': rank,
'user_id': entry['user_id'],
'username': entry['user__username'],
'display_name': entry['user__display_name'] or entry['user__username'],
'total_credits': entry['total_credits'],
'unique_rides': entry['unique_rides'],
})
results.append(
{
"rank": rank,
"user_id": entry["user_id"],
"username": entry["user__username"],
"display_name": entry["user__display_name"] or entry["user__username"],
"total_credits": entry["total_credits"],
"unique_rides": entry["unique_rides"],
}
)
return Response({
'category': 'credits',
'results': results,
})
return Response(
{
"category": "credits",
"results": results,
}
)
def _get_reviews_leaderboard(date_filter, limit):
@@ -85,49 +94,65 @@ def _get_reviews_leaderboard(date_filter, limit):
queryset = queryset.filter(created_at__gte=date_filter)
# Count reviews per user
users_data = queryset.values('user_id', 'user__username', 'user__display_name').annotate(
review_count=Count('id'),
).order_by('-review_count')[:limit]
users_data = (
queryset.values("user_id", "user__username", "user__display_name")
.annotate(
review_count=Count("id"),
)
.order_by("-review_count")[:limit]
)
results = []
for rank, entry in enumerate(users_data, 1):
results.append({
'rank': rank,
'user_id': entry['user_id'],
'username': entry['user__username'],
'display_name': entry['user__display_name'] or entry['user__username'],
'review_count': entry['review_count'],
})
results.append(
{
"rank": rank,
"user_id": entry["user_id"],
"username": entry["user__username"],
"display_name": entry["user__display_name"] or entry["user__username"],
"review_count": entry["review_count"],
}
)
return Response({
'category': 'reviews',
'results': results,
})
return Response(
{
"category": "reviews",
"results": results,
}
)
def _get_contributions_leaderboard(date_filter, limit):
"""Top users by approved contributions."""
queryset = EditSubmission.objects.filter(status='approved')
queryset = EditSubmission.objects.filter(status="approved")
if date_filter:
queryset = queryset.filter(created_at__gte=date_filter)
# Count contributions per user
users_data = queryset.values('submitted_by_id', 'submitted_by__username', 'submitted_by__display_name').annotate(
contribution_count=Count('id'),
).order_by('-contribution_count')[:limit]
users_data = (
queryset.values("submitted_by_id", "submitted_by__username", "submitted_by__display_name")
.annotate(
contribution_count=Count("id"),
)
.order_by("-contribution_count")[:limit]
)
results = []
for rank, entry in enumerate(users_data, 1):
results.append({
'rank': rank,
'user_id': entry['submitted_by_id'],
'username': entry['submitted_by__username'],
'display_name': entry['submitted_by__display_name'] or entry['submitted_by__username'],
'contribution_count': entry['contribution_count'],
})
results.append(
{
"rank": rank,
"user_id": entry["submitted_by_id"],
"username": entry["submitted_by__username"],
"display_name": entry["submitted_by__display_name"] or entry["submitted_by__username"],
"contribution_count": entry["contribution_count"],
}
)
return Response({
'category': 'contributions',
'results': results,
})
return Response(
{
"category": "contributions",
"results": results,
}
)