From 0f593e52e07eee508d21db5a893fda4e49df6a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A5=D0=B0=D0=BB=D0=B8=D0=BC=D0=BE=D0=B2=20=D0=A0=D1=83?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BC?= Date: Mon, 20 Apr 2026 10:44:07 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F,=20=D0=B1?= =?UTF-8?q?=D1=8D=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Abstractions/IMessageRepository.cs | 1 + .../Messages/GetMessages/GetMessagesQuery.cs | 9 +++++++-- .../Endpoints/MessagesEndpoints.cs | 12 ++++++++++-- .../Persistence/MessageRepository.cs | 18 ++++++++++++++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/backend/src/Contracts/Messaging/Application/Abstractions/IMessageRepository.cs b/backend/src/Contracts/Messaging/Application/Abstractions/IMessageRepository.cs index d032fba..f6f94fb 100644 --- a/backend/src/Contracts/Messaging/Application/Abstractions/IMessageRepository.cs +++ b/backend/src/Contracts/Messaging/Application/Abstractions/IMessageRepository.cs @@ -13,6 +13,7 @@ public interface IMessageRepository Task> GetChatMessagesCursorAsync(Guid chatId, DateTime? cursor, long? sequenceId, int limit, CancellationToken cancellationToken); Task> GetChatMessagesAroundAsync(Guid chatId, long sequenceId, int limit, CancellationToken cancellationToken); + Task> GetChatMessagesAfterAsync(Guid chatId, long sequenceId, int limit, CancellationToken cancellationToken); Task GetLastStoryMessageAsync(Guid chatId, Guid storyId, CancellationToken cancellationToken); Task UpdateAsync(Message message, CancellationToken cancellationToken); diff --git a/backend/src/Modules/Conversations/Application/Messages/GetMessages/GetMessagesQuery.cs b/backend/src/Modules/Conversations/Application/Messages/GetMessages/GetMessagesQuery.cs index 3e77abd..4fa6e9a 100644 --- a/backend/src/Modules/Conversations/Application/Messages/GetMessages/GetMessagesQuery.cs +++ b/backend/src/Modules/Conversations/Application/Messages/GetMessages/GetMessagesQuery.cs @@ -13,7 +13,7 @@ using MediatR; namespace Knot.Modules.Conversations.Application.Messages.GetMessages; -public record GetMessagesQuery(Guid UserId, Guid ChatId, string? Cursor, long? Pivot = null, int? Limit = null) : IQuery>; +public record GetMessagesQuery(Guid UserId, Guid ChatId, string? Cursor, long? Pivot = null, long? AfterSequenceId = null, int? Limit = null) : IQuery>; internal sealed class GetMessagesQueryHandler : IQueryHandler> { @@ -41,7 +41,12 @@ internal sealed class GetMessagesQueryHandler : IQueryHandler messages; int queryLimit = request.Limit ?? ChatConstants.DefaultMessageQueryLimit; - if (request.Pivot.HasValue) + if (request.AfterSequenceId.HasValue) + { + // Получаем только сообщения ПОСЛЕ указанного sequenceId (для синхронизации) + messages = await _messageRepository.GetChatMessagesAfterAsync(request.ChatId, request.AfterSequenceId.Value, queryLimit, cancellationToken); + } + else if (request.Pivot.HasValue) { messages = await _messageRepository.GetChatMessagesAroundAsync(request.ChatId, request.Pivot.Value, queryLimit, cancellationToken); } diff --git a/backend/src/Modules/Conversations/Presentation/Endpoints/MessagesEndpoints.cs b/backend/src/Modules/Conversations/Presentation/Endpoints/MessagesEndpoints.cs index 6e89b10..2196e66 100644 --- a/backend/src/Modules/Conversations/Presentation/Endpoints/MessagesEndpoints.cs +++ b/backend/src/Modules/Conversations/Presentation/Endpoints/MessagesEndpoints.cs @@ -19,9 +19,17 @@ public static class MessagesEndpoints { var group = app.MapGroup("api/messages").RequireAuthorization(); - group.MapGet("chat/{chatId:guid}", async ([FromRoute] Guid chatId, [FromQuery] string? cursor, ISender sender, IUserContext userContext, CancellationToken ct) => + group.MapGet("chat/{chatId:guid}", async ( + [FromRoute] Guid chatId, + [FromQuery] string? cursor, + [FromQuery] long? afterSequenceId, + [FromQuery] long? pivot, + [FromQuery] int? limit, + ISender sender, + IUserContext userContext, + CancellationToken ct) => { - var result = await sender.Send(new GetMessagesQuery(userContext.UserId, chatId, cursor), ct); + var result = await sender.Send(new GetMessagesQuery(userContext.UserId, chatId, cursor, pivot, afterSequenceId, limit), ct); return result.IsSuccess ? Results.Ok(result.Value) : Results.BadRequest(result.Error.Description); }); diff --git a/backend/src/Modules/Messaging/Infrastructure/Persistence/MessageRepository.cs b/backend/src/Modules/Messaging/Infrastructure/Persistence/MessageRepository.cs index 1ca31c7..396d7ec 100644 --- a/backend/src/Modules/Messaging/Infrastructure/Persistence/MessageRepository.cs +++ b/backend/src/Modules/Messaging/Infrastructure/Persistence/MessageRepository.cs @@ -95,14 +95,28 @@ public sealed class MessageRepository : IMessageRepository .ToListAsync(cancellationToken); } + public async Task> GetChatMessagesAfterAsync(Guid chatId, long sequenceId, int limit, CancellationToken cancellationToken) + { + var builder = Builders.Filter; + var filter = builder.And( + builder.Eq(m => m.ChatId, chatId), + builder.Gt(m => m.SequenceId, sequenceId) + ); + + return await _messages.Find(filter) + .SortBy(m => m.SequenceId) + .Limit(limit) + .ToListAsync(cancellationToken); + } + public async Task> GetChatMessagesAroundAsync(Guid chatId, long sequenceId, int limit, CancellationToken cancellationToken) { var builder = Builders.Filter; - + // Target message var targetFilter = builder.And(builder.Eq(m => m.ChatId, chatId), builder.Eq(m => m.SequenceId, sequenceId)); var targetMsg = await _messages.Find(targetFilter).FirstOrDefaultAsync(cancellationToken); - + // Older messages var olderFilter = builder.And(builder.Eq(m => m.ChatId, chatId), builder.Lt(m => m.SequenceId, sequenceId)); var older = await _messages.Find(olderFilter)