feat(notification): add admin rest management and deletion
Add revision-safe service and template APIs, channel mapping, and validated admin controls. Ref: IT-1601
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
using MediatR;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Web.Controllers.Admin.ViewModels;
|
||||
@@ -6,7 +8,8 @@ using Microsoft.AspNetCore.Mvc;
|
||||
namespace HrynCo.NotificationService.Web.Controllers.Admin;
|
||||
|
||||
[Route("admin/services")]
|
||||
public sealed class AdminServicesController(INotificationServiceRepository services, ILogger<AdminServicesController> logger) : Controller
|
||||
public sealed class AdminServicesController(INotificationServiceRepository services, ILogger<AdminServicesController> logger,
|
||||
IEmailTemplateDefinitionRepository definitions, IMediator mediator) : Controller
|
||||
{
|
||||
[HttpGet("")]
|
||||
public async Task<IActionResult> Index(CancellationToken ct) => View(await services.GetAllAsync(ct));
|
||||
@@ -77,6 +80,55 @@ public sealed class AdminServicesController(INotificationServiceRepository servi
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{serviceId:guid}/delete")]
|
||||
public async Task<IActionResult> ConfirmServiceDelete([FromRoute] Guid serviceId, CancellationToken ct)
|
||||
{
|
||||
var model = await ServiceDeleteModelAsync(serviceId, ct);
|
||||
return model is null ? NotFound() : View("DeleteService", model);
|
||||
}
|
||||
|
||||
[HttpPost("{serviceId:guid}/delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> DeleteService([FromRoute] Guid serviceId, NotificationServiceDeleteViewModel model, CancellationToken ct)
|
||||
{
|
||||
if (!ModelState.IsValid || !model.ConfirmDelete)
|
||||
return await ServiceDeleteErrorAsync(serviceId, "Confirm deletion of this service to continue.", ct);
|
||||
try
|
||||
{
|
||||
var result = await mediator.Send(new DeleteNotificationServiceCommand(serviceId, model.Revision), ct);
|
||||
if (result.IsSuccess)
|
||||
return RedirectToAction(nameof(Index));
|
||||
return await ServiceDeleteErrorAsync(serviceId, result.Error!.Message, ct);
|
||||
}
|
||||
catch (Exception error) when (error is not OperationCanceledException)
|
||||
{
|
||||
logger.LogError(error, "Failed to delete notification service.");
|
||||
return await ServiceDeleteErrorAsync(serviceId, "Could not complete deletion. Review the current service before trying again.", ct);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<NotificationServiceDeleteViewModel?> ServiceDeleteModelAsync(Guid serviceId, CancellationToken ct)
|
||||
{
|
||||
var service = await services.GetAsync(serviceId, ct);
|
||||
if (service is null)
|
||||
return null;
|
||||
return new NotificationServiceDeleteViewModel
|
||||
{
|
||||
ServiceId = service.Id, Name = service.Name, Revision = service.Revision,
|
||||
DefinitionCount = (await definitions.GetDefinitionsAsync(serviceId, ct)).Count
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<IActionResult> ServiceDeleteErrorAsync(Guid serviceId, string error, CancellationToken ct)
|
||||
{
|
||||
var model = await ServiceDeleteModelAsync(serviceId, ct);
|
||||
if (model is null)
|
||||
return NotFound();
|
||||
ModelState.Clear();
|
||||
ModelState.AddModelError("", error);
|
||||
return View("DeleteService", model);
|
||||
}
|
||||
|
||||
private async Task<IActionResult> ServiceEditorViewAsync(NotificationServiceEditViewModel model, CancellationToken ct)
|
||||
{
|
||||
if (model.Id is not Guid id)
|
||||
|
||||
Reference in New Issue
Block a user