Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 90f540139a |
@@ -3,7 +3,7 @@ name: Build and Push Docker Images Staging
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- production
|
- staging
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GIT_HOST: git.easysoft.ro
|
GIT_HOST: git.easysoft.ro
|
||||||
@@ -16,7 +16,7 @@ env:
|
|||||||
CV_CLEANUP_JOB_IMAGE: apps/myai-cv-cleanup-job
|
CV_CLEANUP_JOB_IMAGE: apps/myai-cv-cleanup-job
|
||||||
CV_SEARCH_JOB_IMAGE: apps/myai-cv-search-job
|
CV_SEARCH_JOB_IMAGE: apps/myai-cv-search-job
|
||||||
PAGE_FETCHER_API_IMAGE: apps/myai-page-fetcher-api
|
PAGE_FETCHER_API_IMAGE: apps/myai-page-fetcher-api
|
||||||
IMAGE_TAG: production
|
IMAGE_TAG: staging
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public sealed class CvMatcherController : ControllerBase
|
|||||||
var attachmentPath = TryGetCachedCvPath(request.CvDocumentId);
|
var attachmentPath = TryGetCachedCvPath(request.CvDocumentId);
|
||||||
var jobLabel = !string.IsNullOrWhiteSpace(request.JobUrl)
|
var jobLabel = !string.IsNullOrWhiteSpace(request.JobUrl)
|
||||||
? request.JobUrl
|
? request.JobUrl
|
||||||
: "Manual job description";
|
: _emailSender.GetManualJobLabel(language);
|
||||||
|
|
||||||
var language = NormalizeLanguage(request.Language);
|
var language = NormalizeLanguage(request.Language);
|
||||||
|
|
||||||
|
|||||||
@@ -61,5 +61,11 @@ namespace Api.Services.Contracts
|
|||||||
/// <param name="expiryDays">Number of days until the job-search link expires (shown in the footer copy).</param>
|
/// <param name="expiryDays">Number of days until the job-search link expires (shown in the footer copy).</param>
|
||||||
/// <returns>Rendered HTML body string.</returns>
|
/// <returns>Rendered HTML body string.</returns>
|
||||||
string BuildMatchEmailBody(string cvDocumentId, JobMatchResponse result, string? jobLabel, string language, string? jobSearchLink = null, int expiryDays = 7);
|
string BuildMatchEmailBody(string cvDocumentId, JobMatchResponse result, string? jobLabel, string language, string? jobSearchLink = null, int expiryDays = 7);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the localised label for a manually-entered job description (no URL provided).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="language">Two-letter language code.</param>
|
||||||
|
string GetManualJobLabel(string language);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,4 +239,7 @@ public sealed class EmailApiEmailSender : IEmailSender
|
|||||||
_emailTemplates.Render("email.match.subject", language,
|
_emailTemplates.Render("email.match.subject", language,
|
||||||
("score", score.ToString()),
|
("score", score.ToString()),
|
||||||
("jobLabel", jobLabel ?? "Job"));
|
("jobLabel", jobLabel ?? "Job"));
|
||||||
|
|
||||||
|
public string GetManualJobLabel(string language) =>
|
||||||
|
_emailTemplates.Get("email.match.manual-job-label", language);
|
||||||
}
|
}
|
||||||
|
|||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Email.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Email.Data.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(EmailDbContext))]
|
||||||
|
[Migration("20260608190611_AddManualJobLabelTemplate")]
|
||||||
|
partial class AddManualJobLabelTemplate
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasDefaultSchema("email")
|
||||||
|
.HasAnnotation("ProductVersion", "10.0.7")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Email.Data.Entities.EmailTemplateEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
||||||
|
b.Property<string>("Language")
|
||||||
|
.HasMaxLength(8)
|
||||||
|
.HasColumnType("nvarchar(8)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("nvarchar(500)")
|
||||||
|
.HasDefaultValue("");
|
||||||
|
|
||||||
|
b.Property<string>("OperatorCopy")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)")
|
||||||
|
.HasDefaultValue("");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("datetime2")
|
||||||
|
.HasDefaultValueSql("SYSUTCDATETIME()");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("Key", "Language");
|
||||||
|
|
||||||
|
b.ToTable("Templates", "email");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using Email.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Email.Data.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddManualJobLabelTemplate : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
schema: MigrationConstants.SchemaName,
|
||||||
|
table: "Templates",
|
||||||
|
columns: ["Key", "Language", "Value", "Description"],
|
||||||
|
values: ["email.match.manual-job-label", "en", "Manual job description", "Label used in the match email subject and body when no job URL was provided"]);
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
schema: MigrationConstants.SchemaName,
|
||||||
|
table: "Templates",
|
||||||
|
columns: ["Key", "Language", "Value", "Description"],
|
||||||
|
values: ["email.match.manual-job-label", "ro", "Descriere manuală a jobului", "Etichetă folosită în subiectul și corpul emailului când nu a fost furnizat un URL de job"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
schema: MigrationConstants.SchemaName,
|
||||||
|
table: "Templates",
|
||||||
|
keyColumns: ["Key", "Language"],
|
||||||
|
keyValues: ["email.match.manual-job-label", "en"]);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
schema: MigrationConstants.SchemaName,
|
||||||
|
table: "Templates",
|
||||||
|
keyColumns: ["Key", "Language"],
|
||||||
|
keyValues: ["email.match.manual-job-label", "ro"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -198,7 +198,9 @@ public sealed class CvSearchJobTask : IJobTask
|
|||||||
// Pre-fetched text passed directly so cv-matcher-api skips re-fetching the page
|
// Pre-fetched text passed directly so cv-matcher-api skips re-fetching the page
|
||||||
JobDescription = jobText,
|
JobDescription = jobText,
|
||||||
// User already gave GDPR consent when they clicked the one-time job search link
|
// User already gave GDPR consent when they clicked the one-time job search link
|
||||||
GdprConsent = true
|
GdprConsent = true,
|
||||||
|
// Propagate language so the LLM uses the correct language-specific prompt
|
||||||
|
Language = session.Language
|
||||||
};
|
};
|
||||||
|
|
||||||
var matchResult = await _matcherApi.MatchJobAsync(matchRequest, ct);
|
var matchResult = await _matcherApi.MatchJobAsync(matchRequest, ct);
|
||||||
|
|||||||
Reference in New Issue
Block a user