refactor(workspace): unify application workflow

This commit is contained in:
cesnimda
2026-08-28 12:28:12 +02:00
parent 4da673ff00
commit e3f938cb42
8 changed files with 264 additions and 102 deletions
@@ -89,6 +89,24 @@ public sealed class ApplicationIntelligenceTests
return profile;
}
private static async Task<CvVariant> AttachCvAsync(JobTrackerContext db, string owner, int jobId, CvVariantSettings? settings = null)
{
var variant = new CvVariant
{
OwnerUserId = owner,
JobApplicationId = jobId,
Name = "Backend CV",
PublicSlug = Guid.NewGuid().ToString("N"),
SettingsJson = CvVariantSettingsJson.Serialize(settings),
Version = 1,
CreatedAtUtc = DateTimeOffset.UtcNow,
UpdatedAtUtc = DateTimeOffset.UtcNow,
};
db.CvVariants.Add(variant);
await db.SaveChangesAsync();
return variant;
}
// ---------- Milestone 1: timeline ----------
[Fact]
@@ -262,11 +280,14 @@ public sealed class ApplicationIntelligenceTests
await using var _d = db;
var job = await SeedJobAsync(db, "user-1");
await SeedProfileAsync(db, "user-1");
await AttachCvAsync(db, "user-1", job.Id);
var m = await intelligence.MatchAsync("user-1", job.Id, default);
Assert.NotNull(m);
Assert.True(m!.HasCareerProfile);
Assert.True(m!.HasSelectedCv);
Assert.Equal("Backend CV", m.SelectedCvName);
Assert.True(m.HasCareerProfile);
Assert.True(m.Score > 0);
Assert.Contains("C#", m.MatchedSkills);
// The relevant-experience list is evidence drawn FROM the profile, not a copy of it.
@@ -282,6 +303,7 @@ public sealed class ApplicationIntelligenceTests
await using var _d = db;
var job = await SeedJobAsync(db, "user-1");
var profile = await SeedProfileAsync(db, "user-1");
await AttachCvAsync(db, "user-1", job.Id);
var bulletsBefore = profile.Experiences[0].BulletsJson;
var experienceCountBefore = profile.Experiences.Count;
var versionBefore = profile.Version;
@@ -295,7 +317,7 @@ public sealed class ApplicationIntelligenceTests
}
[Fact]
public async Task Match_asks_for_a_profile_before_scoring_anything()
public async Task Match_requires_an_explicitly_linked_cv_before_scoring_anything()
{
var (db, intelligence, _) = New("user-1");
await using var _d = db;
@@ -304,8 +326,9 @@ public sealed class ApplicationIntelligenceTests
var m = await intelligence.MatchAsync("user-1", job.Id, default);
Assert.False(m!.HasCareerProfile);
Assert.False(m.HasSelectedCv);
Assert.Equal(0, m.Score);
Assert.Contains(m.Suggestions, s => s.Contains("career profile", StringComparison.OrdinalIgnoreCase));
Assert.Contains(m.Suggestions, s => s.Contains("Select the CV", StringComparison.OrdinalIgnoreCase));
}
[Fact]
@@ -315,10 +338,30 @@ public sealed class ApplicationIntelligenceTests
await using var _d = db;
var job = await SeedJobAsync(db, "user-1");
await SeedProfileAsync(db, "user-2"); // someone else's profile must not be scored
await AttachCvAsync(db, "user-1", job.Id);
var m = await intelligence.MatchAsync("user-1", job.Id, default);
Assert.False(m!.HasCareerProfile);
Assert.True(m.HasSelectedCv);
}
[Fact]
public async Task Match_respects_sections_hidden_in_the_linked_cv()
{
var (db, intelligence, _) = New("user-1");
await using var _d = db;
var job = await SeedJobAsync(db, "user-1");
await SeedProfileAsync(db, "user-1");
await AttachCvAsync(db, "user-1", job.Id, new CvVariantSettings
{
Sections = { new CvSectionSetting { Key = "experience", Hidden = true } },
});
var match = await intelligence.MatchAsync("user-1", job.Id, default);
Assert.True(match!.HasSelectedCv);
Assert.Empty(match.RelevantExperience);
}
[Fact]