using Api.Services; using EmailApi.Models.Requests; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; namespace Api.Controllers; /// /// 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. /// [ApiController] [Route("api/email")] public sealed class EmailController : ControllerBase { private readonly SmtpEmailDispatcher _dispatcher; public EmailController(SmtpEmailDispatcher dispatcher) => _dispatcher = dispatcher; /// /// 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 /// . /// /// Email payload: recipients, subject, HTML body fragment, optional attachment path. /// Cancellation token. /// 204 No Content on success. [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 Send([FromBody] SendEmailRequest request, CancellationToken ct) { await _dispatcher.SendAsync(request, ct); return NoContent(); } }