From 677316242609251b3ce6cdff8f7195973c6ec5ea Mon Sep 17 00:00:00 2001 From: Peter Foster Date: Thu, 22 Jan 2026 21:23:48 +0000 Subject: [PATCH] feat: Display candidate name from CV data instead of filename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added CandidateName field to CVCheckDto - Extract candidate name from ReportJson or ExtractedDataJson - Dashboard now shows actual candidate name for JSON uploads - PDF export uses candidate name from report This fixes the issue where JSON files showed their filename (e.g., "CLEAN-001") instead of the actual candidate name from the CV data. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/RealCV.Application/DTOs/CVCheckDto.cs | 1 + .../Services/CVCheckService.cs | 28 +++++++++++++++++++ .../Components/Pages/Dashboard.razor | 4 +-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/RealCV.Application/DTOs/CVCheckDto.cs b/src/RealCV.Application/DTOs/CVCheckDto.cs index 7973518..f45281f 100644 --- a/src/RealCV.Application/DTOs/CVCheckDto.cs +++ b/src/RealCV.Application/DTOs/CVCheckDto.cs @@ -4,6 +4,7 @@ public sealed record CVCheckDto { public required Guid Id { get; init; } public required string OriginalFileName { get; init; } + public string? CandidateName { get; init; } public required string Status { get; init; } public int? VeracityScore { get; init; } public string? ProcessingStage { get; init; } diff --git a/src/RealCV.Infrastructure/Services/CVCheckService.cs b/src/RealCV.Infrastructure/Services/CVCheckService.cs index 25a865a..658de31 100644 --- a/src/RealCV.Infrastructure/Services/CVCheckService.cs +++ b/src/RealCV.Infrastructure/Services/CVCheckService.cs @@ -184,10 +184,38 @@ public sealed class CVCheckService : ICVCheckService private static CVCheckDto MapToDto(CVCheck cvCheck) { + string? candidateName = null; + + // Try to get candidate name from ReportJson first (completed checks) + if (!string.IsNullOrEmpty(cvCheck.ReportJson)) + { + try + { + var report = JsonSerializer.Deserialize(cvCheck.ReportJson, JsonDefaults.CamelCase); + candidateName = report?.CandidateName; + } + catch { /* Ignore deserialization errors */ } + } + + // Fallback to ExtractedDataJson if no name in report + if (string.IsNullOrEmpty(candidateName) && !string.IsNullOrEmpty(cvCheck.ExtractedDataJson)) + { + try + { + using var doc = JsonDocument.Parse(cvCheck.ExtractedDataJson); + if (doc.RootElement.TryGetProperty("fullName", out var nameElement)) + { + candidateName = nameElement.GetString(); + } + } + catch { /* Ignore deserialization errors */ } + } + return new CVCheckDto { Id = cvCheck.Id, OriginalFileName = cvCheck.OriginalFileName, + CandidateName = candidateName, Status = cvCheck.Status.ToString(), VeracityScore = cvCheck.VeracityScore, ProcessingStage = cvCheck.ProcessingStage, diff --git a/src/RealCV.Web/Components/Pages/Dashboard.razor b/src/RealCV.Web/Components/Pages/Dashboard.razor index 92d9ad9..7df5a53 100644 --- a/src/RealCV.Web/Components/Pages/Dashboard.razor +++ b/src/RealCV.Web/Components/Pages/Dashboard.razor @@ -210,7 +210,7 @@
-

@Path.GetFileNameWithoutExtension(check.OriginalFileName)

+

@(!string.IsNullOrEmpty(check.CandidateName) ? check.CandidateName : Path.GetFileNameWithoutExtension(check.OriginalFileName))

@Path.GetExtension(check.OriginalFileName).ToUpperInvariant()
@@ -659,7 +659,7 @@ reportDataList.Add(new RealCV.Web.Services.PdfReportData { - CandidateName = Path.GetFileNameWithoutExtension(check.OriginalFileName) ?? "Unknown", + CandidateName = report.CandidateName ?? Path.GetFileNameWithoutExtension(check.OriginalFileName) ?? "Unknown", UploadDate = check.CreatedAt, Score = report.OverallScore, ScoreLabel = report.ScoreLabel,