Fix CV verification scoring and UI alignment issues
ProcessCVCheckJob: - Recognize "contract", "contract work", "contract role" as freelance - Add "various", "various clients" for multiple short-term contracts - Prevents false matching of contract work to dissolved companies Report.razor: - Fix stat blocks centering (icon, number, label now centered) - Fix employment table column alignment with fixed widths - Add inline styles to header for consistent centering - Improve GetPointsForCompany to show -10 for unverified companies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -523,13 +523,22 @@ public sealed class ProcessCVCheckJob
|
|||||||
name == "self employed" ||
|
name == "self employed" ||
|
||||||
name == "selfemployed" ||
|
name == "selfemployed" ||
|
||||||
name == "contractor" ||
|
name == "contractor" ||
|
||||||
|
name == "contract" || // Working on contract basis
|
||||||
|
name == "contract work" ||
|
||||||
|
name == "contract role" ||
|
||||||
|
name == "various" || // Multiple short-term contracts
|
||||||
|
name == "various clients" ||
|
||||||
|
name == "various companies" ||
|
||||||
name.StartsWith("freelance ") ||
|
name.StartsWith("freelance ") ||
|
||||||
name.StartsWith("self-employed ") ||
|
name.StartsWith("self-employed ") ||
|
||||||
name.StartsWith("self employed ") ||
|
name.StartsWith("self employed ") ||
|
||||||
|
name.StartsWith("contract ") ||
|
||||||
|
name.StartsWith("contracting ") ||
|
||||||
name.Contains("(freelance)") ||
|
name.Contains("(freelance)") ||
|
||||||
name.Contains("(self-employed)") ||
|
name.Contains("(self-employed)") ||
|
||||||
name.Contains("(self employed)") ||
|
name.Contains("(self employed)") ||
|
||||||
name.Contains("(contractor)");
|
name.Contains("(contractor)") ||
|
||||||
|
name.Contains("(contract)");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsPublicSectorEmployer(string companyName)
|
private static bool IsPublicSectorEmployer(string companyName)
|
||||||
|
|||||||
@@ -214,11 +214,11 @@
|
|||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="employment-list">
|
<div class="employment-list">
|
||||||
<div class="employment-header">
|
<div class="employment-header">
|
||||||
<div></div>
|
<div style="text-align: center;"></div>
|
||||||
<div>Employer</div>
|
<div>Employer</div>
|
||||||
<div>Period</div>
|
<div style="text-align: center;">Period</div>
|
||||||
<div>Match</div>
|
<div style="text-align: center;">Match</div>
|
||||||
<div>Pts</div>
|
<div style="text-align: center;">Pts</div>
|
||||||
</div>
|
</div>
|
||||||
@for (int i = 0; i < _report.EmploymentVerifications.Count; i++)
|
@for (int i = 0; i < _report.EmploymentVerifications.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -573,6 +573,10 @@
|
|||||||
/* Stat Items */
|
/* Stat Items */
|
||||||
.stat-item {
|
.stat-item {
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-icon {
|
.stat-icon {
|
||||||
@@ -641,7 +645,7 @@
|
|||||||
|
|
||||||
.employment-header {
|
.employment-header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 24px 1fr auto 60px 50px;
|
grid-template-columns: 24px 1fr 120px 60px 50px;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
background-color: #f8fafc;
|
background-color: #f8fafc;
|
||||||
@@ -651,17 +655,24 @@
|
|||||||
color: #64748b;
|
color: #64748b;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.025em;
|
letter-spacing: 0.025em;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.employment-header div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.employment-header div:nth-child(3),
|
.employment-header div:nth-child(3),
|
||||||
.employment-header div:nth-child(4),
|
.employment-header div:nth-child(4),
|
||||||
.employment-header div:nth-child(5) {
|
.employment-header div:nth-child(5) {
|
||||||
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.employment-row {
|
.employment-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 24px 1fr auto 60px 50px;
|
grid-template-columns: 24px 1fr 120px 60px 50px;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
@@ -690,6 +701,7 @@
|
|||||||
.employment-company {
|
.employment-company {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
gap: 0.125rem;
|
gap: 0.125rem;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
@@ -707,18 +719,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.employment-dates {
|
.employment-dates {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-align: right;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.employment-score {
|
.employment-score {
|
||||||
text-align: center;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.employment-points {
|
.employment-points {
|
||||||
text-align: center;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
font-size: 0.8125rem;
|
font-size: 0.8125rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -970,7 +989,7 @@
|
|||||||
|
|
||||||
private int GetPointsForCompany(string claimedCompany, string? matchedCompany, int index)
|
private int GetPointsForCompany(string claimedCompany, string? matchedCompany, int index)
|
||||||
{
|
{
|
||||||
if (_report?.Flags is null) return 0;
|
if (_report?.Flags is null || _report?.EmploymentVerifications is null) return 0;
|
||||||
|
|
||||||
// Only show points for the first occurrence of each company
|
// Only show points for the first occurrence of each company
|
||||||
if (!_firstOccurrenceIndices.Contains(index))
|
if (!_firstOccurrenceIndices.Contains(index))
|
||||||
@@ -978,7 +997,13 @@
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sum up all flags that mention this company in their description
|
var totalPoints = 0;
|
||||||
|
|
||||||
|
// Get the verification result for this company
|
||||||
|
var verification = _report.EmploymentVerifications.ElementAtOrDefault(index);
|
||||||
|
|
||||||
|
// Check if there's an "Unverified Company" flag for this company
|
||||||
|
// Search by both title pattern and description containing company name
|
||||||
var companyFlags = _report.Flags
|
var companyFlags = _report.Flags
|
||||||
.Where(f => f.ScoreImpact < 0 &&
|
.Where(f => f.ScoreImpact < 0 &&
|
||||||
((!string.IsNullOrEmpty(f.Description) && f.Description.Contains(claimedCompany, StringComparison.OrdinalIgnoreCase)) ||
|
((!string.IsNullOrEmpty(f.Description) && f.Description.Contains(claimedCompany, StringComparison.OrdinalIgnoreCase)) ||
|
||||||
@@ -987,6 +1012,29 @@
|
|||||||
.Select(g => g.First())
|
.Select(g => g.First())
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return companyFlags.Sum(f => f.ScoreImpact);
|
totalPoints = companyFlags.Sum(f => f.ScoreImpact);
|
||||||
|
|
||||||
|
// If company is unverified but no flag was found in description search,
|
||||||
|
// check if there's a generic "Unverified Company" flag that might use different wording
|
||||||
|
if (verification != null && !verification.IsVerified && totalPoints == 0)
|
||||||
|
{
|
||||||
|
// Look for any Unverified Company flag that might apply
|
||||||
|
var unverifiedFlag = _report.Flags
|
||||||
|
.FirstOrDefault(f => f.Title == "Unverified Company" && f.ScoreImpact < 0 &&
|
||||||
|
!string.IsNullOrEmpty(f.Description) &&
|
||||||
|
f.Description.Contains(claimedCompany, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (unverifiedFlag != null)
|
||||||
|
{
|
||||||
|
totalPoints = unverifiedFlag.ScoreImpact;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Company is unverified but no specific flag found - show the standard penalty
|
||||||
|
totalPoints = -10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalPoints;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user