Импорт

This commit is contained in:
Халимов Рустам
2026-04-06 22:20:13 +03:00
parent fa185afc73
commit 1558b20470
317 changed files with 18311 additions and 924 deletions
@@ -1,12 +1,13 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Knot.Shared.Kernel;
using Knot.Modules.Conversations.Domain;
using Knot.Modules.Conversations.Application.Abstractions;
using Knot.Contracts.Conversations.Domain;
using Knot.Contracts.Conversations.Application.Abstractions;
using MediatR;
using System.Linq;
using Knot.Contracts.Messaging.Application.Abstractions;
using Knot.Shared.Kernel.Storage;
namespace Knot.Modules.Conversations.Application.Chats.LeaveOrDelete;
@@ -15,11 +16,19 @@ public record LeaveOrDeleteChatCommand(Guid ChatId, Guid UserId) : ICommand<Succ
internal sealed class LeaveOrDeleteChatCommandHandler : ICommandHandler<LeaveOrDeleteChatCommand, SuccessResponse>
{
private readonly IChatRepository _chatRepository;
private readonly IMessageRepository _messageRepository;
private readonly IFileStorageService _fileStorage;
private readonly IChatsUnitOfWork _uow;
public LeaveOrDeleteChatCommandHandler(IChatRepository chatRepository, IChatsUnitOfWork uow)
public LeaveOrDeleteChatCommandHandler(
IChatRepository chatRepository,
IMessageRepository messageRepository,
IFileStorageService fileStorage,
IChatsUnitOfWork uow)
{
_chatRepository = chatRepository;
_messageRepository = messageRepository;
_fileStorage = fileStorage;
_uow = uow;
}
@@ -36,13 +45,18 @@ internal sealed class LeaveOrDeleteChatCommandHandler : ICommandHandler<LeaveOrD
return Result.Failure<SuccessResponse>(ChatErrors.Unauthorized);
}
if (chat.Type == ChatType.Group)
// If it's a private chat or the last member leaving a group, delete everything
bool shouldDeleteEverything = chat.Type != ChatType.Group || chat.Members.Count <= 1;
if (chat.Type == ChatType.Group && !shouldDeleteEverything)
{
chat.RemoveMember(request.UserId);
_chatRepository.Update(chat);
}
else
{
// DELETE ALL MESSAGES AND FILES FIRST
await DeleteChatMediaAndMessagesAsync(chat.Id, cancellationToken);
_chatRepository.Remove(chat);
}
@@ -50,5 +64,45 @@ internal sealed class LeaveOrDeleteChatCommandHandler : ICommandHandler<LeaveOrD
return Result.Success(new SuccessResponse(true));
}
}
private async Task DeleteChatMediaAndMessagesAsync(Guid chatId, CancellationToken ct)
{
try
{
// Get all messages directly from Mongo (not paged)
var messages = await _messageRepository.GetChatMessagesAsync(chatId, int.MaxValue, 0, ct);
foreach (var msg in messages)
{
if (msg is Knot.Contracts.Messaging.Domain.MediaMessage mediaMsg)
{
foreach (var media in mediaMsg.Media)
{
if (!string.IsNullOrEmpty(media.Url))
{
var fileId = ExtractFileId(media.Url);
if (!string.IsNullOrEmpty(fileId))
{
await _fileStorage.DeleteFileAsync(fileId);
}
}
}
}
}
await _messageRepository.DeleteChatMessagesAsync(chatId, ct);
}
catch (Exception ex)
{
// Log if possible, but don't fail chat deletion
Console.WriteLine($"[Cleanup] Error deleting chat media: {ex.Message}");
}
}
private string? ExtractFileId(string url)
{
var lastSlash = url.LastIndexOf('/');
if (lastSlash == -1) return null;
var id = url[(lastSlash + 1)..];
if (id.Contains('?')) id = id[..id.IndexOf('?')];
return id;
}
}