Files
MathApp/notifications/serializers.py
Zareian c874c186b1 see the real client IP behind ArvanCloud, and mark all notifications read in one call
Production is ArvanCloud -> nginx -> gunicorn, but NUM_PROXIES was 1, so DRF
took ArvanCloud's edge IP as the client: every guest and every OTP request
behind one edge shared a single throttle bucket (20 guest sessions an hour for
everyone). Default is now 2, and /api/health reports clientIp so the proxy
count can be checked from outside.

PATCH /api/notifications/read-all replaces the frontend's one-PATCH-per-item
loop, which spent the shared "read" budget 75 requests at a time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 05:03:27 +03:30

32 lines
1.2 KiB
Python

from rest_framework import serializers
from .models import Notification
class NotificationItemSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
isRead = serializers.BooleanField(source='is_read')
# body و createdAt از ابتدا روی مدل بودند ولی در پاسخ نبودند، یعنی فرانت
# نه متنِ اعلان را داشت نه زمانش — و هر لیستِ اعلانی به هر دو نیاز دارد.
# هر دو فقط «اضافه» می‌شوند؛ هیچ فیلدی حذف یا تغییرِ نام نداده، پس
# کلاینتِ فعلی نمی‌شکند.
createdAt = serializers.DateTimeField(source='created_at', read_only=True)
class Meta:
model = Notification
fields = ['id', 'type', 'title', 'body', 'isRead', 'createdAt']
class NotificationListResponseSerializer(serializers.Serializer):
items = NotificationItemSerializer(many=True)
unreadCount = serializers.IntegerField()
class MarkReadResponseSerializer(serializers.Serializer):
success = serializers.BooleanField()
class MarkAllReadResponseSerializer(serializers.Serializer):
success = serializers.BooleanField()
updated = serializers.IntegerField()