feat: Add legal compliance changes
- Replace 'diploma mill' language with objective 'unaccredited institution' terminology - Rename DiplomaMills.cs to UnaccreditedInstitutions.cs with neutral language - Update EducationVerificationResult.IsUnaccredited property - Update flag titles to 'Unaccredited Institution' and 'Institution Requires Verification' - Add legal disclaimer to verification report page - Add Privacy Policy page (/privacy) with UK GDPR compliance info - Add Terms of Service page (/terms) with candidate notice requirements - Add footer links to Privacy and Terms pages - Update all tests to use new terminology 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,7 +30,7 @@ public sealed class ProcessCVCheckJob
|
||||
private const int GapMonthPenalty = 1;
|
||||
private const int MaxGapPenalty = 10;
|
||||
private const int OverlapMonthPenalty = 2;
|
||||
private const int DiplomaMillPenalty = 25;
|
||||
private const int UnaccreditedInstitutionPenalty = 25;
|
||||
private const int SuspiciousInstitutionPenalty = 15;
|
||||
private const int UnverifiedEducationPenalty = 5;
|
||||
private const int EducationDatePenalty = 10;
|
||||
@@ -185,11 +185,11 @@ public sealed class ProcessCVCheckJob
|
||||
cvData.Employment);
|
||||
|
||||
_logger.LogDebug(
|
||||
"Education verification for check {CheckId}: {Count} entries verified ({Recognised} recognised, {DiplomaMill} diploma mills)",
|
||||
"Education verification for check {CheckId}: {Count} entries verified ({Recognised} recognised, {Unaccredited} unaccredited)",
|
||||
cvCheckId,
|
||||
educationResults.Count,
|
||||
educationResults.Count(e => e.IsVerified),
|
||||
educationResults.Count(e => e.IsDiplomaMill));
|
||||
educationResults.Count(e => e.IsUnaccredited));
|
||||
|
||||
// Step 7: Analyse timeline
|
||||
cvCheck.ProcessingStage = "Analysing Timeline";
|
||||
@@ -406,23 +406,23 @@ public sealed class ProcessCVCheckJob
|
||||
AddPLCExperienceFlag(verifications, flags);
|
||||
AddVerifiedDirectorFlag(verifications, flags);
|
||||
|
||||
// Penalty for diploma mills (critical)
|
||||
foreach (var edu in educationResults.Where(e => e.IsDiplomaMill))
|
||||
// Penalty for unaccredited institutions (critical)
|
||||
foreach (var edu in educationResults.Where(e => e.IsUnaccredited))
|
||||
{
|
||||
score -= DiplomaMillPenalty;
|
||||
score -= UnaccreditedInstitutionPenalty;
|
||||
|
||||
flags.Add(new FlagResult
|
||||
{
|
||||
Category = FlagCategory.Education.ToString(),
|
||||
Severity = FlagSeverity.Critical.ToString(),
|
||||
Title = "Diploma Mill Detected",
|
||||
Description = $"'{edu.ClaimedInstitution}' is a known diploma mill. {edu.VerificationNotes}",
|
||||
ScoreImpact = -DiplomaMillPenalty
|
||||
Title = "Unaccredited Institution",
|
||||
Description = $"'{edu.ClaimedInstitution}' is not found in the register of recognised institutions. {edu.VerificationNotes}",
|
||||
ScoreImpact = -UnaccreditedInstitutionPenalty
|
||||
});
|
||||
}
|
||||
|
||||
// Penalty for suspicious institutions
|
||||
foreach (var edu in educationResults.Where(e => e.IsSuspicious && !e.IsDiplomaMill))
|
||||
foreach (var edu in educationResults.Where(e => e.IsSuspicious && !e.IsUnaccredited))
|
||||
{
|
||||
score -= SuspiciousInstitutionPenalty;
|
||||
|
||||
@@ -430,15 +430,15 @@ public sealed class ProcessCVCheckJob
|
||||
{
|
||||
Category = FlagCategory.Education.ToString(),
|
||||
Severity = FlagSeverity.Warning.ToString(),
|
||||
Title = "Suspicious Institution",
|
||||
Description = $"'{edu.ClaimedInstitution}' has suspicious characteristics. {edu.VerificationNotes}",
|
||||
Title = "Institution Requires Verification",
|
||||
Description = $"'{edu.ClaimedInstitution}' has characteristics that warrant additional verification. {edu.VerificationNotes}",
|
||||
ScoreImpact = -SuspiciousInstitutionPenalty
|
||||
});
|
||||
}
|
||||
|
||||
// Penalty for unverified education (not recognised, but not flagged as fake)
|
||||
// Penalty for unverified education (not recognised, but not flagged as unaccredited)
|
||||
// Skip unknown/empty institutions as there's nothing to verify
|
||||
foreach (var edu in educationResults.Where(e => !e.IsVerified && !e.IsDiplomaMill && !e.IsSuspicious && e.Status == "Unknown"
|
||||
foreach (var edu in educationResults.Where(e => !e.IsVerified && !e.IsUnaccredited && !e.IsSuspicious && e.Status == "Unknown"
|
||||
&& !string.IsNullOrWhiteSpace(e.ClaimedInstitution)
|
||||
&& !e.ClaimedInstitution.Equals("Unknown Institution", StringComparison.OrdinalIgnoreCase)
|
||||
&& !e.ClaimedInstitution.Equals("Unknown", StringComparison.OrdinalIgnoreCase)))
|
||||
|
||||
@@ -14,17 +14,17 @@ public sealed class EducationVerifierService : IEducationVerifierService
|
||||
{
|
||||
var institution = education.Institution;
|
||||
|
||||
// Check for diploma mill first (highest priority flag)
|
||||
if (DiplomaMills.IsDiplomaMill(institution))
|
||||
// Check for unaccredited institution first (highest priority flag)
|
||||
if (UnaccreditedInstitutions.IsUnaccredited(institution))
|
||||
{
|
||||
return new EducationVerificationResult
|
||||
{
|
||||
ClaimedInstitution = institution,
|
||||
Status = "DiplomaMill",
|
||||
Status = "Unaccredited",
|
||||
IsVerified = false,
|
||||
IsDiplomaMill = true,
|
||||
IsUnaccredited = true,
|
||||
IsSuspicious = true,
|
||||
VerificationNotes = "Institution is on the diploma mill blacklist",
|
||||
VerificationNotes = "Institution not found in QAA/HESA register of recognised institutions",
|
||||
ClaimedStartDate = education.StartDate,
|
||||
ClaimedEndDate = education.EndDate,
|
||||
DatesArePlausible = true,
|
||||
@@ -34,16 +34,16 @@ public sealed class EducationVerifierService : IEducationVerifierService
|
||||
}
|
||||
|
||||
// Check for suspicious patterns
|
||||
if (DiplomaMills.HasSuspiciousPattern(institution))
|
||||
if (UnaccreditedInstitutions.HasSuspiciousPattern(institution))
|
||||
{
|
||||
return new EducationVerificationResult
|
||||
{
|
||||
ClaimedInstitution = institution,
|
||||
Status = "Suspicious",
|
||||
IsVerified = false,
|
||||
IsDiplomaMill = false,
|
||||
IsUnaccredited = false,
|
||||
IsSuspicious = true,
|
||||
VerificationNotes = "Institution name contains suspicious patterns common in diploma mills",
|
||||
VerificationNotes = "Institution name contains patterns that may indicate unaccredited status",
|
||||
ClaimedStartDate = education.StartDate,
|
||||
ClaimedEndDate = education.EndDate,
|
||||
DatesArePlausible = true,
|
||||
@@ -64,7 +64,7 @@ public sealed class EducationVerifierService : IEducationVerifierService
|
||||
MatchedInstitution = officialName,
|
||||
Status = "Recognised",
|
||||
IsVerified = true,
|
||||
IsDiplomaMill = false,
|
||||
IsUnaccredited = false,
|
||||
IsSuspicious = false,
|
||||
VerificationNotes = institution.Equals(officialName, StringComparison.OrdinalIgnoreCase)
|
||||
? "Verified UK higher education institution"
|
||||
@@ -88,7 +88,7 @@ public sealed class EducationVerifierService : IEducationVerifierService
|
||||
ClaimedInstitution = institution,
|
||||
Status = "Unknown",
|
||||
IsVerified = false,
|
||||
IsDiplomaMill = false,
|
||||
IsUnaccredited = false,
|
||||
IsSuspicious = false,
|
||||
VerificationNotes = isUnknownInstitution ? null : "Institution not found in UK recognised institutions database. May be an international institution.",
|
||||
ClaimedStartDate = education.StartDate,
|
||||
|
||||
Reference in New Issue
Block a user