From 6c698c95bee8c93bb7898130375cf7941e9911b6 Mon Sep 17 00:00:00 2001 From: TekH Date: Mon, 17 Aug 2026 01:13:14 +0200 Subject: [PATCH] Refactor ReadEmailQuery to return structured response Updated ReadEmailQuery to return a new response type, ReadEmailQueryResponse, which includes both email data and metadata (e.g., LastSync). Added the Account property to ReadEmailQuery for specifying the email account. Refactored ReadEmailQueryHandler to: - Use IImapEmailService to fetch LastSync metadata. - Return ReadEmailQueryResponse instead of a collection of ReceivedEmailDto. Introduced ReadEmailQueryResponse class to encapsulate LastSync and Emails properties. Updated EmailController to handle the new response structure, ensuring compatibility with the updated ReadEmailQuery and its handler. --- .../EmailReceiving/Queries/ReadEmailQuery.cs | 15 +++++++++++---- .../Queries/ReadEmailQueryResponse.cs | 17 +++++++++++++++++ .../Controllers/EmailController.cs | 10 +++++----- 3 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQueryResponse.cs diff --git a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQuery.cs b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQuery.cs index 0e8bf74..e27dc88 100644 --- a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQuery.cs +++ b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQuery.cs @@ -15,7 +15,7 @@ namespace DigitalData.MessagingService.Application.EmailReceiving.Queries; /// /// Query to fetch emails from an IMAP mailbox. /// -public record ReadEmailQuery : IRequest> +public record ReadEmailQuery : IRequest { /// /// Identifies the email account to use. @@ -28,9 +28,9 @@ public record ReadEmailQuery : IRequest> public MailSearchFilter Mail { get; init; } = new(); } -public class ReadEmailQueryHandler(IMapper Mapper, ILogger Logger, IRepository EmailAccountRepo, IReceivedEmailRepository MailRepo) : IRequestHandler> +public class ReadEmailQueryHandler(IMapper Mapper, ILogger Logger, IRepository EmailAccountRepo, IReceivedEmailRepository MailRepo, IImapEmailService imapEmailService) : IRequestHandler { - public async Task> Handle(ReadEmailQuery request, CancellationToken cancellationToken) + public async Task Handle(ReadEmailQuery request, CancellationToken cancellationToken) { var accounts = await EmailAccountRepo.FindAsync(request.Account.Id is int id ? x => x.Id == id : x => x.Username == request.Account.Username, cancellationToken: cancellationToken); @@ -45,7 +45,14 @@ public class ReadEmailQueryHandler(IMapper Mapper, ILogger>(mails); + + var lastSync = imapEmailService.GetLastImapSyncDate(account.Id, request.Mail.Folder); + + return new ReadEmailQueryResponse + { + LastSync = lastSync, + Emails = Mapper.Map>(mails) + }; } } #endif \ No newline at end of file diff --git a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQueryResponse.cs b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQueryResponse.cs new file mode 100644 index 0000000..a6dc986 --- /dev/null +++ b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQueryResponse.cs @@ -0,0 +1,17 @@ +#if NET +using DigitalData.MessagingService.Application.Common.Dto; + +namespace DigitalData.MessagingService.Application.EmailReceiving.Queries; + +/// +/// +/// +/// +/// +public class ReadEmailQueryResponse +{ + public DateTime? LastSync { get; init; } = null; + + public IEnumerable Emails { get; init; } = []; +} +#endif \ No newline at end of file diff --git a/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs b/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs index dbd7609..64548a1 100644 --- a/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs +++ b/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs @@ -94,22 +94,22 @@ public class EmailController(IMediator mediator) : ControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task FetchEmails([FromQuery] ReadEmailQuery query, [FromQuery] OnlyFilter? only = null, CancellationToken cancellationToken = default) { - var emails = await mediator.Send(query, cancellationToken); + var res = await mediator.Send(query, cancellationToken); - if(!emails.Any()) + if(!res.Emails.Any()) return NotFound("No emails found matching the specified criteria."); if (only == OnlyFilter.HtmlBody) { - if (emails.FirstOrDefault()?.HtmlBody is string htmlBody) + if (res.Emails.FirstOrDefault()?.HtmlBody is string htmlBody) return Content(htmlBody, "text/html"); else return NotFound(); } else if (only == OnlyFilter.Uid) - return Ok(emails.Select(e => e.Uid).ToList()); + return Ok(res.Emails.Select(e => e.Uid).ToList()); else - return Ok(emails); + return Ok(res); } #endregion Receive }