feat: improve admin observability and translation-first summaries
This commit is contained in:
@@ -71,6 +71,20 @@ namespace JobTrackerApi.Controllers
|
||||
return new string(value.Trim().ToLowerInvariant().Where(char.IsLetterOrDigit).ToArray());
|
||||
}
|
||||
|
||||
private static string BuildSummarySource(JobApplication job)
|
||||
{
|
||||
// Prefer translated text for summaries and skill extraction so non-English
|
||||
// postings become easier to understand while keeping the original text intact.
|
||||
var parts = new[]
|
||||
{
|
||||
job.TranslatedDescription,
|
||||
job.Description,
|
||||
job.Notes
|
||||
};
|
||||
|
||||
return string.Join("\n\n", parts.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x!.Trim()));
|
||||
}
|
||||
|
||||
private static string? NormalizeTags(string? raw)
|
||||
{
|
||||
var normalized = SplitTags(raw)
|
||||
@@ -363,8 +377,9 @@ namespace JobTrackerApi.Controllers
|
||||
.MaxAsync(c => (DateTime?)c.Date, cancellationToken);
|
||||
|
||||
var d = RulesEngine.Evaluate(settings, job, now, lm);
|
||||
// Return persisted short summary and compute a fuller summary on demand for the details view.
|
||||
var full = await _summarizer.SummarizeAsync(job.Description ?? job.Notes ?? "", 250, 40);
|
||||
// Prefer translated content for the detailed summary so Norwegian postings
|
||||
// surface readable English analysis while the original text remains available.
|
||||
var full = await _summarizer.SummarizeAsync(BuildSummarySource(job), 250, 40);
|
||||
|
||||
return Ok(new JobApplicationDto(
|
||||
Id: job.Id,
|
||||
@@ -596,7 +611,7 @@ namespace JobTrackerApi.Controllers
|
||||
// Generate and persist a short summary at creation time to avoid repeated model calls.
|
||||
try
|
||||
{
|
||||
var shortSum = await _summarizer.SummarizeAsync(job.Description ?? job.Notes ?? "", 160, 60);
|
||||
var shortSum = await _summarizer.SummarizeAsync(BuildSummarySource(job), 160, 60);
|
||||
job.ShortSummary = shortSum;
|
||||
}
|
||||
catch
|
||||
@@ -752,11 +767,10 @@ namespace JobTrackerApi.Controllers
|
||||
|
||||
if (job is null) return NotFound();
|
||||
|
||||
var sourceText = string.Join("\n\n", new[] { job.Description, job.TranslatedDescription, job.Notes }
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x)));
|
||||
var sourceText = BuildSummarySource(job);
|
||||
if (string.IsNullOrWhiteSpace(sourceText))
|
||||
{
|
||||
return BadRequest("This job does not have enough description or notes to generate a summary and skills.");
|
||||
return BadRequest("This job does not have enough translated text, description, or notes to generate a summary and skills.");
|
||||
}
|
||||
|
||||
var tags = SkillTagger.Detect(sourceText)
|
||||
@@ -1710,7 +1724,7 @@ Candidate master CV:
|
||||
))
|
||||
.ToList();
|
||||
|
||||
return Ok(new DuplicateCheckResult(matches.Count > 0, matches));
|
||||
return Ok(new DuplicateCheckResult(matches.Any(), matches));
|
||||
}
|
||||
|
||||
[HttpGet("{id:int}/followup-draft")]
|
||||
|
||||
Reference in New Issue
Block a user