00a035ea20
Extends the interview-prep persistence pattern (previous commit) to the other two AI-generated per-job outputs that were re-running their full AI call chain on every tab open: candidate-fit (4 AI calls) and focus-plan (4 AI calls). Across all three tabs that's 9 AI calls fired every single time a user revisits a job's AI workspace tabs. Generalized into AiWorkspaceNote (OwnerUserId, JobApplicationId, NoteType, ResultJson) rather than duplicating InterviewPrepNote's per-field-column shape: CandidateFitDto and FocusPlanDto are irregular and nested (up to 13 fields including a nested guidance object), where per-field columns would be unreasonable. One table, keyed by note type, serving both. Same rules as interview prep: reuse across calls, regenerate when the attachment selection changes, regenerate on explicit refresh. Frontend gets the same "Regenerate" button on both tabs. 3 new tests (persist+reuse for both, refresh for candidate-fit). Verified against the real dev DB.
20 lines
1.0 KiB
C#
20 lines
1.0 KiB
C#
namespace JobTrackerApi.Models;
|
|
|
|
// Generic persistence for per-job AI workspace outputs whose shape is irregular/nested enough
|
|
// that per-field columns (as used by InterviewPrepNote) would be unreasonable -- candidate fit
|
|
// and focus plan each make several AI calls and return DTOs with 6-13 fields including nested
|
|
// objects. One row per (owner, job, note type); ResultJson is the serialized DTO. See
|
|
// career-workspace-implementation-roadmap.md Phase F5 -- "persist interview prep / fit outputs".
|
|
public sealed class AiWorkspaceNote
|
|
{
|
|
public int Id { get; set; }
|
|
public string OwnerUserId { get; set; } = string.Empty;
|
|
public int JobApplicationId { get; set; }
|
|
public JobApplication? JobApplication { get; set; }
|
|
// "candidate-fit" | "focus-plan"
|
|
public string NoteType { get; set; } = string.Empty;
|
|
public string AttachmentContextSignature { get; set; } = string.Empty;
|
|
public string ResultJson { get; set; } = string.Empty;
|
|
public DateTimeOffset GeneratedAtUtc { get; set; } = DateTimeOffset.UtcNow;
|
|
}
|