From 8689283e991509eaa0387053805e9765797932a3 Mon Sep 17 00:00:00 2001 From: benya Date: Sun, 8 Mar 2026 12:27:54 +0300 Subject: [PATCH] fix: persist message delivery status across server restarts --- app/messages/repository.py | 5 +++++ app/messages/schemas.py | 1 + app/messages/service.py | 21 ++++++++++++++++++++- docs/api-reference.md | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/messages/repository.py b/app/messages/repository.py index b02a047..4c4bdb4 100644 --- a/app/messages/repository.py +++ b/app/messages/repository.py @@ -180,6 +180,11 @@ async def create_message_receipt( return receipt +async def list_chat_receipts(db: AsyncSession, *, chat_id: int) -> list[MessageReceipt]: + result = await db.execute(select(MessageReceipt).where(MessageReceipt.chat_id == chat_id)) + return list(result.scalars().all()) + + async def get_message_reaction(db: AsyncSession, *, message_id: int, user_id: int) -> MessageReaction | None: result = await db.execute( select(MessageReaction) diff --git a/app/messages/schemas.py b/app/messages/schemas.py index 3ee970d..ca9a71d 100644 --- a/app/messages/schemas.py +++ b/app/messages/schemas.py @@ -16,6 +16,7 @@ class MessageRead(BaseModel): forwarded_from_message_id: int | None type: MessageType text: str | None + delivery_status: Literal["sending", "sent", "delivered", "read"] | None = None created_at: datetime updated_at: datetime diff --git a/app/messages/service.py b/app/messages/service.py index 1aaa59f..4e286cd 100644 --- a/app/messages/service.py +++ b/app/messages/service.py @@ -107,7 +107,26 @@ async def get_messages( ) -> list[Message]: await ensure_chat_membership(db, chat_id=chat_id, user_id=user_id) safe_limit = max(1, min(limit, 100)) - return await repository.list_chat_messages(db, chat_id, user_id=user_id, limit=safe_limit, before_id=before_id) + messages = await repository.list_chat_messages(db, chat_id, user_id=user_id, limit=safe_limit, before_id=before_id) + if not messages: + return messages + receipts = await repository.list_chat_receipts(db, chat_id=chat_id) + other_receipts = [receipt for receipt in receipts if receipt.user_id != user_id] + if not other_receipts: + return messages + for message in messages: + if message.sender_id != user_id: + continue + is_read = any((receipt.last_read_message_id or 0) >= message.id for receipt in other_receipts) + if is_read: + setattr(message, "delivery_status", "read") + continue + is_delivered = any((receipt.last_delivered_message_id or 0) >= message.id for receipt in other_receipts) + if is_delivered: + setattr(message, "delivery_status", "delivered") + continue + setattr(message, "delivery_status", "sent") + return messages async def search_messages( diff --git a/docs/api-reference.md b/docs/api-reference.md index 2baae0c..88f8967 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -254,6 +254,7 @@ Rules: "forwarded_from_message_id": null, "type": "text", "text": "Hello", + "delivery_status": "read", "created_at": "2026-03-08T10:02:00Z", "updated_at": "2026-03-08T10:02:00Z" }