From 79db1c3a69048c3a337b85f3ce52e8ca423e4f30 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 7 Aug 2026 12:43:41 +0200 Subject: [PATCH] Refactor email query and controller endpoints Refactored `FetchEmailsQuery` to encapsulate filtering and retrieval parameters (`UnseenOnly` and `MaxCount`) within a nested `MailQuery` record for better organization. Updated `FetchEmailsQueryHandler` to use the new structure. Simplified `EmailController` endpoints: - Replaced multiple query parameters in `FetchEmails` with a single `FetchEmailsQuery` object. - Replaced multiple parameters in `MarkAsSeen` with a `MarkEmailAsSeenCommand` object. - Adjusted the HTTP route for `MarkAsSeen` from `"{uid}/seen"` to `"seen"`. Updated XML documentation to reflect these changes, improving maintainability and scalability. --- .../Queries/FetchEmailsQuery.cs | 24 ++++++++---- .../Controllers/EmailController.cs | 39 +++---------------- 2 files changed, 21 insertions(+), 42 deletions(-) diff --git a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailsQuery.cs b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailsQuery.cs index 0aaca2a..070d12b 100644 --- a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailsQuery.cs +++ b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailsQuery.cs @@ -22,14 +22,22 @@ public record FetchEmailsQuery : IRequest> public string Folder { get; init; } = "INBOX"; /// - /// When returns only unread messages. + /// Mail query used to filter and limit the emails retrieved. /// - public bool UnseenOnly { get; init; } = false; + public MailQuery Mail { get; init; } = new(); - /// - /// Maximum number of messages to retrieve (most-recent first). 0 = unlimited. - /// - public int MaxCount { get; init; } = 50; + public record MailQuery + { + /// + /// When returns only unread messages. + /// + public bool UnseenOnly { get; init; } = false; + + /// + /// Maximum number of messages to retrieve (most-recent first). 0 = unlimited. + /// + public int MaxCount { get; init; } = 50; + } } public class FetchEmailsQueryHandler( @@ -49,8 +57,8 @@ public class FetchEmailsQueryHandler( return await ImapService.FetchEmailsAsync( account, request.Folder, - request.UnseenOnly, - request.MaxCount, + request.Mail.UnseenOnly, + request.Mail.MaxCount, cancellationToken); } } diff --git a/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs b/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs index d58f52f..da5f926 100644 --- a/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs +++ b/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs @@ -71,31 +71,15 @@ public class EmailController(IMediator mediator) : ControllerBase /// /// Fetch emails from an IMAP mailbox. /// - /// Id of the email account (must have ImapServer configured). - /// Mailbox folder to read (default: INBOX). - /// Return only unread messages. - /// Maximum number of messages to return (most-recent first, default: 50). + /// Query parameters for filtering and fetching emails from the IMAP mailbox. /// Cancellation token. /// HTTP 200 with list of received emails. [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task FetchEmails( - [FromQuery] int accountId, - [FromQuery] string folder = "INBOX", - [FromQuery] bool unseenOnly = false, - [FromQuery] int maxCount = 50, - CancellationToken cancellationToken = default) + public async Task FetchEmails([FromQuery] FetchEmailsQuery query, CancellationToken cancellationToken = default) { - var query = new FetchEmailsQuery - { - Account = new GetSenderQuery { Id = accountId }, - Folder = folder, - UnseenOnly = unseenOnly, - MaxCount = maxCount - }; - var emails = await mediator.Send(query, cancellationToken); return Ok(emails); } @@ -103,28 +87,15 @@ public class EmailController(IMediator mediator) : ControllerBase /// /// Mark a single IMAP message as seen (read). /// - /// Id of the email account. - /// UID of the message on the IMAP server. - /// Mailbox folder the message resides in (default: INBOX). + /// The command containing the mailbox account identifier and the unique identifier (UID) of the message to mark as seen. /// Cancellation token. /// HTTP 204 No Content. - [HttpPatch("{uid}/seen")] + [HttpPatch("seen")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task MarkAsSeen( - [FromRoute] long uid, - [FromQuery] int accountId, - [FromQuery] string folder = "INBOX", - CancellationToken cancellationToken = default) + public async Task MarkAsSeen([FromRoute] MarkEmailAsSeenCommand command, CancellationToken cancellationToken = default) { - var command = new MarkEmailAsSeenCommand - { - Account = new GetSenderQuery { Id = accountId }, - Uid = uid, - Folder = folder - }; - await mediator.Send(command, cancellationToken); return NoContent(); }