Refactor code structure and remove redundant changes

This commit is contained in:
pacnpal
2025-08-26 13:19:04 -04:00
parent bf7e0c0f40
commit 831be6a2ee
151 changed files with 16260 additions and 9137 deletions

View File

@@ -0,0 +1,3 @@
"""
Accounts API module for user profile and top list management.
"""

View File

@@ -0,0 +1,18 @@
"""
Accounts API URL Configuration
"""
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
# Create router and register ViewSets
router = DefaultRouter()
router.register(r"profiles", views.UserProfileViewSet, basename="user-profile")
router.register(r"toplists", views.TopListViewSet, basename="top-list")
router.register(r"toplist-items", views.TopListItemViewSet, basename="top-list-item")
urlpatterns = [
# Include router URLs for ViewSets
path("", include(router.urls)),
]

View File

@@ -0,0 +1,204 @@
"""
Accounts API ViewSets for user profiles and top lists.
"""
from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth import get_user_model
from django.db.models import Q
from apps.accounts.models import UserProfile, TopList, TopListItem
from ..serializers import (
UserProfileCreateInputSerializer,
UserProfileUpdateInputSerializer,
UserProfileOutputSerializer,
TopListCreateInputSerializer,
TopListUpdateInputSerializer,
TopListOutputSerializer,
TopListItemCreateInputSerializer,
TopListItemUpdateInputSerializer,
TopListItemOutputSerializer,
)
User = get_user_model()
class UserProfileViewSet(ModelViewSet):
"""ViewSet for managing user profiles."""
queryset = UserProfile.objects.select_related("user").all()
permission_classes = [IsAuthenticated]
def get_serializer_class(self):
"""Return appropriate serializer based on action."""
if self.action == "create":
return UserProfileCreateInputSerializer
elif self.action in ["update", "partial_update"]:
return UserProfileUpdateInputSerializer
return UserProfileOutputSerializer
def get_queryset(self):
"""Filter profiles based on user permissions."""
if self.request.user.is_staff:
return self.queryset
return self.queryset.filter(user=self.request.user)
@action(detail=False, methods=["get"])
def me(self, request):
"""Get current user's profile."""
try:
profile = UserProfile.objects.get(user=request.user)
serializer = self.get_serializer(profile)
return Response(serializer.data)
except UserProfile.DoesNotExist:
return Response(
{"error": "Profile not found"}, status=status.HTTP_404_NOT_FOUND
)
class TopListViewSet(ModelViewSet):
"""ViewSet for managing user top lists."""
queryset = (
TopList.objects.select_related("user").prefetch_related("items__ride").all()
)
permission_classes = [IsAuthenticated]
def get_serializer_class(self):
"""Return appropriate serializer based on action."""
if self.action == "create":
return TopListCreateInputSerializer
elif self.action in ["update", "partial_update"]:
return TopListUpdateInputSerializer
return TopListOutputSerializer
def get_queryset(self):
"""Filter lists based on user permissions and visibility."""
queryset = self.queryset
if not self.request.user.is_staff:
# Non-staff users can only see their own lists and public lists
queryset = queryset.filter(Q(user=self.request.user) | Q(is_public=True))
return queryset.order_by("-created_at")
def perform_create(self, serializer):
"""Set the user when creating a top list."""
serializer.save(user=self.request.user)
@action(detail=False, methods=["get"])
def my_lists(self, request):
"""Get current user's top lists."""
lists = self.get_queryset().filter(user=request.user)
serializer = self.get_serializer(lists, many=True)
return Response(serializer.data)
@action(detail=True, methods=["post"])
def duplicate(self, request, pk=None):
"""Duplicate a top list for the current user."""
original_list = self.get_object()
# Create new list
new_list = TopList.objects.create(
user=request.user,
name=f"Copy of {original_list.name}",
description=original_list.description,
is_public=False, # Duplicated lists are private by default
)
# Copy all items
for item in original_list.items.all():
TopListItem.objects.create(
top_list=new_list,
ride=item.ride,
position=item.position,
notes=item.notes,
)
serializer = self.get_serializer(new_list)
return Response(serializer.data, status=status.HTTP_201_CREATED)
class TopListItemViewSet(ModelViewSet):
"""ViewSet for managing top list items."""
queryset = TopListItem.objects.select_related("top_list__user", "ride").all()
permission_classes = [IsAuthenticated]
def get_serializer_class(self):
"""Return appropriate serializer based on action."""
if self.action == "create":
return TopListItemCreateInputSerializer
elif self.action in ["update", "partial_update"]:
return TopListItemUpdateInputSerializer
return TopListItemOutputSerializer
def get_queryset(self):
"""Filter items based on user permissions."""
queryset = self.queryset
if not self.request.user.is_staff:
# Non-staff users can only see items from their own lists or public lists
queryset = queryset.filter(
Q(top_list__user=self.request.user) | Q(top_list__is_public=True)
)
return queryset.order_by("top_list_id", "position")
def perform_create(self, serializer):
"""Validate user can add items to the list."""
top_list = serializer.validated_data["top_list"]
if top_list.user != self.request.user and not self.request.user.is_staff:
raise PermissionError("You can only add items to your own lists")
serializer.save()
def perform_update(self, serializer):
"""Validate user can update items in the list."""
top_list = serializer.instance.top_list
if top_list.user != self.request.user and not self.request.user.is_staff:
raise PermissionError("You can only update items in your own lists")
serializer.save()
def perform_destroy(self, instance):
"""Validate user can delete items from the list."""
if (
instance.top_list.user != self.request.user
and not self.request.user.is_staff
):
raise PermissionError("You can only delete items from your own lists")
instance.delete()
@action(detail=False, methods=["post"])
def reorder(self, request):
"""Reorder items in a top list."""
top_list_id = request.data.get("top_list_id")
item_ids = request.data.get("item_ids", [])
if not top_list_id or not item_ids:
return Response(
{"error": "top_list_id and item_ids are required"},
status=status.HTTP_400_BAD_REQUEST,
)
try:
top_list = TopList.objects.get(id=top_list_id)
if top_list.user != request.user and not request.user.is_staff:
return Response(
{"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN
)
# Update positions
for position, item_id in enumerate(item_ids, 1):
TopListItem.objects.filter(id=item_id, top_list=top_list).update(
position=position
)
return Response({"success": True})
except TopList.DoesNotExist:
return Response(
{"error": "Top list not found"}, status=status.HTTP_404_NOT_FOUND
)