Restore AddHtmlShellTemplates migration with copyright symbol fix

- Restored email.html-shell.start and email.html-shell.end templates to InitialSchema migration
- Fixed copyright symbol: changed © to © HTML entity (avoids encoding issues in database)
- These templates wrap plain text email bodies in proper HTML structure
- Migration runs after InitialSchema, seeding the HTML wrapper templates

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 18:37:26 +03:00
parent 9cb38e5bc8
commit f9530b168f
2 changed files with 36 additions and 35 deletions
@@ -1,4 +1,4 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using Email.Data; using Email.Data;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -18,7 +18,7 @@ namespace Email.Data.Migrations
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasDefaultSchema("email") .HasDefaultSchema("email")
.HasAnnotation("ProductVersion", "10.0.7") .HasAnnotation("ProductVersion", "10.0.7")
@@ -27,43 +27,44 @@ namespace Email.Data.Migrations
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Email.Data.Entities.EmailTemplateEntity", b => modelBuilder.Entity("Email.Data.Entities.EmailTemplateEntity", b =>
{ {
b.Property<string>("Key") b.Property<string>("Key")
.HasMaxLength(128) .HasMaxLength(128)
.HasColumnType("nvarchar(128)"); .HasColumnType("nvarchar(128)");
b.Property<string>("Language") b.Property<string>("Language")
.HasMaxLength(8) .HasMaxLength(8)
.HasColumnType("nvarchar(8)"); .HasColumnType("nvarchar(8)");
b.Property<string>("Description") b.Property<string>("Description")
.IsRequired() .IsRequired()
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasMaxLength(500) .HasMaxLength(500)
.HasColumnType("nvarchar(500)") .HasColumnType("nvarchar(500)")
.HasDefaultValue(""); .HasDefaultValue("");
b.Property<string>("OperatorCopy") b.Property<string>("OperatorCopy")
.IsRequired() .IsRequired()
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasMaxLength(256) .HasMaxLength(256)
.HasColumnType("nvarchar(256)") .HasColumnType("nvarchar(256)")
.HasDefaultValue(""); .HasDefaultValue("");
b.Property<DateTime>("UpdatedAt") b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("datetime2") .HasColumnType("datetime2")
.HasDefaultValueSql("SYSUTCDATETIME()"); .HasDefaultValueSql("SYSUTCDATETIME()");
b.Property<string>("Value") b.Property<string>("Value")
.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.HasKey("Key", "Language"); b.HasKey("Key", "Language");
b.ToTable("Templates", "email"); b.ToTable("Templates", "email");
}); });
#pragma warning restore 612, 618
#pragma warning restore 612, 618
} }
} }
} }
@@ -1,4 +1,4 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Email.Data; using Email.Data;
#nullable disable #nullable disable
@@ -15,14 +15,14 @@ namespace Email.Data.Migrations
migrationBuilder.InsertData( migrationBuilder.InsertData(
table: "Templates", table: "Templates",
columns: new[] { "Key", "Language", "Value", "Description" }, columns: new[] { "Key", "Language", "Value", "Description" },
values: new object[] { "email.html-shell.start", "*", "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif; margin: 0; padding: 0; background-color: #f5f5f5; }\n .email-container { max-width: 600px; margin: 0 auto; background-color: #ffffff; }\n .email-header { background-color: #2c5282; color: white; padding: 24px; text-align: center; }\n .email-header h1 { margin: 0; font-size: 24px; font-weight: 600; }\n .email-body { padding: 24px; }\n .email-footer { background-color: #f8f9fa; padding: 16px; text-align: center; color: #6c757d; font-size: 12px; border-top: 1px solid #dee2e6; }\n </style>\n</head>\n<body>\n <div class=\"email-container\">\n <div class=\"email-header\">\n <h1>MyAi.ro</h1>\n </div>\n <div class=\"email-body\">\n", "Opening HTML wrapper for branded emails (blue header, white content area)" }, values: new object[] { "email.html-shell.start", "*", "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif; margin: 0; padding: 0; background-color: #f5f5f5; }\n .email-container { max-width: 600px; margin: 0 auto; background-color: #ffffff; }\n .email-header { background-color: #2c5282; color: white; padding: 24px; text-align: center; }\n .email-header h1 { margin: 0; font-size: 24px; font-weight: 600; }\n .email-body { padding: 24px; }\n .email-footer { background-color: #f8f9fa; padding: 16px; text-align: center; color: #6c757d; font-size: 12px; border-top: 1px solid #dee2e6; }\n </style>\n</head>\n<body>\n <div class=\"email-container\">\n <div class=\"email-header\">\n <h1>MyAi.ro</h1>\n </div>\n <div class=\"email-body\">\n", "Opening HTML wrapper for branded emails (blue header, white content area)" },
schema: MigrationConstants.SchemaName); schema: MigrationConstants.SchemaName);
// HTML email shell — closing tags (footer) // HTML email shell — closing tags (footer)
migrationBuilder.InsertData( migrationBuilder.InsertData(
table: "Templates", table: "Templates",
columns: new[] { "Key", "Language", "Value", "Description" }, columns: new[] { "Key", "Language", "Value", "Description" },
values: new object[] { "email.html-shell.end", "*", " </div>\n <div class=\"email-footer\">\n <p>© 2026 MyAi.ro. All rights reserved.</p>\n </div>\n </div>\n</body>\n</html>\n", "Closing HTML wrapper for branded emails (footer and closing tags)" }, values: new object[] { "email.html-shell.end", "*", " </div>\n <div class=\"email-footer\">\n <p>&copy; 2026 MyAi.ro. All rights reserved.</p>\n </div>\n </div>\n</body>\n</html>\n", "Closing HTML wrapper for branded emails (footer and closing tags)" },
schema: MigrationConstants.SchemaName); schema: MigrationConstants.SchemaName);
} }