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:
+7
@@ -0,0 +1,7 @@
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
using Unit = HrynCo.NotificationService.Services.Core.Unit;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record DeleteEmailTemplateDefinitionCommand(Guid ServiceId, string Key, Guid Revision) : IRequest<ServiceResult<Unit>>;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class DeleteEmailTemplateDefinitionHandler(
|
||||
IContextualSerilogLogger<DeleteEmailTemplateDefinitionCommand> logger, IEmailTemplateDefinitionRepository repository)
|
||||
: RequestHandler<DeleteEmailTemplateDefinitionCommand, ServiceResult<Unit>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<Unit>> DoOnHandle(DeleteEmailTemplateDefinitionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var removed = await repository.DeleteDefinitionAsync(request.ServiceId, request.Key, request.Revision, cancellationToken);
|
||||
return removed ? Success(Unit.Value) : Failure<Unit>("Template definition not found.", ServiceErrorCode.NotFound);
|
||||
}
|
||||
catch (EmailTemplateWriteException error)
|
||||
{
|
||||
return Failure<Unit>(error.Message, error.IsConflict ? ServiceErrorCode.Conflict : ServiceErrorCode.InvalidRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
using Unit = HrynCo.NotificationService.Services.Core.Unit;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record DeleteNotificationServiceCommand(Guid ServiceId, Guid Revision) : IRequest<ServiceResult<Unit>>;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class DeleteNotificationServiceHandler(
|
||||
IContextualSerilogLogger<DeleteNotificationServiceCommand> logger, INotificationServiceRepository repository)
|
||||
: RequestHandler<DeleteNotificationServiceCommand, ServiceResult<Unit>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<Unit>> DoOnHandle(DeleteNotificationServiceCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var removed = await repository.DeleteAsync(request.ServiceId, request.Revision, cancellationToken);
|
||||
return removed ? Success(Unit.Value) : Failure<Unit>("Service not found.", ServiceErrorCode.NotFound);
|
||||
}
|
||||
catch (EmailTemplateWriteException error)
|
||||
{
|
||||
return Failure<Unit>(error.Message, error.IsConflict ? ServiceErrorCode.Conflict : ServiceErrorCode.InvalidRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
using Unit = HrynCo.NotificationService.Services.Core.Unit;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record DeleteServiceLanguageVersionsCommand(Guid ServiceId, Guid LanguageId, Guid Revision, int ExpectedVersionCount, bool ConfirmDelete) : IRequest<ServiceResult<Unit>>;
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class DeleteServiceLanguageVersionsHandler(
|
||||
IContextualSerilogLogger<DeleteServiceLanguageVersionsCommand> logger, INotificationServiceRepository services)
|
||||
: RequestHandler<DeleteServiceLanguageVersionsCommand, ServiceResult<Unit>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<Unit>> DoOnHandle(DeleteServiceLanguageVersionsCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!request.ConfirmDelete || request.ExpectedVersionCount < 0 || request.Revision == Guid.Empty)
|
||||
return Failure<Unit>("ConfirmDelete must be true; a nonnegative expectedVersionCount and nonempty service revision are required.", ServiceErrorCode.InvalidRequest);
|
||||
var service = await services.GetAsync(request.ServiceId, cancellationToken);
|
||||
if (service?.Languages.Any(l => l.Id == request.LanguageId) != true)
|
||||
return Failure<Unit>("Service language not found.", ServiceErrorCode.NotFound);
|
||||
try
|
||||
{
|
||||
await services.RemoveLanguageAsync(request.ServiceId, request.LanguageId, request.ExpectedVersionCount, request.Revision, cancellationToken);
|
||||
return Success(Unit.Value);
|
||||
}
|
||||
catch (EmailTemplateWriteException error)
|
||||
{
|
||||
return Failure<Unit>(error.Message, error.IsConflict ? ServiceErrorCode.Conflict : ServiceErrorCode.InvalidRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
using Unit = HrynCo.NotificationService.Services.Core.Unit;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record DeleteUnusedServiceLanguageCommand(Guid ServiceId, Guid LanguageId, Guid Revision) : IRequest<ServiceResult<Unit>>;
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class DeleteUnusedServiceLanguageHandler(
|
||||
IContextualSerilogLogger<DeleteUnusedServiceLanguageCommand> logger, INotificationServiceRepository services)
|
||||
: RequestHandler<DeleteUnusedServiceLanguageCommand, ServiceResult<Unit>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<Unit>> DoOnHandle(DeleteUnusedServiceLanguageCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (request.Revision == Guid.Empty)
|
||||
return Failure<Unit>("A nonempty service revision is required.", ServiceErrorCode.InvalidRequest);
|
||||
var service = await services.GetAsync(request.ServiceId, cancellationToken);
|
||||
var language = service?.Languages.SingleOrDefault(l => l.Id == request.LanguageId);
|
||||
if (language is null)
|
||||
return Failure<Unit>("Service language not found.", ServiceErrorCode.NotFound);
|
||||
if (language.VersionCount > 0)
|
||||
return Failure<Unit>("This language has template versions. Use delete-with-versions with explicit confirmation and the current count.", ServiceErrorCode.Conflict);
|
||||
try
|
||||
{
|
||||
// The repository repeats the zero-count and revision checks under its mutation lock.
|
||||
await services.RemoveLanguageAsync(request.ServiceId, request.LanguageId, 0, request.Revision, cancellationToken);
|
||||
return Success(Unit.Value);
|
||||
}
|
||||
catch (EmailTemplateWriteException error)
|
||||
{
|
||||
return Failure<Unit>(error.Message, error.IsConflict ? ServiceErrorCode.Conflict : ServiceErrorCode.InvalidRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record EmailTemplateDefinitionDto(Guid Id, Guid ServiceId, string ServiceName, string Key, Guid Revision,
|
||||
IReadOnlyList<TemplateVariableDto> Variables, IReadOnlyList<TemplateTranslationDto> Translations,
|
||||
DateTimeOffset Created, DateTimeOffset? Updated);
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class GetAllNotificationServicesHandler(
|
||||
IContextualSerilogLogger<GetAllNotificationServicesQuery> logger, INotificationServiceRepository services)
|
||||
: RequestHandler<GetAllNotificationServicesQuery, ServiceResult<IReadOnlyList<NotificationServiceDto>>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<IReadOnlyList<NotificationServiceDto>>> DoOnHandle(GetAllNotificationServicesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var all = await services.GetAllAsync(cancellationToken);
|
||||
return Success<IReadOnlyList<NotificationServiceDto>>(all.Select(NotificationServiceMapping.Map).ToList());
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record GetAllNotificationServicesQuery() : IRequest<ServiceResult<IReadOnlyList<NotificationServiceDto>>>;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class GetEmailTemplateDefinitionHandler(
|
||||
IContextualSerilogLogger<GetEmailTemplateDefinitionQuery> logger, IEmailTemplateDefinitionRepository definitions)
|
||||
: RequestHandler<GetEmailTemplateDefinitionQuery, ServiceResult<EmailTemplateDefinitionDto>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<EmailTemplateDefinitionDto>> DoOnHandle(GetEmailTemplateDefinitionQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var definition = await definitions.GetDefinitionAsync(request.ServiceId, request.Key, cancellationToken);
|
||||
return definition is null
|
||||
? Failure<EmailTemplateDefinitionDto>("Template definition not found.", ServiceErrorCode.NotFound)
|
||||
: Success(TemplateDefinitionMapping.Map(definition));
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record GetEmailTemplateDefinitionQuery(Guid ServiceId, string Key) : IRequest<ServiceResult<EmailTemplateDefinitionDto>>;
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class GetNotificationServiceHandler(
|
||||
IContextualSerilogLogger<GetNotificationServiceQuery> logger, INotificationServiceRepository services)
|
||||
: RequestHandler<GetNotificationServiceQuery, ServiceResult<NotificationServiceDto>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<NotificationServiceDto>> DoOnHandle(GetNotificationServiceQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (request.ServiceId is null && string.IsNullOrWhiteSpace(request.Name))
|
||||
return Failure<NotificationServiceDto>("An exact service name is required.", ServiceErrorCode.InvalidRequest);
|
||||
var service = request.ServiceId is Guid id
|
||||
? await services.GetAsync(id, cancellationToken)
|
||||
: await services.GetByNameAsync(request.Name!, cancellationToken);
|
||||
return service is null
|
||||
? Failure<NotificationServiceDto>("Service not found.", ServiceErrorCode.NotFound)
|
||||
: Success(NotificationServiceMapping.Map(service));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record GetNotificationServiceQuery(Guid? ServiceId, string? Name) : IRequest<ServiceResult<NotificationServiceDto>>;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class GetServiceTemplateDefinitionsHandler(
|
||||
IContextualSerilogLogger<GetServiceTemplateDefinitionsQuery> logger,
|
||||
INotificationServiceRepository services, IEmailTemplateDefinitionRepository definitions)
|
||||
: RequestHandler<GetServiceTemplateDefinitionsQuery, ServiceResult<IReadOnlyList<EmailTemplateDefinitionDto>>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<IReadOnlyList<EmailTemplateDefinitionDto>>> DoOnHandle(GetServiceTemplateDefinitionsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (await services.GetAsync(request.ServiceId, cancellationToken) is null)
|
||||
return Failure<IReadOnlyList<EmailTemplateDefinitionDto>>("Service not found.", ServiceErrorCode.NotFound);
|
||||
var all = await definitions.GetDefinitionsAsync(request.ServiceId, cancellationToken);
|
||||
return Success<IReadOnlyList<EmailTemplateDefinitionDto>>(all.Select(TemplateDefinitionMapping.Map).ToList());
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record GetServiceTemplateDefinitionsQuery(Guid ServiceId) : IRequest<ServiceResult<IReadOnlyList<EmailTemplateDefinitionDto>>>;
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record NotificationServiceDto(Guid Id, string Name, Guid Revision, IReadOnlyList<string> SupportedLanguageCodes, IReadOnlyList<ServiceLanguageDto> Languages);
|
||||
@@ -0,0 +1,10 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal static class NotificationServiceMapping
|
||||
{
|
||||
public static NotificationServiceDto Map(NotificationServiceInfo service) =>
|
||||
new(service.Id, service.Name, service.Revision, service.Languages.Select(l => l.Code).ToList(),
|
||||
service.Languages.Select(l => new ServiceLanguageDto(l.Id, l.Code, l.VersionCount)).ToList());
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record SaveNotificationServiceCommand(NotificationServiceInfo Service, bool IsNew) : IRequest<ServiceResult<NotificationServiceDto>>;
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class SaveNotificationServiceHandler(
|
||||
IContextualSerilogLogger<SaveNotificationServiceCommand> logger, INotificationServiceRepository services)
|
||||
: RequestHandler<SaveNotificationServiceCommand, ServiceResult<NotificationServiceDto>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<NotificationServiceDto>> DoOnHandle(SaveNotificationServiceCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!request.IsNew && request.Service.Revision == Guid.Empty)
|
||||
return Failure<NotificationServiceDto>("A nonempty service revision is required for update.", ServiceErrorCode.InvalidRequest);
|
||||
if (!request.IsNew && await services.GetAsync(request.Service.Id, cancellationToken) is null)
|
||||
return Failure<NotificationServiceDto>("Service not found.", ServiceErrorCode.NotFound);
|
||||
try
|
||||
{
|
||||
await services.SaveAsync(request.Service, request.IsNew, cancellationToken);
|
||||
var saved = await services.GetAsync(request.Service.Id, cancellationToken);
|
||||
return Success(NotificationServiceMapping.Map(saved!));
|
||||
}
|
||||
catch (EmailTemplateWriteException error)
|
||||
{
|
||||
return Failure<NotificationServiceDto>(error.Message, error.IsConflict ? ServiceErrorCode.Conflict : ServiceErrorCode.InvalidRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record ServiceLanguageDto(Guid Id, string Code, int VersionCount);
|
||||
@@ -0,0 +1,12 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal static class TemplateDefinitionMapping
|
||||
{
|
||||
public static EmailTemplateDefinitionDto Map(EmailTemplateDefinition definition) => new(
|
||||
definition.Id, definition.ServiceId, definition.ServiceName, definition.Key, definition.Revision,
|
||||
definition.Variables.Select(v => new TemplateVariableDto(v.Name, v.Required)).ToList(),
|
||||
definition.Languages.Select(t => new TemplateTranslationDto(t.Id, t.LanguageCode, t.Subject, t.HtmlBody, t.TextBody, t.Created, t.Updated)).ToList(),
|
||||
definition.Created, definition.Updated);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record TemplateTranslationDto(Guid Id, string LanguageCode, string Subject, string HtmlBody, string TextBody, DateTimeOffset Created, DateTimeOffset? Updated);
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record TemplateVariableDto(string Name, bool Required);
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using MediatR;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
public sealed record UpsertEmailTemplateDefinitionCommand(EmailTemplateDefinitionPatch Patch) : IRequest<ServiceResult<EmailTemplateDefinitionDto>>;
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using HrynCo.NotificationService.Services.Core;
|
||||
using HrynCo.NotificationService.Services.Logging;
|
||||
using static HrynCo.NotificationService.Services.Core.ServiceResultHelper;
|
||||
|
||||
namespace HrynCo.NotificationService.Services.TemplateDefinitions;
|
||||
|
||||
internal sealed class UpsertEmailTemplateDefinitionHandler(
|
||||
IContextualSerilogLogger<UpsertEmailTemplateDefinitionCommand> logger, IEmailTemplateDefinitionRepository definitions)
|
||||
: RequestHandler<UpsertEmailTemplateDefinitionCommand, ServiceResult<EmailTemplateDefinitionDto>>(logger)
|
||||
{
|
||||
protected override async Task<ServiceResult<EmailTemplateDefinitionDto>> DoOnHandle(UpsertEmailTemplateDefinitionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var definition = await definitions.UpsertDefinitionAsync(request.Patch, cancellationToken);
|
||||
return definition is null
|
||||
? Failure<EmailTemplateDefinitionDto>("Service not found.", ServiceErrorCode.NotFound)
|
||||
: Success(TemplateDefinitionMapping.Map(definition));
|
||||
}
|
||||
catch (EmailTemplateWriteException error)
|
||||
{
|
||||
return Failure<EmailTemplateDefinitionDto>(error.Message, error.IsConflict ? ServiceErrorCode.Conflict : ServiceErrorCode.InvalidRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user