Files
myAi/Apis/email-data/Migrations/20260528130652_SeedEmailTemplates.cs
T
claude e14a6a0f69
Build and Push Docker Images Staging / build (push) Successful in 8m22s
refactor(migrations): extract schema constant for clarity
2026-05-29 10:16:18 +03:00

179 lines
11 KiB
C#

using Microsoft.EntityFrameworkCore.Migrations;
using Email.Data;
#nullable disable
namespace Email.Data.Migrations
{
/// <inheritdoc />
public partial class SeedEmailTemplates : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
Seed(migrationBuilder);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
// Delete all seeded templates (only those we know we added)
migrationBuilder.DeleteData(
table: "EmailTemplates",
keyColumns: new[] { "Key", "Language" },
keyValues: new object[] { "email.html-shell.start", "*" });
}
private static void Seed(MigrationBuilder m)
{
const string op = "contact@myai.ro";
const string schema = MigrationConstants.SchemaName;
void Row(string key, string lang, string value, string description = "", string operatorCopy = "")
=> m.InsertData("EmailTemplates",
["Key", "Language", "Value", "Description", "OperatorCopy"],
[key, lang, value, description, operatorCopy],
schema);
// ── HTML shell (no operator copy — these are layout fragments, not addressable emails) ──
Row("email.html-shell.start", "*",
"<!DOCTYPE html>\n<html>\n<head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"></head>\n<body style=\"margin:0;padding:0;background:#f4f4f4;font-family:Arial,Helvetica,sans-serif\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"padding:20px 0\">\n <tr><td align=\"center\">\n <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\"\n style=\"background:#ffffff;border-radius:8px;max-width:600px\">\n <tr><td style=\"background:#2c5282;padding:24px 32px;border-radius:8px 8px 0 0\">\n <h1 style=\"margin:0;color:#ffffff;font-size:22px;font-weight:600\">myAi</h1>\n </td></tr>\n <tr><td style=\"padding:32px\">",
"Opening HTML shell fragment — wrapped around every HtmlBody before sending");
Row("email.html-shell.end", "*",
" </td></tr>\n <tr><td style=\"background:#f8f9fa;padding:16px 32px;text-align:center;\n color:#6c757d;font-size:12px;border-radius:0 0 8px 8px\">\n Automated message from myAi.\n </td></tr>\n </table>\n </td></tr>\n </table>\n</body>\n</html>",
"Closing HTML shell fragment — appended after every HtmlBody before sending");
// ── CV match result email ──
Row("email.match.subject", "en",
"MyAi.ro CV Match: {{score}}% - {{jobLabel}}",
"Subject for the CV match result email",
op);
Row("email.match.subject", "ro",
"MyAi.ro Potrivire CV: {{score}}% - {{jobLabel}}",
"Subiect email rezultat potrivire CV",
op);
Row("email.match.body", "en",
"<h2 style=\"margin:0 0 20px;color:#2c5282;font-size:20px\">CV Match Report</h2>" +
"<table cellpadding=\"10\" cellspacing=\"0\" style=\"width:100%;border-collapse:collapse;margin-bottom:24px\">" +
"<tr style=\"background:#f8f9fa\">" +
"<td style=\"font-weight:600;width:130px;border:1px solid #dee2e6;color:#495057\">CV ID</td>" +
"<td style=\"border:1px solid #dee2e6;font-family:monospace;font-size:13px\">{{cvDocumentId}}</td>" +
"</tr>" +
"<tr>" +
"<td style=\"font-weight:600;border:1px solid #dee2e6;color:#495057\">Job</td>" +
"<td style=\"border:1px solid #dee2e6\">{{jobLabel}}</td>" +
"</tr>" +
"<tr style=\"background:#f8f9fa\">" +
"<td style=\"font-weight:600;border:1px solid #dee2e6;color:#495057\">URL</td>" +
"<td style=\"border:1px solid #dee2e6\"><a href=\"{{jobUrl}}\" style=\"color:#2c5282\">{{jobUrl}}</a></td>" +
"</tr>" +
"<tr>" +
"<td style=\"font-weight:600;border:1px solid #dee2e6;color:#495057\">Score</td>" +
"<td style=\"border:1px solid #dee2e6;font-size:26px;font-weight:700;color:#28a745\">{{score}}%</td>" +
"</tr>" +
"</table>" +
"<h3 style=\"color:#2c5282;border-bottom:2px solid #e9ecef;padding-bottom:6px\">Summary</h3>" +
"<p style=\"color:#495057;line-height:1.7\">{{summary}}</p>" +
"<h3 style=\"color:#2c5282;border-bottom:2px solid #e9ecef;padding-bottom:6px\">Strengths</h3>{{strengths}}" +
"<h3 style=\"color:#2c5282;border-bottom:2px solid #e9ecef;padding-bottom:6px\">Gaps</h3>{{gaps}}" +
"<h3 style=\"color:#2c5282;border-bottom:2px solid #e9ecef;padding-bottom:6px\">Recommendations</h3>{{recommendations}}",
"Body for the CV match result email",
op);
Row("email.match.body", "ro",
"<h2 style=\"margin:0 0 20px;color:#2c5282;font-size:20px\">Raport Potrivire CV</h2>" +
"<table cellpadding=\"10\" cellspacing=\"0\" style=\"width:100%;border-collapse:collapse;margin-bottom:24px\">" +
"<tr style=\"background:#f8f9fa\">" +
"<td style=\"font-weight:600;width:130px;border:1px solid #dee2e6;color:#495057\">ID Document CV</td>" +
"<td style=\"border:1px solid #dee2e6;font-family:monospace;font-size:13px\">{{cvDocumentId}}</td>" +
"</tr>" +
"<tr>" +
"<td style=\"font-weight:600;border:1px solid #dee2e6;color:#495057\">Job</td>" +
"<td style=\"border:1px solid #dee2e6\">{{jobLabel}}</td>" +
"</tr>" +
"<tr style=\"background:#f8f9fa\">" +
"<td style=\"font-weight:600;border:1px solid #dee2e6;color:#495057\">URL</td>" +
"<td style=\"border:1px solid #dee2e6\"><a href=\"{{jobUrl}}\" style=\"color:#2c5282\">{{jobUrl}}</a></td>" +
"</tr>" +
"<tr>" +
"<td style=\"font-weight:600;border:1px solid #dee2e6;color:#495057\">Scor</td>" +
"<td style=\"border:1px solid #dee2e6;font-size:26px;font-weight:700;color:#28a745\">{{score}}%</td>" +
"</tr>" +
"</table>" +
"<h3 style=\"color:#2c5282;border-bottom:2px solid #e9ecef;padding-bottom:6px\">Rezumat</h3>" +
"<p style=\"color:#495057;line-height:1.7\">{{summary}}</p>" +
"<h3 style=\"color:#2c5282;border-bottom:2px solid #e9ecef;padding-bottom:6px\">Puncte forte</h3>{{strengths}}" +
"<h3 style=\"color:#2c5282;border-bottom:2px solid #e9ecef;padding-bottom:6px\">Lipsuri</h3>{{gaps}}" +
"<h3 style=\"color:#2c5282;border-bottom:2px solid #e9ecef;padding-bottom:6px\">Recomandări</h3>{{recommendations}}",
"Corpul emailului pentru rezultatul potrivirii CV",
op);
Row("email.match.job-search-footer", "en",
"<div style=\"background:#f0f4f8;border-left:4px solid #2c5282;padding:16px;margin-top:24px;border-radius:4px\">" +
"<p style=\"margin:0;color:#495057\">" +
"Want to find matching jobs automatically? " +
"<a href=\"{{jobSearchLink}}\" style=\"color:#2c5282;font-weight:600\">Start a job search &#8594;</a><br>" +
"<small style=\"color:#6c757d\">Link valid for {{expiryDays}} days.</small>" +
"</p>" +
"</div>",
"Job search CTA appended to match result email",
op);
Row("email.match.job-search-footer", "ro",
"<div style=\"background:#f0f4f8;border-left:4px solid #2c5282;padding:16px;margin-top:24px;border-radius:4px\">" +
"<p style=\"margin:0;color:#495057\">" +
"Vrei să găsești joburi potrivite automat? " +
"<a href=\"{{jobSearchLink}}\" style=\"color:#2c5282;font-weight:600\">Pornește o căutare de joburi &#8594;</a><br>" +
"<small style=\"color:#6c757d\">Link valabil {{expiryDays}} zile.</small>" +
"</p>" +
"</div>",
"CTA cautare joburi adaugat la emailul de potrivire CV",
op);
// ── Job search results email ──
Row("email.search-results.subject", "en",
"MyAi.ro: {{count}} jobs matching your CV",
"Subject for job search results email",
op);
Row("email.search-results.subject", "ro",
"MyAi.ro: {{count}} joburi potrivite CV-ului tau",
"Subiect email rezultate cautare joburi",
op);
Row("email.search-results.body", "en",
"<h2 style=\"margin:0 0 16px;color:#2c5282\">Job Search Results</h2>" +
"<p style=\"color:#495057\">Found <strong>{{count}}</strong> matching job(s):</p>" +
"{{items}}",
"Body preamble for job search results email",
op);
Row("email.search-results.body", "ro",
"<h2 style=\"margin:0 0 16px;color:#2c5282\">Rezultate Căutare Joburi</h2>" +
"<p style=\"color:#495057\">Am găsit <strong>{{count}}</strong> job(uri) potrivite:</p>" +
"{{items}}",
"Corpul emailului de rezultate cautare joburi",
op);
Row("email.search-results.empty", "en",
"<div style=\"text-align:center;padding:32px;color:#6c757d\">" +
"<p style=\"font-size:18px;margin:0 0 8px;color:#495057\">No matching jobs found</p>" +
"<p style=\"margin:0\">Your job search completed but no matching jobs were found. Try again later or adjust your CV.</p>" +
"</div>",
"No results message for job search results email",
op);
Row("email.search-results.empty", "ro",
"<div style=\"text-align:center;padding:32px;color:#6c757d\">" +
"<p style=\"font-size:18px;margin:0 0 8px;color:#495057\">Niciun job potrivit găsit</p>" +
"<p style=\"margin:0\">Căutarea s-a finalizat dar nu au fost găsite joburi potrivite. Încearcă mai târziu sau ajustează CV-ul.</p>" +
"</div>",
"Mesaj fara rezultate pentru emailul de cautare joburi",
op);
}
}
}