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 score = BaseScore;
|
||||||
var flags = new List<FlagResult>();
|
var flags = new List<FlagResult>();
|
||||||
|
|
||||||
// Penalty for unverified companies
|
// Penalty for unverified companies (deduplicated by company name)
|
||||||
foreach (var verification in verifications.Where(v => !v.IsVerified))
|
var unverifiedByCompany = verifications
|
||||||
|
.Where(v => !v.IsVerified)
|
||||||
|
.GroupBy(v => v.ClaimedCompany, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var companyGroup in unverifiedByCompany)
|
||||||
{
|
{
|
||||||
score -= UnverifiedCompanyPenalty;
|
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
|
flags.Add(new FlagResult
|
||||||
{
|
{
|
||||||
Category = FlagCategory.Employment.ToString(),
|
Category = FlagCategory.Employment.ToString(),
|
||||||
Severity = FlagSeverity.Warning.ToString(),
|
Severity = FlagSeverity.Warning.ToString(),
|
||||||
Title = "Unverified Company",
|
Title = "Unverified Company",
|
||||||
Description = $"Could not verify employment at '{verification.ClaimedCompany}'. {verification.VerificationNotes}",
|
Description = description,
|
||||||
ScoreImpact = -UnverifiedCompanyPenalty
|
ScoreImpact = -UnverifiedCompanyPenalty
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process company verification flags (incorporation date, dissolution, dormant, etc.)
|
// 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 verification in verifications.Where(v => v.Flags.Count > 0))
|
||||||
{
|
{
|
||||||
foreach (var companyFlag in verification.Flags)
|
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);
|
var penalty = Math.Abs(companyFlag.ScoreImpact);
|
||||||
score -= penalty;
|
score -= penalty;
|
||||||
|
|
||||||
@@ -660,4 +682,24 @@ public sealed class ProcessCVCheckJob
|
|||||||
// Level 1: Junior / Entry-level
|
// Level 1: Junior / Entry-level
|
||||||
return 1;
|
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