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.
This commit is contained in:
@@ -22,14 +22,22 @@ public record FetchEmailsQuery : IRequest<IEnumerable<ReceivedEmailContext>>
|
|||||||
public string Folder { get; init; } = "INBOX";
|
public string Folder { get; init; } = "INBOX";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When <see langword="true"/> returns only unread messages.
|
/// Mail query used to filter and limit the emails retrieved.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool UnseenOnly { get; init; } = false;
|
public MailQuery Mail { get; init; } = new();
|
||||||
|
|
||||||
/// <summary>
|
public record MailQuery
|
||||||
/// Maximum number of messages to retrieve (most-recent first). 0 = unlimited.
|
{
|
||||||
/// </summary>
|
/// <summary>
|
||||||
public int MaxCount { get; init; } = 50;
|
/// When <see langword="true"/> returns only unread messages.
|
||||||
|
/// </summary>
|
||||||
|
public bool UnseenOnly { get; init; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum number of messages to retrieve (most-recent first). 0 = unlimited.
|
||||||
|
/// </summary>
|
||||||
|
public int MaxCount { get; init; } = 50;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FetchEmailsQueryHandler(
|
public class FetchEmailsQueryHandler(
|
||||||
@@ -49,8 +57,8 @@ public class FetchEmailsQueryHandler(
|
|||||||
return await ImapService.FetchEmailsAsync(
|
return await ImapService.FetchEmailsAsync(
|
||||||
account,
|
account,
|
||||||
request.Folder,
|
request.Folder,
|
||||||
request.UnseenOnly,
|
request.Mail.UnseenOnly,
|
||||||
request.MaxCount,
|
request.Mail.MaxCount,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,31 +71,15 @@ public class EmailController(IMediator mediator) : ControllerBase
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fetch emails from an IMAP mailbox.
|
/// Fetch emails from an IMAP mailbox.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="accountId">Id of the email account (must have ImapServer configured).</param>
|
/// <param name="query">Query parameters for filtering and fetching emails from the IMAP mailbox.</param>
|
||||||
/// <param name="folder">Mailbox folder to read (default: INBOX).</param>
|
|
||||||
/// <param name="unseenOnly">Return only unread messages.</param>
|
|
||||||
/// <param name="maxCount">Maximum number of messages to return (most-recent first, default: 50).</param>
|
|
||||||
/// <param name="cancellationToken">Cancellation token.</param>
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
/// <returns>HTTP 200 with list of received emails.</returns>
|
/// <returns>HTTP 200 with list of received emails.</returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<IActionResult> FetchEmails(
|
public async Task<IActionResult> FetchEmails([FromQuery] FetchEmailsQuery query, CancellationToken cancellationToken = default)
|
||||||
[FromQuery] int accountId,
|
|
||||||
[FromQuery] string folder = "INBOX",
|
|
||||||
[FromQuery] bool unseenOnly = false,
|
|
||||||
[FromQuery] int maxCount = 50,
|
|
||||||
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);
|
var emails = await mediator.Send(query, cancellationToken);
|
||||||
return Ok(emails);
|
return Ok(emails);
|
||||||
}
|
}
|
||||||
@@ -103,28 +87,15 @@ public class EmailController(IMediator mediator) : ControllerBase
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mark a single IMAP message as seen (read).
|
/// Mark a single IMAP message as seen (read).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="accountId">Id of the email account.</param>
|
/// <param name="command">The command containing the mailbox account identifier and the unique identifier (UID) of the message to mark as seen.</param>
|
||||||
/// <param name="uid">UID of the message on the IMAP server.</param>
|
|
||||||
/// <param name="folder">Mailbox folder the message resides in (default: INBOX).</param>
|
|
||||||
/// <param name="cancellationToken">Cancellation token.</param>
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
/// <returns>HTTP 204 No Content.</returns>
|
/// <returns>HTTP 204 No Content.</returns>
|
||||||
[HttpPatch("{uid}/seen")]
|
[HttpPatch("seen")]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<IActionResult> MarkAsSeen(
|
public async Task<IActionResult> MarkAsSeen([FromRoute] MarkEmailAsSeenCommand command, CancellationToken cancellationToken = default)
|
||||||
[FromRoute] long uid,
|
|
||||||
[FromQuery] int accountId,
|
|
||||||
[FromQuery] string folder = "INBOX",
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
{
|
||||||
var command = new MarkEmailAsSeenCommand
|
|
||||||
{
|
|
||||||
Account = new GetSenderQuery { Id = accountId },
|
|
||||||
Uid = uid,
|
|
||||||
Folder = folder
|
|
||||||
};
|
|
||||||
|
|
||||||
await mediator.Send(command, cancellationToken);
|
await mediator.Send(command, cancellationToken);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user