e1f171168e
Fixes inconsistency where email-api used EmailApi.* and page-fetcher-api used PageFetcherApi.*, while cv-matcher-api and rag-api use the generic Api.* namespace. All four API projects now follow the same pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
48 lines
2.2 KiB
C#
48 lines
2.2 KiB
C#
using Api.Services;
|
|
using EmailApi.Models.Requests;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Swashbuckle.AspNetCore.Annotations;
|
|
|
|
namespace Api.Controllers;
|
|
|
|
/// <summary>
|
|
/// Internal email relay. Accepts an HTML body fragment from trusted callers
|
|
/// (api, cv-search-job), wraps it in the branded HTML shell, and dispatches
|
|
/// via SMTP. Protected by X-Internal-Api-Key.
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/email")]
|
|
public sealed class EmailController : ControllerBase
|
|
{
|
|
private readonly SmtpEmailDispatcher _dispatcher;
|
|
|
|
public EmailController(SmtpEmailDispatcher dispatcher) => _dispatcher = dispatcher;
|
|
|
|
/// <summary>
|
|
/// Sends an HTML email via SMTP. The supplied body fragment is wrapped in
|
|
/// the branded HTML shell before dispatch. Attachments are resolved from
|
|
/// the shared file storage volume using the relative path in
|
|
/// <see cref="SendEmailRequest.AttachmentPath"/>.
|
|
/// </summary>
|
|
/// <param name="request">Email payload: recipients, subject, HTML body fragment, optional attachment path.</param>
|
|
/// <param name="ct">Cancellation token.</param>
|
|
/// <returns>204 No Content on success.</returns>
|
|
[HttpPost("send")]
|
|
[SwaggerOperation(
|
|
Summary = "Send an HTML email via SMTP",
|
|
Description = "Wraps the provided HTML body in the branded shell and sends via SMTP. " +
|
|
"If AttachmentPath is set, resolves the file from the shared file-storage volume. " +
|
|
"Returns 204 on success; 400 when the request body is invalid; 500 on SMTP failure.")]
|
|
[SwaggerResponse(StatusCodes.Status204NoContent, "Email dispatched successfully")]
|
|
[SwaggerResponse(StatusCodes.Status400BadRequest, "Request body is missing or invalid")]
|
|
[SwaggerResponse(StatusCodes.Status500InternalServerError, "SMTP dispatch failed")]
|
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<IActionResult> Send([FromBody] SendEmailRequest request, CancellationToken ct)
|
|
{
|
|
await _dispatcher.SendAsync(request, ct);
|
|
return NoContent();
|
|
}
|
|
}
|