Improve CV rewrite flow and parser accuracy

This commit is contained in:
2026-04-01 11:30:37 +02:00
parent f402213526
commit f22c6791a7
9 changed files with 581 additions and 55 deletions
@@ -431,7 +431,7 @@ public sealed class ProfileCvControllerTests
{
"version": "1",
"contact": {
"location": "Tønsberg, Norway",
"location": "Python,Ruby",
"website": "https://cesnimda.co.uk/about",
"linkedin": "linkedin.com/in/demo-user?trk=foo"
},
@@ -456,9 +456,28 @@ public sealed class ProfileCvControllerTests
"isCurrent": false,
"bullets": ["Kept services running"],
"skills": []
},
{
"title": "Developer",
"company": "Demo Co",
"location": "Warwickshire College, UK S A L E S R E P R E S E N T A T I V E",
"start": "2021",
"end": "2022",
"isCurrent": false,
"bullets": ["Managed account handovers"],
"skills": []
}
],
"education": [
{
"qualification": "Warwickshire College",
"institution": "ICT Level 3",
"location": "Warwickshire College, UK S A L E S R E P R E S E N T A T I V E",
"start": "2012",
"end": "2015",
"details": []
}
],
"education": [],
"skills": [],
"languages": [],
"interests": [],
@@ -466,7 +485,7 @@ public sealed class ProfileCvControllerTests
}
""");
Assert.Equal("Tønsberg, Norway", structured.Contact.Location);
Assert.Null(structured.Contact.Location);
Assert.Equal("cesnimda.co.uk", structured.Contact.Website);
Assert.Equal("https://www.linkedin.com/in/demo-user", structured.Contact.LinkedIn);
Assert.Equal("Warwickshire, England, UK", structured.Jobs[0].Location);
@@ -475,6 +494,37 @@ public sealed class ProfileCvControllerTests
Assert.Null(structured.Jobs[1].Location);
Assert.Null(structured.Jobs[1].Start);
Assert.Null(structured.Jobs[1].End);
Assert.Equal("Warwickshire College, UK", structured.Jobs[2].Location);
Assert.Equal("ICT Level 3", structured.Education[0].Qualification);
Assert.Equal("Warwickshire College", structured.Education[0].Institution);
Assert.Equal("Warwickshire College, UK", structured.Education[0].Location);
}
[Fact]
public async Task Rewrite_section_can_target_saved_job_context_and_whole_cv()
{
var user = new ApplicationUser { Id = "user-1", ProfileCvText = "Professional Summary\nBuilt backend systems." };
var userManager = CreateUserManager();
userManager.Setup(x => x.GetUserAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user);
var aiService = new Mock<ISummarizerService>();
aiService
.Setup(x => x.SummarizeSectionAsync(It.Is<string>(instruction => instruction.Contains("Harvard template", StringComparison.Ordinal) && instruction.Contains("Senior Backend Engineer", StringComparison.Ordinal)), It.Is<string>(text => text.Contains("Professional Summary", StringComparison.Ordinal)), 1800, 400))
.ReturnsAsync("Professional Summary\nSharper backend platform positioning.");
await using var db = CreateDb();
db.Companies.Add(new Company { Id = 7, Name = "Acme Systems", OwnerUserId = "user-1" });
db.JobApplications.Add(new JobApplication { Id = 42, JobTitle = "Senior Backend Engineer", Description = "Build API integrations and platform workflows.", OwnerUserId = "user-1", CompanyId = 7, Status = "Waiting", DateApplied = DateTime.UtcNow });
await db.SaveChangesAsync();
var paths = CreatePaths();
var controller = CreateController(userManager.Object, aiService.Object, db, paths);
var result = await controller.RewriteSection(new ProfileCvController.RewriteSectionRequest(null, "harvard", null, 42, "harvard"));
var ok = Assert.IsType<OkObjectResult>(result);
var json = JsonSerializer.Serialize(ok.Value);
Assert.Contains("Sharper backend platform positioning", json);
Assert.Contains("harvard", json, StringComparison.OrdinalIgnoreCase);
Assert.Contains("42", json, StringComparison.OrdinalIgnoreCase);
}
[Fact]