Add canonical CV artifact pipeline

This commit is contained in:
2026-03-28 23:32:54 +01:00
parent d8ab312f59
commit 107c181506
10 changed files with 619 additions and 82 deletions
+3
View File
@@ -9,6 +9,9 @@ public sealed class ApplicationUser : IdentityUser
public string? DisplayName { get; set; }
public string? ProfileCvText { get; set; }
public string? ProfileCvStructureJson { get; set; }
public int? CurrentCvUploadArtifactId { get; set; }
public int? CurrentCvExtractionRunId { get; set; }
public int? CurrentCvProfileVersion { get; set; }
public string? AvatarImageDataUrl { get; set; }
public string? GoogleSubject { get; set; }
public string? GoogleEmail { get; set; }
+34
View File
@@ -0,0 +1,34 @@
namespace JobTrackerApi.Models;
public sealed class CvUploadArtifact
{
public int Id { get; set; }
public string OwnerUserId { get; set; } = string.Empty;
public string OriginalFileName { get; set; } = string.Empty;
public string StoredFileName { get; set; } = string.Empty;
public string MimeType { get; set; } = string.Empty;
public long ByteSize { get; set; }
public string Sha256 { get; set; } = string.Empty;
public string StoragePath { get; set; } = string.Empty;
public DateTimeOffset UploadedAtUtc { get; set; } = DateTimeOffset.UtcNow;
}
public sealed class CvExtractionRun
{
public int Id { get; set; }
public string OwnerUserId { get; set; } = string.Empty;
public int? ArtifactId { get; set; }
public CvUploadArtifact? Artifact { get; set; }
public string Trigger { get; set; } = string.Empty;
public string ParserVersion { get; set; } = string.Empty;
public string NormalizerVersion { get; set; } = string.Empty;
public string LlmPromptVersion { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string? RawExtractedText { get; set; }
public string? NormalizedText { get; set; }
public string? StructuredProfileJson { get; set; }
public string? ErrorMessage { get; set; }
public DateTimeOffset StartedAtUtc { get; set; } = DateTimeOffset.UtcNow;
public DateTimeOffset? CompletedAtUtc { get; set; }
public DateTimeOffset? AppliedAtUtc { get; set; }
}
+20
View File
@@ -3,6 +3,7 @@ namespace JobTrackerApi.Models;
public sealed class StructuredCvProfile
{
public string Version { get; set; } = "1";
public StructuredCvMetadata Metadata { get; set; } = new();
public StructuredCvContact Contact { get; set; } = new();
public List<string> Summary { get; set; } = new();
public List<StructuredCvJob> Jobs { get; set; } = new();
@@ -14,6 +15,25 @@ public sealed class StructuredCvProfile
public List<StructuredCvSection> Sections { get; set; } = new();
}
public sealed class StructuredCvMetadata
{
public int? ProfileVersion { get; set; }
public int? AppliedExtractionRunId { get; set; }
public DateTimeOffset? UpdatedAtUtc { get; set; }
public Dictionary<string, StructuredCvFieldMetadata> Fields { get; set; } = new();
}
public sealed class StructuredCvFieldMetadata
{
public double? Confidence { get; set; }
public string? Method { get; set; }
public string? SourceSnippet { get; set; }
public int? SourcePage { get; set; }
public string? SourceBlockId { get; set; }
public string? ReviewState { get; set; }
public DateTimeOffset? LastUpdatedAtUtc { get; set; }
}
public sealed class StructuredCvContact
{
public string? FullName { get; set; }
+2
View File
@@ -134,6 +134,8 @@ public static class StructuredCvProfileJson
{
profile ??= new StructuredCvProfile();
profile.Version = string.IsNullOrWhiteSpace(profile.Version) ? "1" : profile.Version.Trim();
profile.Metadata ??= new StructuredCvMetadata();
profile.Metadata.Fields ??= new Dictionary<string, StructuredCvFieldMetadata>();
profile.Contact ??= new StructuredCvContact();
profile.Summary = CleanList(profile.Summary);
profile.Jobs = (profile.Jobs ?? new List<StructuredCvJob>())