using HrynCo.NotificationService.DAL.Abstract.Templates; using HrynCo.NotificationService.Services.Core; using Unit = HrynCo.NotificationService.Services.Core.Unit; using HrynCo.NotificationService.Web.Infrastructure; using HrynCo.NotificationService.Services.TemplateDefinitions; using MediatR; using Microsoft.AspNetCore.Mvc; namespace HrynCo.NotificationService.Web.Controllers.Api.Services; [Route("api/v1/services")] [TypeFilter(typeof(ApiRequestValidationFilter), Order = -3000)] public sealed class ServicesController(IMediator mediator) : ApiControllerBase(mediator) { [HttpGet("{serviceId:guid}")] [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status404NotFound)] public async Task Get([FromRoute] Guid serviceId, CancellationToken cancellationToken) => FromServiceResult(await Mediator.Send(new GetNotificationServiceQuery(serviceId, null), cancellationToken)); [HttpGet] [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status404NotFound)] public async Task GetByName([FromQuery] string? name, CancellationToken cancellationToken) => FromServiceResult(await Mediator.Send(new GetNotificationServiceQuery(null, name), cancellationToken)); [HttpGet("all")] [ProducesResponseType>>(StatusCodes.Status200OK)] public async Task GetAll(CancellationToken cancellationToken) => FromServiceResult(await Mediator.Send(new GetAllNotificationServicesQuery(), cancellationToken)); [HttpDelete("{serviceId:guid}")] [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status404NotFound)] [ProducesResponseType>(StatusCodes.Status409Conflict)] public async Task Delete([FromRoute] Guid serviceId, [FromQuery] Guid revision, CancellationToken cancellationToken) => FromServiceResult(await Mediator.Send(new DeleteNotificationServiceCommand(serviceId, revision), cancellationToken)); [HttpPost] [ProducesResponseType>(StatusCodes.Status201Created)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status409Conflict)] public Task Create([FromBody] CreateNotificationServiceRequest request, CancellationToken cancellationToken) => SaveServiceAsync(null, request.Name, request.Languages, Guid.Empty, cancellationToken); [HttpPut("{serviceId:guid}")] [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status404NotFound)] [ProducesResponseType>(StatusCodes.Status409Conflict)] public Task Update([FromRoute] Guid serviceId, [FromBody] UpdateNotificationServiceRequest request, CancellationToken cancellationToken) => SaveServiceAsync(serviceId, request.Name, request.Languages, request.Revision, cancellationToken); [HttpDelete("{serviceId:guid}/languages/{languageId:guid}")] [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status404NotFound)] [ProducesResponseType>(StatusCodes.Status409Conflict)] public async Task DeleteUnusedLanguage([FromRoute] Guid serviceId, [FromRoute] Guid languageId, [FromQuery] Guid revision, CancellationToken cancellationToken) => FromServiceResult(await Mediator.Send(new DeleteUnusedServiceLanguageCommand(serviceId, languageId, revision), cancellationToken)); [HttpPost("{serviceId:guid}/languages/{languageId:guid}/delete-with-versions")] [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType>(StatusCodes.Status400BadRequest)] [ProducesResponseType>(StatusCodes.Status404NotFound)] [ProducesResponseType>(StatusCodes.Status409Conflict)] public async Task DeleteLanguageWithVersions([FromRoute] Guid serviceId, [FromRoute] Guid languageId, [FromBody] DeleteServiceLanguageVersionsRequest request, CancellationToken cancellationToken) => FromServiceResult(await Mediator.Send(new DeleteServiceLanguageVersionsCommand(serviceId, languageId, request.Revision, request.ExpectedVersionCount, request.ConfirmDelete), cancellationToken)); private async Task SaveServiceAsync(Guid? id, string name, IReadOnlyList languages, Guid revision, CancellationToken cancellationToken) { try { var model = NotificationServiceRequestMapping.Map(id, name, languages, revision); var result = await Mediator.Send(new SaveNotificationServiceCommand(model, id is null), cancellationToken); if (!result.IsSuccess) return MapServiceError(result.Error!); if (id is null) return CreatedAtAction(nameof(Get), new { serviceId = result.Result!.Id }, new ApiResponse { Success = true, Data = result.Result }); return FromServiceResult(result); } catch (EmailTemplateWriteException error) { return MapServiceError(new ServiceError(error.Message, ServiceErrorCode.InvalidRequest)); } } }