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;
|
namespace DigitalData.MessagingService.Application.EmailAccounts.Validators;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validator for <see cref="GetSenderQuery"/>.
|
/// Validator for <see cref="GetEmailAccountQuery"/>.
|
||||||
/// Either <see cref="GetSenderQuery.Id"/> or <see cref="GetSenderQuery.Username"/> must be provided, but not both.
|
/// Either <see cref="GetEmailAccountQuery.Id"/> or <see cref="GetEmailAccountQuery.Username"/> must be provided, but not both.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GetSenderQueryValidator : AbstractValidator<GetSenderQuery>
|
public class GetSenderQueryValidator : AbstractValidator<GetEmailAccountQuery>
|
||||||
{
|
{
|
||||||
public GetSenderQueryValidator()
|
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, () =>
|
When(x => x.Username is not null, () =>
|
||||||
{
|
{
|
||||||
RuleFor(x => x.Username)
|
RuleFor(x => x.Username)
|
||||||
|
|||||||
Reference in New Issue
Block a user