from rest_framework import generics, status from rest_framework.response import Response from rest_framework.authentication import TokenAuthentication from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from rest_framework.permissions import IsAuthenticated from rest_framework.viewsets import ModelViewSet from apps.account.serializers import ( NotificationSerializer, NotificationSendSerializer, AdminNotificationSerializer, NotificationTemplateSerializer ) from apps.account.models import Notification, User, NotificationTemplate from apps.account.tasks import send_notification_task from utils.pagination import StandardResultsSetPagination from apps.account.permissions import IsSuperAdmin import logging logger = logging.getLogger(__name__) class NotificationListView(generics.ListAPIView): serializer_class = NotificationSerializer permission_classes = [IsAuthenticated] authentication_classes = [TokenAuthentication] pagination_class = StandardResultsSetPagination @swagger_auto_schema( operation_description="Retrieve a list of notifications for the authenticated user.", tags=['Notifications'], ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def get_queryset(self): return Notification.objects.filter(user=self.request.user).order_by('-created_at') class NotificationReadAllView(generics.GenericAPIView): permission_classes = [IsAuthenticated] authentication_classes = [TokenAuthentication] @swagger_auto_schema( operation_description="Mark all notifications as read for the authenticated user.", tags=['Notifications'], responses={200: "All notifications marked as read"} ) def post(self, request, *args, **kwargs): Notification.objects.filter(user=request.user, is_read=False).update(is_read=True) return Response({'status': 'all notifications marked as read'}, status=status.HTTP_200_OK) class SendNotificationView(generics.GenericAPIView): permission_classes = [IsAuthenticated] authentication_classes = [TokenAuthentication] @swagger_auto_schema( operation_description="Dispatch an in-app notification to a specific user.", tags=['Notifications'], request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=['user_id', 'title', 'body'], properties={ 'user_id': openapi.Schema(type=openapi.TYPE_INTEGER, description='Target User ID'), 'title': openapi.Schema(type=openapi.TYPE_STRING, description='Notification title'), 'body': openapi.Schema(type=openapi.TYPE_STRING, description='Notification body'), 'data': openapi.Schema(type=openapi.TYPE_OBJECT, description='Extra payload data'), }, ), responses={ 200: openapi.Response('Notification dispatched.'), 404: openapi.Response('User not found.'), } ) def post(self, request, *args, **kwargs): user_id = request.data.get('user_id') title = request.data.get('title') body = request.data.get('body') data = request.data.get('data', {}) if not User.objects.filter(id=user_id).exists(): return Response({'error': 'User not found.'}, status=status.HTTP_404_NOT_FOUND) send_notification_task.delay(user_id=user_id, title=title, body=body, data=data) return Response({'status': 'notification queued'}, status=status.HTTP_200_OK) class AdminNotificationViewSet(ModelViewSet): queryset = Notification.objects.all().select_related('user') serializer_class = AdminNotificationSerializer permission_classes = [IsAuthenticated, IsSuperAdmin] authentication_classes = [TokenAuthentication] pagination_class = StandardResultsSetPagination class AdminNotificationTemplateViewSet(ModelViewSet): queryset = NotificationTemplate.objects.all() serializer_class = NotificationTemplateSerializer permission_classes = [IsAuthenticated, IsSuperAdmin] authentication_classes = [TokenAuthentication] pagination_class = StandardResultsSetPagination