From fab1866fc83321282b21a69d84843269cf177bb0 Mon Sep 17 00:00:00 2001 From: Peter Foster Date: Sun, 25 Jan 2026 08:11:08 +0000 Subject: [PATCH] feat: Detect fake UK universities using naming patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add detection for institutions that follow UK university naming conventions (e.g., "University of the Peak District") but aren't in the recognised institutions list. These are now flagged as "Suspicious" with a -15 point penalty instead of just "Unknown". 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../Services/EducationVerifierService.cs | 96 +++++++++++++++++++ .../Services/EducationVerifierServiceTests.cs | 24 +++++ 2 files changed, 120 insertions(+) diff --git a/src/RealCV.Infrastructure/Services/EducationVerifierService.cs b/src/RealCV.Infrastructure/Services/EducationVerifierService.cs index 620ab6e..527d386 100644 --- a/src/RealCV.Infrastructure/Services/EducationVerifierService.cs +++ b/src/RealCV.Infrastructure/Services/EducationVerifierService.cs @@ -78,6 +78,26 @@ public sealed class EducationVerifierService : IEducationVerifierService }; } + // Check if this looks like a UK university name but isn't recognised + // This catches fake institutions like "University of the Peak District" + if (LooksLikeUKUniversity(institution)) + { + return new EducationVerificationResult + { + ClaimedInstitution = institution, + Status = "Suspicious", + IsVerified = false, + IsUnaccredited = false, + IsSuspicious = true, + VerificationNotes = "Institution uses UK university naming convention but is not found in the register of recognised UK institutions", + ClaimedStartDate = education.StartDate, + ClaimedEndDate = education.EndDate, + DatesArePlausible = true, + ClaimedQualification = education.Qualification, + ClaimedSubject = education.Subject + }; + } + // Not in our database - could be international or unrecognised var isUnknownInstitution = string.IsNullOrWhiteSpace(institution) || institution.Equals("Unknown Institution", StringComparison.OrdinalIgnoreCase) || @@ -99,6 +119,82 @@ public sealed class EducationVerifierService : IEducationVerifierService }; } + /// + /// Checks if an institution name follows UK university naming conventions. + /// If it does but isn't in the recognised list, it's likely a fake UK institution. + /// + private static bool LooksLikeUKUniversity(string? institution) + { + if (string.IsNullOrWhiteSpace(institution)) + return false; + + var lower = institution.ToLowerInvariant().Trim(); + + // Skip if explicitly marked as foreign/international + if (lower.Contains("foreign") || lower.Contains("international")) + return false; + + // "University of the [X]" is a distinctly British naming pattern + // Examples: University of the West of England, University of the Highlands and Islands + // Fake examples: University of the Peak District, University of the Cotswolds + if (lower.StartsWith("university of the ")) + return true; + + // UK-specific naming patterns that are less common internationally + if (lower.Contains(" metropolitan university")) // Manchester Metropolitan University + return true; + if (lower.Contains(" brookes university")) // Oxford Brookes + return true; + if (lower.Contains(" hallam university")) // Sheffield Hallam + return true; + if (lower.Contains(" beckett university")) // Leeds Beckett + return true; + if (lower.Contains(" napier university")) // Edinburgh Napier + return true; + if (lower.Contains(" trent university")) // Nottingham Trent + return true; + if (lower.StartsWith("royal college of ")) // Royal College of Art, etc. + return true; + + // Check for UK place names that don't have real universities + // These are well-known UK regions/places used by diploma mills + var fakeUkPatterns = new[] + { + "university of devonshire", + "university of cornwall", // No "University of Cornwall" - only Falmouth + "university of wiltshire", + "university of dorset", + "university of hampshire", + "university of norfolk", + "university of suffolk", // Note: There IS a University of Suffolk now + "university of berkshire", + "university of shropshire", + "university of herefordshire", + "university of rutland", + "university of cumbria", // This one exists - keep for now + "university of england", + "university of britain", + "university of the lake district", + "university of the cotswolds", + "university of the peak district", + "university of the dales", + "university of the moors", + "university of the fens", + "university of london south", + "university of london north", + "university of london east", + "university of london west", + }; + + foreach (var pattern in fakeUkPatterns) + { + if (lower.Contains(pattern)) + return true; + } + + return false; + } + public List VerifyAll( List education, List? employment = null) diff --git a/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs b/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs index 825cf50..9f04201 100644 --- a/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs +++ b/tests/RealCV.Tests/Services/EducationVerifierServiceTests.cs @@ -80,6 +80,30 @@ public sealed class EducationVerifierServiceTests result.IsVerified.Should().BeFalse(); } + [Theory] + [InlineData("University of the Peak District")] + [InlineData("University of the Cotswolds")] + [InlineData("University of the Lake District")] + [InlineData("University of the Dales")] + [InlineData("Sheffield Metropolitan University")] // Uses UK pattern but doesn't exist + public void Verify_FakeUKInstitution_ReturnsSuspicious(string institution) + { + // Arrange + var education = new EducationEntry + { + Institution = institution + }; + + // Act + var result = _sut.Verify(education); + + // Assert + result.Status.Should().Be("Suspicious"); + result.IsSuspicious.Should().BeTrue(); + result.IsVerified.Should().BeFalse(); + result.VerificationNotes.Should().Contain("UK university naming convention"); + } + #endregion #region UK Institution Recognition