Adds transactional outbox and email verification
Implements outbox pattern for reliable message delivery Adds email verification flow with Postmark integration Enhances account registration with secure token generation Introduces background processing for asynchronous email sending Implements database-level notification mechanism for message processing
This commit is contained in:
parent
88812177a9
commit
54b057886c
35 changed files with 1174 additions and 358 deletions
14
Core/Email/EmailModule.cs
Normal file
14
Core/Email/EmailModule.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using Autofac;
|
||||
|
||||
namespace PlanTempus.Core.Email;
|
||||
|
||||
public class EmailModule : Module
|
||||
{
|
||||
public required PostmarkConfiguration PostmarkConfiguration { get; set; }
|
||||
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterInstance(PostmarkConfiguration).AsSelf().SingleInstance();
|
||||
builder.RegisterType<PostmarkEmailService>().As<IEmailService>().SingleInstance();
|
||||
}
|
||||
}
|
||||
10
Core/Email/IEmailService.cs
Normal file
10
Core/Email/IEmailService.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#nullable enable
|
||||
|
||||
namespace PlanTempus.Core.Email;
|
||||
|
||||
public interface IEmailService
|
||||
{
|
||||
Task<EmailResult> SendVerificationEmailAsync(string toEmail, string userName, string verifyUrl);
|
||||
}
|
||||
|
||||
public record EmailResult(bool Success, string? MessageId, string? ErrorMessage);
|
||||
10
Core/Email/PostmarkConfiguration.cs
Normal file
10
Core/Email/PostmarkConfiguration.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#nullable enable
|
||||
|
||||
namespace PlanTempus.Core.Email;
|
||||
|
||||
public class PostmarkConfiguration
|
||||
{
|
||||
public required string ServerToken { get; set; }
|
||||
public required string FromEmail { get; set; }
|
||||
public string? TestToEmail { get; set; }
|
||||
}
|
||||
41
Core/Email/PostmarkEmailService.cs
Normal file
41
Core/Email/PostmarkEmailService.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using PostmarkDotNet;
|
||||
|
||||
namespace PlanTempus.Core.Email;
|
||||
|
||||
public class PostmarkEmailService : IEmailService
|
||||
{
|
||||
private readonly PostmarkConfiguration _config;
|
||||
private readonly PostmarkClient _client;
|
||||
|
||||
public PostmarkEmailService(PostmarkConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
_client = new PostmarkClient(config.ServerToken);
|
||||
}
|
||||
|
||||
public async Task<EmailResult> SendVerificationEmailAsync(string toEmail, string userName, string verifyUrl)
|
||||
{
|
||||
var recipient = _config.TestToEmail ?? toEmail;
|
||||
|
||||
var message = new TemplatedPostmarkMessage
|
||||
{
|
||||
From = _config.FromEmail,
|
||||
To = recipient,
|
||||
TemplateAlias = "code-your-own-1",
|
||||
TemplateModel = new Dictionary<string, object>
|
||||
{
|
||||
{ "USER_NAME", userName },
|
||||
{ "VERIFY_URL", verifyUrl }
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client.SendMessageAsync(message);
|
||||
|
||||
if (response.Status == PostmarkStatus.Success)
|
||||
{
|
||||
return new EmailResult(true, response.MessageID.ToString(), null);
|
||||
}
|
||||
|
||||
return new EmailResult(false, null, response.Message);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue