feat(career): add factual evidence bank

This commit is contained in:
cesnimda
2026-08-31 17:03:09 +02:00
parent 5337ba3a5e
commit 78ad0c66f9
16 changed files with 362 additions and 5 deletions
@@ -1,6 +1,7 @@
using JobTrackerApi.Data;
using JobTrackerApi.Models;
using Microsoft.EntityFrameworkCore;
using System.Text.Json;
namespace JobTrackerApi.Services;
@@ -176,6 +177,26 @@ public sealed class ApplicationAssetsService : IApplicationAssetsService
match.RelevantProjects.Select(p => p.Subtitle is null ? p.Title : $"{p.Title} — {p.Subtitle}").ToList()));
}
var evidenceTerms = match.MatchedSkills.Concat(analysis.Keywords)
.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
var evidence = await _db.CareerEvidence.AsNoTracking()
.Where(x => x.OwnerUserId == ownerUserId && x.IsVerified)
.OrderByDescending(x => x.UpdatedAtUtc)
.ToListAsync(ct);
var relevantEvidence = evidence.Where(item =>
{
var searchable = $"{item.Title} {item.Statement} {string.Join(' ', EvidenceTags(item.TagsJson))}";
return evidenceTerms.Any(term => searchable.Contains(term, StringComparison.OrdinalIgnoreCase));
}).Take(6).Select(item => $"{item.Title} — {item.Statement}").ToList();
if (relevantEvidence.Count > 0)
{
suggestions.Add(new TailoringSuggestionDto(
"career-evidence",
"Verified evidence to reuse",
"Facts you previously approved. Adapt the wording, but keep the claim accurate.",
relevantEvidence));
}
if (analysis.Keywords.Count > 0)
{
suggestions.Add(new TailoringSuggestionDto(
@@ -297,4 +318,10 @@ public sealed class ApplicationAssetsService : IApplicationAssetsService
private Task<JobApplication?> LoadJobAsync(string ownerUserId, int jobApplicationId, CancellationToken ct) =>
_db.JobApplications.AsNoTracking()
.FirstOrDefaultAsync(j => j.Id == jobApplicationId && j.OwnerUserId == ownerUserId, ct);
private static IReadOnlyList<string> EvidenceTags(string? json)
{
try { return JsonSerializer.Deserialize<List<string>>(json ?? "[]") ?? []; }
catch (JsonException) { return []; }
}
}