Рабочий чат

This commit is contained in:
Халимов Рустам
2026-04-01 23:18:55 +03:00
parent 249c344df8
commit 4ae7dd60ce
42 changed files with 1016 additions and 184 deletions
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Knot.Modules.Relations.Domain;
using Knot.Shared.Kernel;
using Microsoft.EntityFrameworkCore;
using Knot.Modules.Relations.Application.Abstractions;
namespace Knot.Modules.Relations.Application.Contacts;
public record ContactUserDto(Guid Id, string Username, string DisplayName, string Avatar);
public record ContactRequestDto(Guid Id, ContactUserDto User, DateTime CreatedAt, bool IsOutgoing);
public record GetContactRequestsQuery(Guid UserId) : IQuery<List<ContactRequestDto>>;
internal sealed class GetContactRequestsQueryHandler : IQueryHandler<GetContactRequestsQuery, List<ContactRequestDto>>
{
private readonly IContactsDbContext _context;
public GetContactRequestsQueryHandler(IContactsDbContext context)
{
_context = context;
}
public async Task<Result<List<ContactRequestDto>>> Handle(GetContactRequestsQuery request, CancellationToken cancellationToken)
{
// 1. Fetch ALL pending requests where current user is either sender or receiver
var contacts = await _context.Contacts
.Where(c => (c.ContactId == request.UserId || c.UserId == request.UserId) && c.Status == ContactStatus.Pending)
.ToListAsync(cancellationToken);
// 2. Fetch all unique IDs for users we need replicas for
var userIds = contacts
.Select(c => c.UserId == request.UserId ? c.ContactId : c.UserId)
.Distinct()
.ToList();
// 3. Fetch replicas
var replicas = await _context.UserReplicas
.Where(r => userIds.Contains(r.Id))
.ToDictionaryAsync(r => r.Id, cancellationToken);
// 4. Transform into DTOs
var result = contacts
.Select(c =>
{
var isOutgoing = c.UserId == request.UserId;
var otherUserId = isOutgoing ? c.ContactId : c.UserId;
// If replica is missing, we try to at least return the record (Visibility fix part 1)
// We will handle replica creation in SendContactRequest proactively.
if (!replicas.TryGetValue(otherUserId, out var user))
{
return new ContactRequestDto(
c.Id,
new ContactUserDto(otherUserId, "Unknown", "Unknown", ""),
c.CreatedAt,
isOutgoing
);
}
return new ContactRequestDto(
c.Id,
new ContactUserDto(user.Id, user.Username, user.DisplayName, user.Avatar),
c.CreatedAt,
isOutgoing
);
})
.ToList();
return Result.Success(result);
}
}