feat(api): Add REST API controllers with RabbitMQ for POST/PUT/DELETE

Controllers:
- EmailProfilesController: CRUD operations (GET sync, POST/PUT/DELETE async via RabbitMQ)
  * GET /api/emailprofiles - List all profiles
  * GET /api/emailprofiles/{id} - Get profile by ID
  * GET /api/emailprofiles/active - List active profiles
  * POST /api/emailprofiles - Create (202 Accepted, queued to RabbitMQ)
  * PUT /api/emailprofiles/{id} - Update (202 Accepted, queued to RabbitMQ)
  * DELETE /api/emailprofiles/{id} - Delete (202 Accepted, queued to RabbitMQ)

- EmailAccountsController: CRUD operations
  * GET /api/emailaccounts - List all accounts
  * GET /api/emailaccounts/{id} - Get account by ID
  * POST /api/emailaccounts - Create (202 Accepted, queued to RabbitMQ)

- EmailHistoryController: Read-only operations
  * GET /api/emailhistory/profile/{profileId} - Get history with pagination
  * GET /api/emailhistory/{id} - Get history by ID

Changes:
- Fix ICommandPublisher constraint: IRequest → IBaseRequest (supports IRequest<T>)
- All POST/PUT/DELETE return HTTP 202 Accepted (async processing)
- All GET operations return HTTP 200 OK (synchronous via MediatR)
- Proper error handling: 404 Not Found for missing resources
This commit is contained in:
2026-07-14 16:39:35 +02:00
parent 0d22fe0b5c
commit bfe24eba06
5 changed files with 253 additions and 3 deletions

View File

@@ -0,0 +1,57 @@
using DigitalData.EmailProfiler.Application.Common.Dtos.EmailHistories;
using DigitalData.EmailProfiler.Application.Features.EmailHistories.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.EmailProfiler.API.Controllers;
/// <summary>
/// Email history API controller (read-only)
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class EmailHistoryController(IMediator mediator) : ControllerBase
{
/// <summary>
/// Get email history by profile ID with pagination
/// </summary>
[HttpGet("profile/{profileId:int}")]
[ProducesResponseType(typeof(IEnumerable<EmailHistoryDto>), StatusCodes.Status200OK)]
public async Task<IActionResult> GetByProfile(
int profileId,
[FromQuery] int pageNumber = 1,
[FromQuery] int pageSize = 50,
CancellationToken cancellationToken = default)
{
var query = new GetEmailHistoryByProfileQuery(profileId, pageNumber, pageSize);
var result = await mediator.Send(query, cancellationToken);
return Ok(new
{
ProfileId = profileId,
PageNumber = pageNumber,
PageSize = pageSize,
Data = result
});
}
/// <summary>
/// Get email history by ID
/// </summary>
[HttpGet("{id:int}")]
[ProducesResponseType(typeof(EmailHistoryDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetById(int id, CancellationToken cancellationToken)
{
var query = new GetEmailHistoryByIdQuery(id);
var result = await mediator.Send(query, cancellationToken);
if (result == null)
return NotFound(new { Message = $"Email history with ID {id} not found" });
return Ok(result);
}
// Note: Email history is typically managed by ProcessEmailCommand
// No direct CREATE/UPDATE/DELETE endpoints needed
}