Corp/backend/communications/services/chat_notifications.py
lizerk 14f1e52425
Some checks failed
Deploy production / deploy (push) Failing after 4s
fix(messages): make HTTP authoritative for chat reads
2026-09-10 11:41:59 +03:00

72 lines
2.2 KiB
Python

from dataclasses import dataclass
from django.db import transaction
from django.db.models import Q
from django.utils import timezone
from communications.notifications.config import NotificationVerbs
from notifications.cache import invalidate_unread_summary
from notifications.models import Notification
from notifications.push_lifecycle import dismiss_chat_push
from notifications.realtime import send_notifications_read_all_event
@dataclass(frozen=True)
class ChatNotificationReadResult:
notification_ids: list[int]
count: int
class ChatNotificationReadService:
"""Use case for reading notifications related to a specific chat."""
chat_related_verbs = (
NotificationVerbs.NEW_MESSAGE,
NotificationVerbs.ANNOUNCEMENT,
NotificationVerbs.MENTION,
NotificationVerbs.REPLY,
NotificationVerbs.ADDED_TO_CHAT,
NotificationVerbs.COMMENTED,
)
def mark_chat_notifications_as_read(
self,
*,
user,
chat_id: int,
) -> ChatNotificationReadResult:
queryset = self._get_unread_queryset(user_id=user.id, chat_id=chat_id)
notification_ids = list(queryset.values_list("id", flat=True))
if not notification_ids:
return ChatNotificationReadResult(notification_ids=[], count=0)
read_at = timezone.now()
count = queryset.update(unread=False, timestamp_read=read_at)
invalidate_unread_summary(user.id)
def notify_after_commit():
invalidate_unread_summary(user.id)
send_notifications_read_all_event(user.id, notification_ids)
dismiss_chat_push(
user_id=user.id,
chat_id=chat_id,
notification_ids=notification_ids,
)
transaction.on_commit(notify_after_commit)
return ChatNotificationReadResult(
notification_ids=notification_ids,
count=count,
)
def _get_unread_queryset(self, *, user_id: int, chat_id: int):
return Notification.objects.filter(
Q(data__chat_id=chat_id) | Q(data__chat_id=str(chat_id)),
recipient_id=user_id,
unread=True,
deleted=False,
verb__in=self.chat_related_verbs,
)