feat: consume transactional email notifications
Add contract validation, SMTP delivery results, terminal failure context, neutral development seeding, and local Docker setup. Ref: IT-1033
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
namespace HrynCo.NotificationService.Migrator;
|
||||
|
||||
using HrynCo.NotificationService.DAL.Abstract.Providers;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
internal sealed class DevelopmentDataSeeder
|
||||
{
|
||||
internal const string DefaultServiceName = "TestService";
|
||||
internal const string DefaultLanguageCode = "en";
|
||||
|
||||
private readonly IEmailChannelRepository _channels;
|
||||
private readonly IEmailTemplateRepository _templates;
|
||||
private readonly ILogger<DevelopmentDataSeeder> _logger;
|
||||
|
||||
public DevelopmentDataSeeder(
|
||||
IEmailChannelRepository channels,
|
||||
IEmailTemplateRepository templates,
|
||||
ILogger<DevelopmentDataSeeder> logger)
|
||||
{
|
||||
_channels = channels;
|
||||
_templates = templates;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task SeedAsync(string serviceName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(serviceName))
|
||||
throw new InvalidOperationException("Development seed service name is not configured.");
|
||||
|
||||
await SeedMailpitChannelAsync(serviceName, cancellationToken);
|
||||
|
||||
foreach (EmailTemplate template in CreateTemplates(serviceName))
|
||||
{
|
||||
EmailTemplate? existing = await _templates.GetAsync(
|
||||
template.ServiceName, template.Key, template.LanguageCode, cancellationToken);
|
||||
|
||||
if (existing is not null)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"Development email template already exists; leaving it unchanged [ServiceName={ServiceName}, Key={TemplateKey}, LanguageCode={LanguageCode}]",
|
||||
template.ServiceName, template.Key, template.LanguageCode);
|
||||
continue;
|
||||
}
|
||||
|
||||
await _templates.AddAsync(template, cancellationToken);
|
||||
_logger.LogInformation(
|
||||
"Created development email template [ServiceName={ServiceName}, Key={TemplateKey}, LanguageCode={LanguageCode}]",
|
||||
template.ServiceName, template.Key, template.LanguageCode);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SeedMailpitChannelAsync(string serviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
IReadOnlyList<EmailChannel> existingChannels = await _channels.GetByServiceAsync(
|
||||
serviceName, cancellationToken);
|
||||
|
||||
if (existingChannels.Count > 0)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"Development email channel already exists; leaving all channels unchanged [ServiceName={ServiceName}]",
|
||||
serviceName);
|
||||
return;
|
||||
}
|
||||
|
||||
var channel = new EmailChannel
|
||||
{
|
||||
ServiceName = serviceName,
|
||||
Priority = 1,
|
||||
EmailChannelType = EmailChannelType.Smtp,
|
||||
Settings = new SmtpChannelSettings
|
||||
{
|
||||
Host = "mailpit",
|
||||
Port = 1025,
|
||||
Username = string.Empty,
|
||||
Password = string.Empty,
|
||||
UseSsl = false,
|
||||
FromEmail = "no-reply@local.hrynco.test",
|
||||
FromName = "HrynCo Development"
|
||||
},
|
||||
WarnThresholdPercent = 90,
|
||||
IsActive = true,
|
||||
Created = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
await _channels.AddAsync(channel, cancellationToken);
|
||||
_logger.LogInformation(
|
||||
"Created Mailpit development email channel [ServiceName={ServiceName}]",
|
||||
serviceName);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<EmailTemplate> CreateTemplates(string serviceName)
|
||||
{
|
||||
DateTimeOffset created = DateTimeOffset.UtcNow;
|
||||
|
||||
return
|
||||
[
|
||||
new EmailTemplate
|
||||
{
|
||||
ServiceName = serviceName,
|
||||
Key = "TestEmail",
|
||||
LanguageCode = DefaultLanguageCode,
|
||||
Subject = "Test notification",
|
||||
HtmlBody = "<p>Hello {{RecipientName}},</p><p>{{Message}}</p>",
|
||||
TextBody = "Hello {{RecipientName}}, {{Message}}",
|
||||
Variables =
|
||||
[
|
||||
new EmailTemplateVariable { Name = "RecipientName", Required = true },
|
||||
new EmailTemplateVariable { Name = "Message", Required = true }
|
||||
],
|
||||
Created = created
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user