from django.db.models import Count, Q from rest_framework import viewsets from rest_framework.permissions import IsAuthenticated from rest_framework.decorators import action from rest_framework.request import Request from rest_framework.response import Response from .models import JobApplication, JobUpdate from .serializers import ( DashboardMetricsSerializer, JobApplicationSerializer, JobUpdateSerializer, ) class JobApplicationViewSet(viewsets.ModelViewSet): queryset = JobApplication.objects.all().prefetch_related("updates") serializer_class = JobApplicationSerializer permission_classes = [IsAuthenticated] class JobUpdateViewSet(viewsets.ModelViewSet): queryset = JobUpdate.objects.select_related("job_application").all() serializer_class = JobUpdateSerializer permission_classes = [IsAuthenticated] @action(detail=False, methods=["get"]) def latest(self, request: Request) -> Response: """Return the 3 most recent job updates with job info and metrics.""" updates = ( self.get_queryset() .select_related("job_application") .order_by("-created_at")[:3] ) serializer = self.get_serializer(updates, many=True) return Response(serializer.data) @action(detail=False, methods=["get"]) def metrics(self, request: Request) -> Response: """Return dashboard metrics: total apps, status breakdown, interview/offer counts.""" total = JobApplication.objects.count() status_counts = dict( JobApplication.objects.values("status") .annotate(count=Count("id")) .values_list("status", "count") ) interview_count = JobApplication.objects.filter( Q(status="INTERVIEW") | Q(status="OFFER") ).count() offer_count = JobApplication.objects.filter(status="OFFER").count() rejection_rate = ( round( status_counts.get("REJECTED", 0) / total * 100, 1 ) if total > 0 else 0.0 ) serializer = DashboardMetricsSerializer( instance={ "total_applications": total, "status_breakdown": status_counts, "interviews_count": interview_count, "offers_count": offer_count, "rejection_rate": rejection_rate, } ) return Response(serializer.data)