From e17f17b566570c7c6645f6aab9a1763fecc8c0c5 Mon Sep 17 00:00:00 2001 From: claude Date: Thu, 28 May 2026 08:45:18 +0300 Subject: [PATCH] feat(cv-search-job): replace MyAiDbContext+ITemplateService with IEmailTemplateService - Add ProjectReference to email-api-data; remove myai-data reference - Program.cs: register EmailApiDbContext (no migrate), IEmailTemplateRepository (scoped), IEmailTemplateService (singleton); remove MyAiDbContext + ITemplateService registrations and their migration call - CvSearchEmailSender: inject IEmailTemplateService; replace _config["Contact:ToEmail"] with GetOperatorCopy("email.search-results.subject") for operator copy logic; remove IConfiguration injection - docker-compose: remove Contact__ToEmail from cv-search-job service block; add Database__* env vars to email-api service (needed for EmailApiDbContext) Co-Authored-By: Claude Sonnet 4.6 --- Jobs/cv-search-job/Program.cs | 21 +++++++-------- .../Services/CvSearchEmailSender.cs | 26 ++++++++----------- Jobs/cv-search-job/cv-search-job.csproj | 2 +- docker-compose/docker-compose.yml | 9 +++++-- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Jobs/cv-search-job/Program.cs b/Jobs/cv-search-job/Program.cs index 59abf8d..c273d20 100644 --- a/Jobs/cv-search-job/Program.cs +++ b/Jobs/cv-search-job/Program.cs @@ -3,6 +3,10 @@ using CvMatcher.Models.Settings; using CvSearch.Data; using CvSearchJob.Clients; using CvSearchJob.Services; +using EmailApi.Data; +using EmailApi.Data.Repositories; +using EmailApi.Data.Repositories.Contracts; +using EmailApi.Data.Services; using EmailApi.Models.Clients; using CvSearchJob.Tasks; using JobScheduler.Scheduling; @@ -10,8 +14,6 @@ using JobScheduler.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using MyAi.Data; -using MyAi.Data.Services; using Refit; using Serilog; using Common.Settings; @@ -54,16 +56,18 @@ try client.DefaultRequestHeaders.Add("X-Internal-Api-Key", key); }); - builder.Services.AddDbContext(options => + builder.Services.AddDbContext(options => { var connectionString = builder.Services.GetConfiguredDbConnectionString(builder.Configuration); options.UseSqlServer(connectionString, sql => { - sql.MigrationsAssembly("myai-data"); - sql.MigrationsHistoryTable(MyAiDbContext.MigrationTableName, MyAiDbContext.SchemaName); + sql.MigrationsHistoryTable(EmailApiDbContext.MigrationTableName, EmailApiDbContext.SchemaName); + sql.MigrationsAssembly("email-api-data"); }); }); - builder.Services.AddSingleton(); + + builder.Services.AddScoped(); + builder.Services.AddSingleton(); builder.Services.AddRefitClient() .ConfigureHttpClient((sp, client) => @@ -98,11 +102,6 @@ try var db = scope.ServiceProvider.GetRequiredService(); db.Database.Migrate(); } - using (var scope = host.Services.CreateScope()) - { - var db = scope.ServiceProvider.GetRequiredService(); - db.Database.Migrate(); - } Log.Information("{Service} startup complete. Background scheduler is running.", ServiceName); await host.RunAsync(); diff --git a/Jobs/cv-search-job/Services/CvSearchEmailSender.cs b/Jobs/cv-search-job/Services/CvSearchEmailSender.cs index 8eeedc6..89be54f 100644 --- a/Jobs/cv-search-job/Services/CvSearchEmailSender.cs +++ b/Jobs/cv-search-job/Services/CvSearchEmailSender.cs @@ -1,29 +1,25 @@ using CvMatcher.Models.Responses; using CvSearch.Data.Entities; +using EmailApi.Data.Services; using EmailApi.Models.Clients; using EmailApi.Models.Requests; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using MyAi.Data.Services; namespace CvSearchJob.Services; public sealed class CvSearchEmailSender { private readonly IEmailApiClient _emailApi; - private readonly ITemplateService _templates; - private readonly IConfiguration _config; + private readonly IEmailTemplateService _emailTemplates; private readonly ILogger _logger; public CvSearchEmailSender( IEmailApiClient emailApi, - ITemplateService templates, - IConfiguration config, + IEmailTemplateService emailTemplates, ILogger logger) { _emailApi = emailApi; - _templates = templates; - _config = config; + _emailTemplates = emailTemplates; _logger = logger; } @@ -34,18 +30,18 @@ public sealed class CvSearchEmailSender string language, CancellationToken ct) { - var contactToEmail = _config["Contact:ToEmail"]; + var operatorCopy = _emailTemplates.GetOperatorCopy("email.search-results.subject", language); var recipients = new List(); if (!string.IsNullOrWhiteSpace(toEmail)) recipients.Add(toEmail); - if (!string.IsNullOrWhiteSpace(contactToEmail) && - !recipients.Any(r => string.Equals(r, contactToEmail, StringComparison.OrdinalIgnoreCase))) - recipients.Add(contactToEmail); + if (!string.IsNullOrWhiteSpace(operatorCopy) && + !recipients.Any(r => string.Equals(r, operatorCopy, StringComparison.OrdinalIgnoreCase))) + recipients.Add(operatorCopy); if (recipients.Count == 0) return; var htmlBody = BuildBody(results, language); - var subject = _templates.Render("email.search-results.subject", language, + var subject = _emailTemplates.Render("email.search-results.subject", language, ("count", results.Count.ToString())); try @@ -71,7 +67,7 @@ public sealed class CvSearchEmailSender private string BuildBody(IReadOnlyList results, string language) { if (results.Count == 0) - return _templates.Get("email.search-results.empty", language); + return _emailTemplates.Get("email.search-results.empty", language); var items = new System.Text.StringBuilder(); for (int i = 0; i < results.Count; i++) @@ -91,7 +87,7 @@ public sealed class CvSearchEmailSender """); } - return _templates.Render("email.search-results.body", language, + return _emailTemplates.Render("email.search-results.body", language, ("count", results.Count.ToString()), ("items", items.ToString())); } diff --git a/Jobs/cv-search-job/cv-search-job.csproj b/Jobs/cv-search-job/cv-search-job.csproj index 94657fc..c0bd6ca 100644 --- a/Jobs/cv-search-job/cv-search-job.csproj +++ b/Jobs/cv-search-job/cv-search-job.csproj @@ -21,12 +21,12 @@ + - diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index e873de2..a371f4f 100644 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -108,6 +108,13 @@ services: - ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080} - APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.staging} + - Database__Host=${Database__Host:-sqlserver} + - Database__Port=${Database__Port:-1433} + - Database__Name=${Database__Name:-MyAiDb} + - Database__User=${Database__User:-sa} + - Database__Password=${Database__Password:-} + - Database__TrustServerCertificate=${Database__TrustServerCertificate:-true} + - InternalApi__ApiKey=${EmailApi__InternalApiKey:-} - InternalApi__RequireApiKey=true @@ -261,8 +268,6 @@ services: - EmailApi__BaseUrl=${EmailApi__BaseUrl:-http://email-api:8080} - EmailApi__InternalApiKey=${EmailApi__InternalApiKey:-} - - Contact__ToEmail=${Contact__ToEmail:-} - - FileStorage__Path=${FileStorage__Path:-Files} - JobSearch__Enabled=${JobSearch__Enabled:-true}