feat(email-api): wire email-api-data; load html shell templates from DB
- Add ProjectReference to email-api-data - Register EmailApiDbContext + run migrations on startup - Register IEmailTemplateRepository (scoped) and IEmailTemplateService (singleton) - SmtpEmailDispatcher: inject IEmailTemplateService; replace hardcoded HtmlShellStart/HtmlShellEnd string constants with DB template lookups (email.html-shell.start / email.html-shell.end, language "*") Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
using System.Reflection;
|
||||
using EmailApi.Data;
|
||||
using EmailApi.Data.Repositories;
|
||||
using EmailApi.Data.Repositories.Contracts;
|
||||
using EmailApi.Data.Services;
|
||||
using EmailApi.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Models.Settings;
|
||||
using Serilog;
|
||||
using StartupHelpers;
|
||||
@@ -24,6 +29,19 @@ try
|
||||
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));
|
||||
builder.Services.Configure<FileStorageSettings>(builder.Configuration.GetSection("FileStorage"));
|
||||
|
||||
builder.Services.AddDbContext<EmailApiDbContext>(options =>
|
||||
{
|
||||
var connectionString = builder.Services.GetConfiguredDbConnectionString(builder.Configuration);
|
||||
options.UseSqlServer(connectionString, sql =>
|
||||
{
|
||||
sql.MigrationsHistoryTable(EmailApiDbContext.MigrationTableName, EmailApiDbContext.SchemaName);
|
||||
sql.MigrationsAssembly("email-api-data");
|
||||
});
|
||||
});
|
||||
|
||||
builder.Services.AddScoped<IEmailTemplateRepository, EfEmailTemplateRepository>();
|
||||
builder.Services.AddSingleton<IEmailTemplateService, EmailTemplateService>();
|
||||
|
||||
builder.Services.AddScoped<SmtpEmailDispatcher>();
|
||||
|
||||
var app = builder.Build();
|
||||
@@ -40,6 +58,13 @@ try
|
||||
app.UseAuthorization();
|
||||
app.MapControllers();
|
||||
|
||||
Log.Information("Running EF Core migrations if any");
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<EmailApiDbContext>();
|
||||
db.Database.Migrate();
|
||||
}
|
||||
|
||||
Log.Information("{Service} startup complete. Listening for requests...", ServiceName);
|
||||
app.Run();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using EmailApi.Data.Services;
|
||||
using EmailApi.Models.Requests;
|
||||
using MailKit.Net.Smtp;
|
||||
using MailKit.Security;
|
||||
@@ -11,44 +12,19 @@ public sealed class SmtpEmailDispatcher
|
||||
{
|
||||
private readonly SmtpSettings _smtp;
|
||||
private readonly FileStorageSettings _fileStorage;
|
||||
private readonly IEmailTemplateService _templates;
|
||||
private readonly ILogger<SmtpEmailDispatcher> _log;
|
||||
private readonly string _environmentName;
|
||||
|
||||
private static readonly string HtmlShellStart = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head>
|
||||
<body style="margin:0;padding:0;background:#f4f4f4;font-family:Arial,Helvetica,sans-serif">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" style="padding:20px 0">
|
||||
<tr><td align="center">
|
||||
<table width="600" cellpadding="0" cellspacing="0"
|
||||
style="background:#ffffff;border-radius:8px;max-width:600px">
|
||||
<tr><td style="background:#2c5282;padding:24px 32px;border-radius:8px 8px 0 0">
|
||||
<h1 style="margin:0;color:#ffffff;font-size:22px;font-weight:600">myAi</h1>
|
||||
</td></tr>
|
||||
<tr><td style="padding:32px">
|
||||
""";
|
||||
|
||||
private static readonly string HtmlShellEnd = """
|
||||
</td></tr>
|
||||
<tr><td style="background:#f8f9fa;padding:16px 32px;text-align:center;
|
||||
color:#6c757d;font-size:12px;border-radius:0 0 8px 8px">
|
||||
Automated message from myAi.
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
""";
|
||||
|
||||
public SmtpEmailDispatcher(
|
||||
IOptions<SmtpSettings> smtp,
|
||||
IOptions<FileStorageSettings> fileStorage,
|
||||
IEmailTemplateService templates,
|
||||
ILogger<SmtpEmailDispatcher> log)
|
||||
{
|
||||
_smtp = smtp.Value;
|
||||
_fileStorage = fileStorage.Value;
|
||||
_templates = templates;
|
||||
_log = log;
|
||||
_environmentName = Environment.GetEnvironmentVariable("APP_ENVIRONMENT_NAME") ?? "Development";
|
||||
}
|
||||
@@ -72,9 +48,12 @@ public sealed class SmtpEmailDispatcher
|
||||
|
||||
msg.Subject = $"[{_environmentName}] {req.Subject}".Trim();
|
||||
|
||||
var shellStart = _templates.Get("email.html-shell.start", "*");
|
||||
var shellEnd = _templates.Get("email.html-shell.end", "*");
|
||||
|
||||
var builder = new BodyBuilder
|
||||
{
|
||||
HtmlBody = HtmlShellStart + req.HtmlBody + HtmlShellEnd
|
||||
HtmlBody = shellStart + req.HtmlBody + shellEnd
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.AttachmentPath))
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<ProjectReference Include="..\..\Helpers\startup-helpers\startup-helpers.csproj" />
|
||||
<ProjectReference Include="..\api-models\api-models.csproj" />
|
||||
<ProjectReference Include="..\common\common.csproj" />
|
||||
<ProjectReference Include="..\email-api-data\email-api-data.csproj" />
|
||||
<ProjectReference Include="..\email-api-models\email-api-models.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user