992f89e619
Recover the F1 Career Profile foundation + AI-workspace persistence from the unmerged feature/career-workspace branch, so Phase 2 builds on the documented, tested target state instead of re-deriving it. Foundation only — CV Builder commits (variants, ATS badge, rewrite diff) stay deferred per "do not build CV Builder yet". See docs/career-workspace-branch-assessment.md. Squashed from 3 branch commits (235e291,5916f09,00a035e), resolved against main + Phase 0: - CareerProfile + CareerProfileVersion (append-only history), dual-written from every profile save path via CareerProfileService. ApplicationUser. ProfileCvStructureJson stays authoritative; the tables mirror it. Stable item IDs assigned to jobs/education/certifications/projects (the prerequisite for future variant lineage). CvDateNormalizer for free-text -> YYYY-MM. - InterviewPrepNote + AiWorkspaceNote: cache AI interview prep / candidate fit / focus plan keyed by an attachment-context signature, so they stop regenerating (and re-spending the provider) on every open. Conflict resolutions (union, favouring current code + Phase 0): - JobTrackerContext / StartupInitializationExtensions: kept Phase 0's tables and reconciler blocks, added the career/interview/ai-note tables (both SQLite and MySQL dialects). - ProfileCvController: dropped the branch's in-file DTO records (main defines them in ProfileCvDtos.cs) and the LayoutFamily/AtsRating template fields (deferred ATS-badge work), keeping main's 7-arg CvTemplateDescriptor. - JobApplicationsController: kept the branch's cache-check, restored main's AsNoTracking on the read-only user load. Tables ship empty (verified dev); nothing to migrate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
30 lines
1.4 KiB
C#
30 lines
1.4 KiB
C#
namespace JobTrackerApi.Models;
|
|
|
|
// The Career Workspace's durable source of truth. Bounded to one row per user for now
|
|
// (see career-workspace-implementation-roadmap.md Phase F1) -- ProfileJson mirrors
|
|
// ApplicationUser.ProfileCvStructureJson during the dual-write window and will become
|
|
// authoritative once every read path is migrated (F5).
|
|
public sealed class CareerProfile
|
|
{
|
|
public int Id { get; set; }
|
|
public string OwnerUserId { get; set; } = string.Empty;
|
|
public string ProfileJson { get; set; } = string.Empty;
|
|
public int Version { get; set; }
|
|
public DateTimeOffset CreatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
|
|
public DateTimeOffset UpdatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
|
|
}
|
|
|
|
// Append-only history: one row per save, so profile edits are never silently lost.
|
|
public sealed class CareerProfileVersion
|
|
{
|
|
public int Id { get; set; }
|
|
public string OwnerUserId { get; set; } = string.Empty;
|
|
public int CareerProfileId { get; set; }
|
|
public CareerProfile? CareerProfile { get; set; }
|
|
public int Version { get; set; }
|
|
public string ProfileJson { get; set; } = string.Empty;
|
|
// Where this version came from: "upload" | "rebuild" | "improve" | "reprocess" | "parse" | "manual".
|
|
public string Source { get; set; } = string.Empty;
|
|
public DateTimeOffset CreatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
|
|
}
|