using JobTrackerApi.Models; using JobTrackerApi.Services; namespace JobTrackerApi.Controllers { public sealed record TailoredCvPreviewDto(string TemplateId, string Html, string SuggestedFileName); public sealed record TailoredCvRenderRequest( string? TemplateId, string? Headline, List? Summary, List? SelectedSkills, List? Experience, List? Education, List? CustomSections, TailoredCvRenderOptions? RenderOptions, string? PhotoDataUrl, bool? UseProfileAvatar); public sealed record AttachmentContextResult(string Context, List Signals, List UsedFiles); public sealed record CorrespondenceContextResult(string Context, List Signals, List Participants, List ThreadIds); public sealed record WorkflowSignalDto( string ActionKey, string Reason, string WorkspaceTab, string? FollowMode, bool NeedsAttention, bool HasPackageGap, bool NeedsInterviewPrep, bool NeedsFollowUpAction, bool HasTailoredCv, bool HasSavedApplicationAnswerDraft, bool HasInterviewPrepNotes ); public sealed record PagedResult(List Items, int Total, int Page, int PageSize); public sealed record JobApplicationDto( int Id, int CompanyId, Company Company, string JobTitle, string Status, // Null while the job is in a pre-application (Prospect) stage — nothing submitted yet. DateTime? DateApplied, // When the user captured the job. Always set, so clients have a date to sort/show for // jobs that have no DateApplied yet. DateTime SavedAt, bool ResponseReceived, DateTime? ResponseDate, string? Notes, string? CoverLetterText, string? JobUrl, string? Description, string? TranslatedDescription, string? DescriptionLanguage, string? Tags, DateTime? Deadline, string? Location, string? Salary, decimal? SalaryMin, decimal? SalaryMax, string? SalaryCurrency, string? SalaryPeriod, string? NextAction, DateTime? FollowUpAt, DateTime? FeedbackRequestedAt, bool HasResume, bool HasCoverLetter, bool HasPortfolio, bool HasOtherAttachment, bool IsDeleted, DateTime? DeletedAt, // Null when DateApplied is null: no elapsed time to report before applying. int? DaysSince, bool NeedsFollowUp, string? FollowUpReason, string? TailoredCvText, WorkflowSignalDto WorkflowSignal, string? ShortSummary, string? FullSummary ); public sealed record CreateJobApplicationRequest( string JobTitle, int CompanyId, string? Status, string? Location, string? Salary, decimal? SalaryMin, decimal? SalaryMax, string? SalaryCurrency, string? SalaryPeriod, string? NextAction, DateTime? FollowUpAt, string? Notes, string? Description, string? TranslatedDescription, string? DescriptionLanguage, string? Tags, DateTime? Deadline, string? CoverLetterText, string? JobUrl, DateTime? DateApplied, DateTime? FeedbackRequestedAt, string? Source = null, string? CountryCode = null ); public sealed record UpdateJobApplicationRequest( string JobTitle, int CompanyId, string Status, bool ResponseReceived, DateTime? ResponseDate, string? Location, string? Salary, decimal? SalaryMin, decimal? SalaryMax, string? SalaryCurrency, string? SalaryPeriod, string? NextAction, DateTime? FollowUpAt, string? Notes, string? Description, string? TranslatedDescription, string? DescriptionLanguage, string? Tags, DateTime? Deadline, string? CoverLetterText, string? JobUrl, DateTime? DateApplied, DateTime? FeedbackRequestedAt, DateTime? StatusChangedAt ); public sealed record UpdateStatusRequest(string Status); // Category = analytics semantics (Prospect/Active/Success/Closed). // Group = how the board collapses stages (NotApplied/Active/Closed). Different axes on purpose // — Offer is Success but still actively worked. See JobPipeline.PipelineGroup. public sealed record PipelineStageDto(string Key, int Order, string Category, string Group); public sealed record StatusSuggestionDto( bool HasSuggestion, string? SuggestedStatus, string? CurrentStatus, string? Signal, string? Confidence, DateTime? MessageDate, string? MessageSubject); public sealed record FollowUpRequest(DateTime? FollowUpAt); public sealed record JobEventDto(int Id, string Type, string? OldValue, string? NewValue, string? Note, DateTime At); public sealed record TimelineItemDto(string Kind, DateTime At, object Data); public sealed record AnalyticsPoint(string Month, int Applied, int Responses); public sealed record TagPoint(string Tag, int Count); public sealed record TagTrendSeries(string Tag, List Counts); public sealed record TagTrendPoint(string Month, List Counts); public sealed record DuplicateCandidateDto(int Id, string JobTitle, string Company, string? JobUrl, string Status, DateTime? DateApplied, string Reason); public sealed record DuplicateCheckResult(bool HasDuplicates, List Matches); public sealed record FollowUpDraftDto(string Subject, string Body, string Reason, DateTime SuggestedSendOn, string ContextSummary, List ContextSignals, string? ThreadSubject, string? LastCorrespondenceFrom, DateTime? LastCorrespondenceAt); public sealed record FocusPlanDto( List ImmediatePriorities, List CvBulletIdeas, List ProofPointsToLeadWith, List CoverLetterAngles, List FollowUpApproach, string StrategicSummary); public sealed record SendFollowUpRequest(string? ToEmail, string Subject, string Body, DateTime? NextFollowUpAt); public sealed record TagTrendResponse(List Months, List Series); public sealed record CandidateFitChannelGuidanceDto(List Cv, List CoverLetter, List Interview, List RecruiterMessage); public sealed record CandidateFitDto( string MatchSummary, string FitLevel, int MatchScore, List Strengths, List Gaps, List Mention, List Avoid, List CvImprovements, List MissingKeywords, List InterviewPrep, string TailoredPitch, CandidateFitChannelGuidanceDto Guidance, string? CoverLetterDraft, string? RecruiterMessageDraft); public sealed record SaveTailoredCvRequest(string? TailoredCvText); public sealed record TailoredCvDraftDto( int? Id, int? CanonicalProfileVersion, string TemplateId, string? Headline, List Summary, List SelectedSkills, List Experience, List Education, List CustomSections, TailoredCvRenderOptions RenderOptions, string? GenerationContextHash, DateTimeOffset? LastGeneratedAtUtc, DateTimeOffset? LastEditedAtUtc, string Status, string RenderedText, bool IsLegacyFallback); public sealed record SaveTailoredCvDraftRequest( string? TemplateId, string? Headline, List? Summary, List? SelectedSkills, List? Experience, List? Education, List? CustomSections, TailoredCvRenderOptions? RenderOptions, string? Status); public sealed record GenerateApplicationPackageDto(string TailoredCvText, string? CoverLetterDraft, string? ApplicationAnswerDraft, string? RecruiterMessageDraft, List KeyPoints, List AttachmentSignals, List AttachmentFilesUsed, List CoverLetterVariants, List RecruiterMessageVariants); public sealed record SaveApplicationDraftsRequest(string? CoverLetterText, string? Notes, string? RecruiterMessageDraft); public sealed record SavedPackageMaterial(string? TailoredCvText, string? CoverLetterText, string? RecruiterMessageDraft, string? Notes); public sealed record InterviewPrepDto(string Summary, List TalkingPoints, List LikelyQuestions, List WeakSpots); public sealed record ReadinessDto(int Score, string Level, List Completed, List Missing, List Reminders, WorkflowSignalDto WorkflowSignal); public sealed record MatchScoreDto( int Score, string Band, int MatchedCount, int TotalKeywords, List MatchedKeywords, List MissingKeywords, List SectionCoverage, bool HasEnoughSignal, IReadOnlyList LearningRecommendations); public sealed record MatchSectionCoverageDto(string Section, int Matched, int Total); }