Files
jobtrackingapp/job-tracker-ui/src/types.ts
T
cesnimda 9adbde3f5e feat(S05/T01): Unified workflow trust signals across the API, table, da…
- JobTrackerApi/Controllers/JobApplicationsController.cs
- JobTrackerApi.Tests/JobApplicationsWorkflowSignalsTests.cs
- job-tracker-ui/src/jobWorkflowSignals.ts
- job-tracker-ui/src/components/JobTable.tsx
- job-tracker-ui/src/components/DashboardView.tsx
- job-tracker-ui/src/components/RemindersView.tsx
- job-tracker-ui/src/workflow-trust-signals.test.tsx
2026-03-24 14:28:01 +01:00

270 lines
6.0 KiB
TypeScript

export interface Company {
id: number;
name: string;
location?: string;
source?: string;
recruiterName?: string;
recruiterEmail?: string;
recruiterLinkedIn?: string;
lastContactedAt?: string;
nextContactAt?: string;
pipelineStage?: string;
}
export type WorkflowActionKey = "package-work" | "follow-up" | "interview-prep" | "review-readiness";
export type WorkflowWorkspaceTab = "tailored-cv" | "follow-up" | "interview-prep" | "readiness";
export interface WorkflowSignal {
actionKey: WorkflowActionKey;
reason: string;
workspaceTab: WorkflowWorkspaceTab;
followMode?: string | null;
needsAttention: boolean;
hasPackageGap: boolean;
needsInterviewPrep: boolean;
needsFollowUpAction: boolean;
hasTailoredCv: boolean;
hasSavedApplicationAnswerDraft: boolean;
hasInterviewPrepNotes: boolean;
}
export interface JobApplication {
id: number;
jobTitle: string;
company: Company;
companyId?: number;
status: string;
dateApplied: string;
location?: string;
salary?: string;
nextAction?: string;
followUpAt?: string;
feedbackRequestedAt?: string;
responseReceived: boolean;
responseDate?: string;
description?: string;
translatedDescription?: string;
descriptionLanguage?: string;
tags?: string; // JSON array string
deadline?: string;
notes?: string;
coverLetterText?: string;
recruiterMessageDraft?: string | null;
jobUrl?: string;
shortSummary?: string;
fullSummary?: string | null;
tailoredCvText?: string | null;
tailoredCvUpdatedAt?: string | null;
workflowSignal?: WorkflowSignal | null;
hasResume?: boolean;
hasCoverLetter?: boolean;
hasPortfolio?: boolean;
hasOtherAttachment?: boolean;
daysSince: number;
isDeleted?: boolean;
deletedAt?: string;
needsFollowUp?: boolean;
followUpReason?: string | null;
}
export interface CandidateFitChannelGuidance {
cv: string[];
coverLetter: string[];
interview: string[];
recruiterMessage: string[];
}
export interface CandidateFit {
matchSummary: string;
fitLevel: string;
matchScore: number;
strengths: string[];
gaps: string[];
mention: string[];
avoid: string[];
cvImprovements: string[];
missingKeywords: string[];
interviewPrep: string[];
tailoredPitch: string;
guidance: CandidateFitChannelGuidance;
coverLetterDraft?: string | null;
recruiterMessageDraft?: string | null;
}
export interface FocusPlanResponse {
immediatePriorities: string[];
cvBulletIdeas: string[];
proofPointsToLeadWith: string[];
coverLetterAngles: string[];
followUpApproach: string[];
strategicSummary: string;
}
export interface InterviewPrepResponse {
summary: string;
talkingPoints: string[];
likelyQuestions: string[];
weakSpots: string[];
}
export interface ReadinessResponse {
score: number;
level: string;
completed: string[];
missing: string[];
reminders: string[];
workflowSignal: WorkflowSignal;
}
export interface FollowUpDraft {
subject: string;
body: string;
reason: string;
suggestedSendOn: string;
contextSummary: string;
contextSignals: string[];
threadSubject?: string | null;
lastCorrespondenceFrom?: string | null;
lastCorrespondenceAt?: string | null;
}
export interface ApplicationPackageResponse {
tailoredCvText: string;
coverLetterDraft?: string | null;
applicationAnswerDraft?: string | null;
recruiterMessageDraft?: string | null;
keyPoints: string[];
attachmentSignals: string[];
attachmentFilesUsed: string[];
coverLetterVariants: string[];
recruiterMessageVariants: string[];
}
export interface SaveApplicationDraftsRequest {
coverLetterText?: string | null;
notes?: string | null;
recruiterMessageDraft?: string | null;
}
export interface CorrespondenceMessage {
id: number;
jobApplicationId: number;
from: string;
content: string;
subject?: string;
channel?: string;
date: string;
externalMessageId?: string | null;
externalThreadId?: string | null;
externalFrom?: string | null;
externalTo?: string | null;
}
export interface GmailJobMatchReason {
label: string;
value: string;
}
export interface GmailJobMatchedMessage {
id: string;
threadId: string;
subject: string;
from: string;
to: string;
date?: string;
snippet: string;
score: number;
confidence: string;
alreadyImported: boolean;
matchReasons: GmailJobMatchReason[];
}
export interface GmailJobMatchedThread {
threadId: string;
subject: string;
score: number;
confidence: string;
hasImportedMessages: boolean;
messageCount: number;
latestDate?: string;
matchReasons: GmailJobMatchReason[];
messages: GmailJobMatchedMessage[];
}
export interface GmailJobMatchesResponse {
jobApplicationId: number;
jobTitle: string;
companyName: string;
recruiterName?: string | null;
recruiterEmail?: string | null;
queries: string[];
threads: GmailJobMatchedThread[];
}
export interface GmailImportMessageResult {
imported: number;
skipped: number;
messageId: string;
threadId?: string | null;
message?: CorrespondenceMessage | null;
}
export interface GmailImportThreadResult {
imported: number;
skipped: number;
threadId?: string | null;
}
export interface GmailThreadRefreshThreadResult {
threadId: string;
imported: number;
skipped: number;
totalMessages: number;
status: string;
latestMessageDate?: string;
}
export interface GmailThreadRefreshResult {
jobApplicationId: number;
threadsChecked: number;
imported: number;
skipped: number;
hasLinkedThreads: boolean;
refreshedAt: string;
threads: GmailThreadRefreshThreadResult[];
}
export interface GmailStatus {
connected: boolean;
gmailAddress?: string;
connectedAt?: string;
lastSyncedAt?: string;
}
export interface GmailMessageSummary {
id: string;
threadId: string;
subject: string;
from: string;
to: string;
date?: string;
snippet: string;
}
export interface JobImportResult {
title?: string;
company?: string;
location?: string;
description?: string;
translatedDescription?: string;
language?: string;
tags: string[];
sourceUrl: string;
deadline?: string;
success: boolean;
parser?: string;
error?: string;
}