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>
This commit is contained in:
@@ -146,3 +146,29 @@ class NotificationPayloadShapeTests(TestCase):
|
||||
r = self.client.get('/api/notifications', HTTP_AUTHORIZATION=f'Bearer {self.token}')
|
||||
|
||||
self.assertEqual(r.data['items'][0]['body'], '')
|
||||
|
||||
|
||||
class MarkAllReadTests(TestCase):
|
||||
"""دکمهی «همه خوانده شد» با یک درخواست، نه یکی برای هر اعلان."""
|
||||
|
||||
def setUp(self):
|
||||
from django.core.cache import cache
|
||||
cache.clear()
|
||||
from accounts.authentication import issue_access_token
|
||||
from accounts.models import User
|
||||
self.me = User.objects.create(phone='09120000021')
|
||||
self.other = User.objects.create(phone='09120000022')
|
||||
self.auth = {'HTTP_AUTHORIZATION': f'Bearer {issue_access_token(self.me.id)}'}
|
||||
for user in (self.me, self.me, self.other):
|
||||
Notification.objects.create(user_id=user.id, type='xp_earned', title='x')
|
||||
|
||||
def test_marks_only_my_unread_notifications(self):
|
||||
response = self.client.patch('/api/notifications/read-all', **self.auth)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(), {'success': True, 'updated': 2})
|
||||
self.assertFalse(Notification.objects.filter(user_id=self.me.id, is_read=False).exists())
|
||||
self.assertTrue(Notification.objects.filter(user_id=self.other.id, is_read=False).exists())
|
||||
|
||||
def test_requires_sign_in(self):
|
||||
self.assertEqual(self.client.patch('/api/notifications/read-all').status_code, 401)
|
||||
|
||||
Reference in New Issue
Block a user