Рабочий чат
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
using Knot.Shared.Kernel;
|
||||
using Knot.Shared.Kernel.Events;
|
||||
using Knot.Contracts.Profiles.Domain;
|
||||
using Knot.Modules.Profiles.Domain;
|
||||
using MediatR;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Knot.Modules.Profiles.Application.Profiles.Integration;
|
||||
|
||||
internal sealed class UserStatusChangedHandler :
|
||||
INotificationHandler<UserBannedDomainEvent>,
|
||||
INotificationHandler<UserDeletedDomainEvent>
|
||||
{
|
||||
private readonly IProfileRepository _repository;
|
||||
|
||||
public UserStatusChangedHandler(IProfileRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public async Task Handle(UserBannedDomainEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
await _repository.UpdateStatusAsync(notification.UserId, notification.IsBanned, false, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task Handle(UserDeletedDomainEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
await _repository.DeleteAsync(notification.UserId, cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -5,23 +5,69 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediatR;
|
||||
using System;
|
||||
using Knot.Contracts.Relations.Application.Contacts;
|
||||
using Knot.Contracts.Auth.Application.Abstractions;
|
||||
|
||||
namespace Knot.Modules.Profiles.Application.Profiles.Search;
|
||||
|
||||
public sealed record SearchProfilesQuery(string Query) : IQuery<List<UserProfileDto>>;
|
||||
public sealed record SearchProfilesQuery(string Query, Guid UserId) : IQuery<List<UserProfileDto>>;
|
||||
|
||||
internal sealed class SearchProfilesQueryHandler : IQueryHandler<SearchProfilesQuery, List<UserProfileDto>>
|
||||
{
|
||||
private readonly IProfileRepository _repository;
|
||||
private readonly ISender _sender;
|
||||
|
||||
public SearchProfilesQueryHandler(IProfileRepository repository)
|
||||
public SearchProfilesQueryHandler(IProfileRepository repository, ISender sender)
|
||||
{
|
||||
_repository = repository;
|
||||
_sender = sender;
|
||||
}
|
||||
|
||||
public async Task<Result<List<UserProfileDto>>> Handle(SearchProfilesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. Fetch candidates from MongoDB (which might have orphans)
|
||||
var profiles = await _repository.SearchAsync(request.Query, 20, cancellationToken);
|
||||
return Result.Success(profiles);
|
||||
|
||||
var candidates = profiles.Where(p => p.UserId != request.UserId).ToList();
|
||||
if (!candidates.Any()) return Result.Success(new List<UserProfileDto>());
|
||||
|
||||
var candidateIds = candidates.Select(p => p.UserId).ToList();
|
||||
|
||||
// 2. Validate existence in Auth module (to filter out orphans from deleted accounts)
|
||||
var existingIds = new List<Guid>();
|
||||
try {
|
||||
var existenceResult = await _sender.Send(new GetUsersExistenceQuery(candidateIds), cancellationToken);
|
||||
if (existenceResult.IsSuccess) existingIds = existenceResult.Value;
|
||||
} catch {
|
||||
// If Auth module is not available, we assume all exist to avoid empty results
|
||||
existingIds = candidateIds;
|
||||
}
|
||||
|
||||
// 3. Remove orphans (and physically delete them from Mongo if they don't exist in Auth)
|
||||
var validCandidates = candidates.Where(p => existingIds.Contains(p.UserId)).ToList();
|
||||
var orphanIds = candidateIds.Except(existingIds).ToList();
|
||||
foreach (var orphanId in orphanIds)
|
||||
{
|
||||
// Background cleanup (fire and forget or just do it since it's only a few)
|
||||
_ = _repository.DeleteAsync(orphanId, CancellationToken.None);
|
||||
}
|
||||
|
||||
if (!validCandidates.Any()) return Result.Success(new List<UserProfileDto>());
|
||||
|
||||
// 4. Check for blocked users among valid candidates
|
||||
var blockedIds = new List<Guid>();
|
||||
try {
|
||||
var blockedResult = await _sender.Send(new CheckBlockedStatusQuery(request.UserId, validCandidates.Select(v => v.UserId).ToList()), cancellationToken);
|
||||
if (blockedResult.IsSuccess) blockedIds = blockedResult.Value;
|
||||
} catch { }
|
||||
|
||||
// final filter
|
||||
var filtered = validCandidates
|
||||
.Where(p => !blockedIds.Contains(p.UserId))
|
||||
.ToList();
|
||||
|
||||
return Result.Success(filtered);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user