refactor(application): replace GetSenderQuery with GetEmailAccountQuery and add EmailAccountModificationCommand
- Rename GetSenderQuery to GetEmailAccountQuery with updated return type (IEnumerable<EmailAccountDto>) - Handler now queries IRepository<EmailAccount> directly instead of chaining MediatR dispatches - Add EmailAccountModificationCommand for create/update/delete operations on email accounts - Update GetSenderQueryValidator to reference renamed query type - Remove exclusive Id/Username validation rule (now handled by repo query logic)
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
#if NET
|
||||
using DigitalData.MessagingService.Application.Common.Dto.EmailAccounts;
|
||||
using DigitalData.MessagingService.Application.Common.Interfaces.Repositories;
|
||||
using DigitalData.MessagingService.Application.Common.ValueObjects;
|
||||
using DigitalData.MessagingService.Domain.Entities;
|
||||
using MediatR;
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace DigitalData.MessagingService.Application.EmailAccounts.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// DTO for a single email account configuration.
|
||||
/// </summary>
|
||||
public record EmailAccountModificationCommand : IRequest<(EmailAccount, bool)>
|
||||
{
|
||||
public required EmailAccountModificationDto ModifiedAccount { get; init; }
|
||||
|
||||
public required Modification Modification { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Repo"></param>
|
||||
public class EmailAccountModificationCommandHandler(IRepository<EmailAccount> Repo) : IRequestHandler<EmailAccountModificationCommand, (EmailAccount, bool)>
|
||||
{
|
||||
public async Task<(EmailAccount, bool)> Handle(EmailAccountModificationCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
return request.Modification switch
|
||||
{
|
||||
Modification.Upsert => await Repo.UpsertAsync(a => a.Username == request.ModifiedAccount.Username, request.ModifiedAccount, cancellationToken),
|
||||
_ => throw new NotSupportedException($"Modification type '{request.Modification}' is not supported in email account modification."),
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
#if NET
|
||||
using MediatR;
|
||||
using DigitalData.MessagingService.Domain.Entities;
|
||||
using DigitalData.MessagingService.Application.Common.Interfaces.Repositories;
|
||||
using AutoMapper;
|
||||
using DigitalData.MessagingService.Domain.Exceptions;
|
||||
using DigitalData.MessagingService.Application.Common.Dto.EmailAccounts;
|
||||
|
||||
namespace DigitalData.MessagingService.Application.EmailAccounts.Queries;
|
||||
|
||||
public record GetEmailAccountQuery : IRequest<IEnumerable<EmailAccountDto>>
|
||||
{
|
||||
public int? Id { get; init; }
|
||||
|
||||
public string? Username { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles queries for retrieving email accounts.
|
||||
/// </summary>
|
||||
/// <param name="Repo"></param>
|
||||
/// <param name="Mapper"></param>
|
||||
public class GetEmailAccountQueryHandler(IRepository<EmailAccount> Repo, IMapper Mapper) : IRequestHandler<GetEmailAccountQuery, IEnumerable<EmailAccountDto>>
|
||||
{
|
||||
public async Task<IEnumerable<EmailAccountDto>> Handle(GetEmailAccountQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var accounts = request.Id is null && request.Username is null
|
||||
? await Repo.GetAllAsync(cancellationToken)
|
||||
: await Repo.FindAsync(request.Id is int id ? x => x.Id == id : x => x.Username == request.Username, cancellationToken: cancellationToken);
|
||||
|
||||
if (accounts.Any())
|
||||
return Mapper.Map<IEnumerable<EmailAccountDto>>(accounts);
|
||||
else
|
||||
throw new NotFoundException($"No email account found for the given criteria ({(request.Id is not null ? $"Id: {request.Id}" : $"Username: {request.Username}")}).");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,41 +0,0 @@
|
||||
#if NET
|
||||
using DigitalData.MessagingService.Application.Common.Options;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using DigitalData.MessagingService.Domain.Entities;
|
||||
|
||||
namespace DigitalData.MessagingService.Application.EmailAccounts.Queries;
|
||||
|
||||
public record GetSenderQuery : IRequest<EmailAccount?>
|
||||
{
|
||||
public int? Id { get; init; }
|
||||
|
||||
public string? Username { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Options"></param>
|
||||
/// <param name="Logger"></param>
|
||||
public class GetSenderQueryHandler(IOptions<EmailAccountsOptions> Options, ILogger<GetSenderQueryHandler> Logger) : IRequestHandler<GetSenderQuery, EmailAccount?>
|
||||
{
|
||||
public Task<EmailAccount?> Handle(GetSenderQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var accounts = request.Id is not null
|
||||
? Options.Value.Accounts.Where(a => a.Id == request.Id)
|
||||
: Options.Value.Accounts.Where(a => a.Username == request.Username);
|
||||
|
||||
if(accounts.Count() > 1)
|
||||
{
|
||||
Logger.LogWarning(
|
||||
"Multiple email accounts found for the given criteria ({Criteria}). Returning the first one.",
|
||||
request.Id is not null ? $"Id: {request.Id}" : $"Username: {request.Username}"
|
||||
);
|
||||
}
|
||||
|
||||
return Task.FromResult(accounts.FirstOrDefault());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -5,17 +5,13 @@ using FluentValidation;
|
||||
namespace DigitalData.MessagingService.Application.EmailAccounts.Validators;
|
||||
|
||||
/// <summary>
|
||||
/// Validator for <see cref="GetSenderQuery"/>.
|
||||
/// Either <see cref="GetSenderQuery.Id"/> or <see cref="GetSenderQuery.Username"/> must be provided, but not both.
|
||||
/// Validator for <see cref="GetEmailAccountQuery"/>.
|
||||
/// Either <see cref="GetEmailAccountQuery.Id"/> or <see cref="GetEmailAccountQuery.Username"/> must be provided, but not both.
|
||||
/// </summary>
|
||||
public class GetSenderQueryValidator : AbstractValidator<GetSenderQuery>
|
||||
public class GetSenderQueryValidator : AbstractValidator<GetEmailAccountQuery>
|
||||
{
|
||||
public GetSenderQueryValidator()
|
||||
{
|
||||
RuleFor(x => x)
|
||||
.Must(x => (x.Id is not null) ^ (x.Username is not null))
|
||||
.WithMessage("Either Id or Username must be provided, but not both.");
|
||||
|
||||
When(x => x.Username is not null, () =>
|
||||
{
|
||||
RuleFor(x => x.Username)
|
||||
|
||||
Reference in New Issue
Block a user