Deduplicate penalties for same company appearing multiple times
When a company appears multiple times in employment history (e.g., multiple roles at same company), penalties are now applied only once per unique company, not per employment entry. - Unverified company: -10 pts once per company (not per role) - Company flags (incorporation date, etc.): once per (company, flag type) Description now shows "(X roles)" when multiple instances exist. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -261,26 +261,48 @@ public sealed class ProcessCVCheckJob
|
||||
var score = BaseScore;
|
||||
var flags = new List<FlagResult>();
|
||||
|
||||
// Penalty for unverified companies
|
||||
foreach (var verification in verifications.Where(v => !v.IsVerified))
|
||||
// Penalty for unverified companies (deduplicated by company name)
|
||||
var unverifiedByCompany = verifications
|
||||
.Where(v => !v.IsVerified)
|
||||
.GroupBy(v => v.ClaimedCompany, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
foreach (var companyGroup in unverifiedByCompany)
|
||||
{
|
||||
score -= UnverifiedCompanyPenalty;
|
||||
var firstInstance = companyGroup.First();
|
||||
var instanceCount = companyGroup.Count();
|
||||
|
||||
var description = instanceCount > 1
|
||||
? $"Could not verify employment at '{firstInstance.ClaimedCompany}' ({instanceCount} roles). {firstInstance.VerificationNotes}"
|
||||
: $"Could not verify employment at '{firstInstance.ClaimedCompany}'. {firstInstance.VerificationNotes}";
|
||||
|
||||
flags.Add(new FlagResult
|
||||
{
|
||||
Category = FlagCategory.Employment.ToString(),
|
||||
Severity = FlagSeverity.Warning.ToString(),
|
||||
Title = "Unverified Company",
|
||||
Description = $"Could not verify employment at '{verification.ClaimedCompany}'. {verification.VerificationNotes}",
|
||||
Description = description,
|
||||
ScoreImpact = -UnverifiedCompanyPenalty
|
||||
});
|
||||
}
|
||||
|
||||
// Process company verification flags (incorporation date, dissolution, dormant, etc.)
|
||||
// Deduplicate by (company, flag type) to avoid penalizing same issue multiple times
|
||||
var processedCompanyFlags = new HashSet<(string Company, string FlagType)>(
|
||||
new CompanyFlagComparer());
|
||||
|
||||
foreach (var verification in verifications.Where(v => v.Flags.Count > 0))
|
||||
{
|
||||
foreach (var companyFlag in verification.Flags)
|
||||
{
|
||||
var key = (verification.ClaimedCompany, companyFlag.Type);
|
||||
if (!processedCompanyFlags.Add(key))
|
||||
{
|
||||
// Already processed this flag for this company, skip
|
||||
continue;
|
||||
}
|
||||
|
||||
var penalty = Math.Abs(companyFlag.ScoreImpact);
|
||||
score -= penalty;
|
||||
|
||||
@@ -660,4 +682,24 @@ public sealed class ProcessCVCheckJob
|
||||
// Level 1: Junior / Entry-level
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comparer for deduplicating company flags by (company name, flag type).
|
||||
/// Uses case-insensitive comparison for company names.
|
||||
/// </summary>
|
||||
private sealed class CompanyFlagComparer : IEqualityComparer<(string Company, string FlagType)>
|
||||
{
|
||||
public bool Equals((string Company, string FlagType) x, (string Company, string FlagType) y)
|
||||
{
|
||||
return string.Equals(x.Company, y.Company, StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(x.FlagType, y.FlagType, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public int GetHashCode((string Company, string FlagType) obj)
|
||||
{
|
||||
return HashCode.Combine(
|
||||
obj.Company?.ToUpperInvariant() ?? "",
|
||||
obj.FlagType?.ToUpperInvariant() ?? "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user