This commit is contained in:
2026-04-05 04:20:58 +03:30
parent df15d03d7c
commit ec8e72737b
6 changed files with 163 additions and 25 deletions
+59 -11
View File
@@ -1,14 +1,15 @@
from django.conf import settings
from drf_spectacular.utils import OpenApiParameter, OpenApiTypes, extend_schema
from rest_framework import serializers, status
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from drf_spectacular.utils import extend_schema
from config.swagger import code_response
from farm_hub.models import FarmHub
from .serializers import FarmNotificationSerializer
from .services import create_notification_for_farm_uuid, long_poll_notifications
from .services import long_poll_notifications, mark_notifications_as_read
class NotificationLongPollQuerySerializer(serializers.Serializer):
@@ -17,12 +18,15 @@ class NotificationLongPollQuerySerializer(serializers.Serializer):
timeout = serializers.IntegerField(required=False, min_value=0, max_value=60)
class ExternalNotificationCreateSerializer(serializers.Serializer):
class NotificationMarkReadSerializer(serializers.Serializer):
farm_uuid = serializers.UUIDField()
title = serializers.CharField(max_length=255)
message = serializers.CharField()
level = serializers.CharField(max_length=32, required=False, default="info")
metadata = serializers.JSONField(required=False)
slice_id = serializers.IntegerField(min_value=1)
def get_owned_farm(*, farm_uuid, user):
return FarmHub.objects.filter(farm_uuid=farm_uuid, owner=user).first()
class NotificationLongPollView(APIView):
@@ -41,10 +45,10 @@ class NotificationLongPollView(APIView):
serializer = NotificationLongPollQuerySerializer(data=request.query_params)
serializer.is_valid(raise_exception=True)
farm = FarmHub.objects.filter(
farm = get_owned_farm(
farm_uuid=serializer.validated_data["farm_uuid"],
owner=request.user,
).first()
user=request.user,
)
if farm is None:
return Response({"code": 404, "msg": "Farm not found."}, status=status.HTTP_404_NOT_FOUND)
@@ -65,3 +69,47 @@ class NotificationLongPollView(APIView):
return Response({"code": 200, "msg": "success", "data": data}, status=status.HTTP_200_OK)
class NotificationMarkReadView(APIView):
permission_classes = [IsAuthenticated]
@extend_schema(
tags=["Notifications"],
request=NotificationMarkReadSerializer,
responses={
200: code_response(
"NotificationMarkReadResponse",
extra_fields={"marked_count": serializers.IntegerField()},
),
404: code_response("NotificationMarkReadNotFoundResponse"),
503: code_response("NotificationMarkReadUnavailableResponse"),
},
)
def post(self, request):
serializer = NotificationMarkReadSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
farm = get_owned_farm(
farm_uuid=serializer.validated_data["farm_uuid"],
user=request.user,
)
if farm is None:
return Response({"code": 404, "msg": "Farm not found."}, status=status.HTTP_404_NOT_FOUND)
try:
marked_count = mark_notifications_as_read(
farm=farm,
slice_id=serializer.validated_data["slice_id"],
)
except ValueError as exc:
if str(exc) == "Notifications table is not migrated.":
return Response(
{"code": 503, "msg": "Notifications table is not ready. Run migrations."},
status=status.HTTP_503_SERVICE_UNAVAILABLE,
)
raise
return Response(
{"code": 200, "msg": "success", "marked_count": marked_count},
status=status.HTTP_200_OK,
)