diff --git a/src/RealCV.Application/Data/DiplomaMills.cs b/src/RealCV.Application/Data/DiplomaMills.cs index bb8de2e..fe5f4e4 100644 --- a/src/RealCV.Application/Data/DiplomaMills.cs +++ b/src/RealCV.Application/Data/DiplomaMills.cs @@ -135,24 +135,6 @@ public static class DiplomaMills "distance learning university", // be careful - some are legit ]; - /// - /// Fake accreditation bodies used by diploma mills. - /// - public static readonly HashSet FakeAccreditors = new(StringComparer.OrdinalIgnoreCase) - { - "World Association of Universities and Colleges", - "WAUC", - "International Accreditation Agency", - "Universal Accreditation Council", - "Board of Online Universities Accreditation", - "International Council for Open and Distance Education", - "World Online Education Accrediting Commission", - "Central States Consortium of Colleges and Schools", - "American Council of Private Colleges and Universities", - "Association of Distance Learning Programs", - "International Distance Education Certification Agency", - }; - /// /// Check if an institution is a known diploma mill. /// @@ -196,15 +178,4 @@ public static class DiplomaMills return false; } - - /// - /// Check if an accreditor is known to be fake. - /// - public static bool IsFakeAccreditor(string accreditorName) - { - if (string.IsNullOrWhiteSpace(accreditorName)) - return false; - - return FakeAccreditors.Contains(accreditorName.Trim()); - } } diff --git a/src/RealCV.Application/Helpers/JsonDefaults.cs b/src/RealCV.Application/Helpers/JsonDefaults.cs index 5f11c4b..bf8b3df 100644 --- a/src/RealCV.Application/Helpers/JsonDefaults.cs +++ b/src/RealCV.Application/Helpers/JsonDefaults.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using System.Text.Json.Serialization; namespace RealCV.Application.Helpers; @@ -16,4 +17,13 @@ public static class JsonDefaults PropertyNameCaseInsensitive = true, WriteIndented = true }; + + /// + /// Options for consuming external APIs - case insensitive with null handling. + /// + public static readonly JsonSerializerOptions ApiClient = new() + { + PropertyNameCaseInsensitive = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; } diff --git a/src/RealCV.Application/Models/GitHubVerificationResult.cs b/src/RealCV.Application/Models/GitHubVerificationResult.cs index 69856de..cfbea8f 100644 --- a/src/RealCV.Application/Models/GitHubVerificationResult.cs +++ b/src/RealCV.Application/Models/GitHubVerificationResult.cs @@ -37,9 +37,6 @@ public sealed record SkillVerification public required string ClaimedSkill { get; init; } public required bool IsVerified { get; init; } public int RepoCount { get; init; } - public int TotalLinesOfCode { get; init; } - public DateOnly? FirstUsed { get; init; } - public DateOnly? LastUsed { get; init; } public string? Notes { get; init; } } diff --git a/src/RealCV.Application/Models/SemanticMatchResult.cs b/src/RealCV.Application/Models/SemanticMatchResult.cs index 2610e16..3006e51 100644 --- a/src/RealCV.Application/Models/SemanticMatchResult.cs +++ b/src/RealCV.Application/Models/SemanticMatchResult.cs @@ -10,12 +10,6 @@ public record SemanticMatchResult public bool IsMatch => ConfidenceScore >= 70; } -public record CompanyMatchRequest -{ - public required string CVCompanyName { get; init; } - public required List Candidates { get; init; } -} - public record CompanyCandidate { public required string CompanyName { get; init; } diff --git a/src/RealCV.Infrastructure/Clients/FcaRegisterClient.cs b/src/RealCV.Infrastructure/Clients/FcaRegisterClient.cs index dca9f33..615b74f 100644 --- a/src/RealCV.Infrastructure/Clients/FcaRegisterClient.cs +++ b/src/RealCV.Infrastructure/Clients/FcaRegisterClient.cs @@ -1,8 +1,8 @@ using System.Net.Http.Json; -using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using RealCV.Application.Helpers; namespace RealCV.Infrastructure.Clients; @@ -44,7 +44,7 @@ public sealed class FcaRegisterClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -70,7 +70,7 @@ public sealed class FcaRegisterClient return null; } - var wrapper = await response.Content.ReadFromJsonAsync(JsonOptions); + var wrapper = await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); return wrapper?.Data?.FirstOrDefault(); } catch (Exception ex) @@ -94,7 +94,7 @@ public sealed class FcaRegisterClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -102,12 +102,6 @@ public sealed class FcaRegisterClient return null; } } - - private static readonly JsonSerializerOptions JsonOptions = new() - { - PropertyNameCaseInsensitive = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - }; } public class FcaOptions diff --git a/src/RealCV.Infrastructure/Clients/GitHubClient.cs b/src/RealCV.Infrastructure/Clients/GitHubClient.cs index c3945de..e83a99d 100644 --- a/src/RealCV.Infrastructure/Clients/GitHubClient.cs +++ b/src/RealCV.Infrastructure/Clients/GitHubClient.cs @@ -1,9 +1,9 @@ using System.Net.Http.Headers; using System.Net.Http.Json; -using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using RealCV.Application.Helpers; namespace RealCV.Infrastructure.Clients; @@ -49,7 +49,7 @@ public sealed class GitHubApiClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -76,7 +76,7 @@ public sealed class GitHubApiClient break; } - var pageRepos = await response.Content.ReadFromJsonAsync>(JsonOptions); + var pageRepos = await response.Content.ReadFromJsonAsync>(JsonDefaults.ApiClient); if (pageRepos == null || pageRepos.Count == 0) { @@ -107,28 +107,6 @@ public sealed class GitHubApiClient return repos; } - public async Task?> GetRepoLanguagesAsync(string owner, string repo) - { - try - { - var url = $"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(repo)}/languages"; - - var response = await _httpClient.GetAsync(url); - - if (!response.IsSuccessStatusCode) - { - return null; - } - - return await response.Content.ReadFromJsonAsync>(JsonOptions); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error getting languages for repo: {Owner}/{Repo}", owner, repo); - return null; - } - } - public async Task SearchUsersAsync(string query, int perPage = 30) { try @@ -143,7 +121,7 @@ public sealed class GitHubApiClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -151,12 +129,6 @@ public sealed class GitHubApiClient return null; } } - - private static readonly JsonSerializerOptions JsonOptions = new() - { - PropertyNameCaseInsensitive = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - }; } public class GitHubOptions diff --git a/src/RealCV.Infrastructure/Clients/OrcidClient.cs b/src/RealCV.Infrastructure/Clients/OrcidClient.cs index 37e3c94..1486ba9 100644 --- a/src/RealCV.Infrastructure/Clients/OrcidClient.cs +++ b/src/RealCV.Infrastructure/Clients/OrcidClient.cs @@ -1,8 +1,8 @@ using System.Net.Http.Headers; using System.Net.Http.Json; -using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.Logging; +using RealCV.Application.Helpers; namespace RealCV.Infrastructure.Clients; @@ -40,7 +40,7 @@ public sealed class OrcidClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -69,7 +69,7 @@ public sealed class OrcidClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -92,7 +92,7 @@ public sealed class OrcidClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -115,7 +115,7 @@ public sealed class OrcidClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -138,7 +138,7 @@ public sealed class OrcidClient return null; } - return await response.Content.ReadFromJsonAsync(JsonOptions); + return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { @@ -155,12 +155,6 @@ public sealed class OrcidClient .Trim(); return orcidId; } - - private static readonly JsonSerializerOptions JsonOptions = new() - { - PropertyNameCaseInsensitive = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - }; } // Response models diff --git a/src/RealCV.Infrastructure/Jobs/ProcessCVCheckJob.cs b/src/RealCV.Infrastructure/Jobs/ProcessCVCheckJob.cs index ee8efe0..7070288 100644 --- a/src/RealCV.Infrastructure/Jobs/ProcessCVCheckJob.cs +++ b/src/RealCV.Infrastructure/Jobs/ProcessCVCheckJob.cs @@ -24,7 +24,6 @@ public sealed class ProcessCVCheckJob private const int BaseScore = 100; private const int UnverifiedCompanyPenalty = 10; private const int ImplausibleJobTitlePenalty = 15; - private const int CompanyVerificationFlagPenalty = 5; // Base penalty for company flags, actual from flag.ScoreImpact private const int RapidProgressionPenalty = 10; private const int EarlyCareerSeniorRolePenalty = 10; private const int GapMonthPenalty = 1; diff --git a/tools/ApiTester/ApiTester.csproj b/tools/ApiTester/ApiTester.csproj deleted file mode 100644 index 91b464a..0000000 --- a/tools/ApiTester/ApiTester.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - diff --git a/tools/ApiTester/Program.cs b/tools/ApiTester/Program.cs deleted file mode 100644 index 7ac6992..0000000 --- a/tools/ApiTester/Program.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System.Net.Http.Headers; -using System.Text.Json; - -Console.WriteLine("=== RealCV API Integration Tester ===\n"); - -// Test 1: FCA Register API -Console.WriteLine("1. Testing FCA Register API..."); -try -{ - var fcaClient = new HttpClient(); - fcaClient.BaseAddress = new Uri("https://register.fca.org.uk/services/V0.1/"); - fcaClient.DefaultRequestHeaders.Add("X-Auth-Email", "peter.foster@ukdataservices.co.uk"); - fcaClient.DefaultRequestHeaders.Add("X-Auth-Key", "9ae1aee51e5c717a1135775501c89075"); - - var fcaResponse = await fcaClient.GetAsync("Individuals?q=John%20Smith&page=1"); - Console.WriteLine($" Status: {fcaResponse.StatusCode}"); - - if (fcaResponse.IsSuccessStatusCode) - { - var content = await fcaResponse.Content.ReadAsStringAsync(); - Console.WriteLine($" ✓ FCA API working"); - using var doc = JsonDocument.Parse(content); - if (doc.RootElement.TryGetProperty("Data", out var data) && data.ValueKind == JsonValueKind.Array) - { - Console.WriteLine($" Found {data.GetArrayLength()} individuals matching 'John Smith'"); - } - else - { - Console.WriteLine($" Response: {content.Substring(0, Math.Min(200, content.Length))}"); - } - } - else - { - Console.WriteLine($" ✗ Error: {fcaResponse.StatusCode}"); - } -} -catch (Exception ex) -{ - Console.WriteLine($" ✗ Error: {ex.Message}"); -} - -Console.WriteLine(); - -// Test 2: ORCID API -Console.WriteLine("2. Testing ORCID API..."); -try -{ - var orcidClient = new HttpClient(); - orcidClient.BaseAddress = new Uri("https://pub.orcid.org/v3.0/"); - orcidClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - - // Get a known ORCID record directly - var orcidResponse = await orcidClient.GetAsync("0000-0001-5109-3700/record"); - Console.WriteLine($" Status: {orcidResponse.StatusCode}"); - - if (orcidResponse.IsSuccessStatusCode) - { - var content = await orcidResponse.Content.ReadAsStringAsync(); - Console.WriteLine($" ✓ ORCID API working"); - using var doc = JsonDocument.Parse(content); - if (doc.RootElement.TryGetProperty("person", out var person) && - person.TryGetProperty("name", out var name)) - { - var givenName = ""; - var familyName = ""; - if (name.TryGetProperty("given-names", out var gn) && gn.TryGetProperty("value", out var gnv)) - givenName = gnv.GetString() ?? ""; - if (name.TryGetProperty("family-name", out var fn) && fn.TryGetProperty("value", out var fnv)) - familyName = fnv.GetString() ?? ""; - Console.WriteLine($" Retrieved record for: {givenName} {familyName}"); - } - } - else - { - Console.WriteLine($" ✗ Error: {orcidResponse.StatusCode}"); - } -} -catch (Exception ex) -{ - Console.WriteLine($" ✗ Error: {ex.Message}"); -} - -Console.WriteLine(); - -// Test 3: GitHub API -Console.WriteLine("3. Testing GitHub API..."); -try -{ - var githubClient = new HttpClient(); - githubClient.BaseAddress = new Uri("https://api.github.com/"); - githubClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github+json")); - githubClient.DefaultRequestHeaders.Add("X-GitHub-Api-Version", "2022-11-28"); - githubClient.DefaultRequestHeaders.UserAgent.ParseAdd("RealCV/1.0"); - - var githubResponse = await githubClient.GetAsync("users/torvalds"); - Console.WriteLine($" Status: {githubResponse.StatusCode}"); - - if (githubResponse.IsSuccessStatusCode) - { - var content = await githubResponse.Content.ReadAsStringAsync(); - Console.WriteLine($" ✓ GitHub API working"); - using var doc = JsonDocument.Parse(content); - var name = doc.RootElement.GetProperty("name").GetString(); - var repos = doc.RootElement.GetProperty("public_repos").GetInt32(); - var followers = doc.RootElement.GetProperty("followers").GetInt32(); - Console.WriteLine($" User: {name}, Repos: {repos}, Followers: {followers}"); - } - else - { - Console.WriteLine($" ✗ Error: {githubResponse.StatusCode}"); - } - - if (githubResponse.Headers.TryGetValues("X-RateLimit-Remaining", out var remaining)) - { - Console.WriteLine($" Rate limit remaining: {remaining.First()}"); - } -} -catch (Exception ex) -{ - Console.WriteLine($" ✗ Error: {ex.Message}"); -} - -Console.WriteLine("\n=== Tests complete ===");