export type ApplicationStatus = | 'Saved' | 'Applying' | 'Applied' | 'Captcha Required' | 'Intervention Needed' | 'Screening' | 'Interviewing' | 'Offer' | 'Rejected' | 'Withdrawn'; export type PlatformType = | 'LinkedIn' | 'Indeed' | 'Glassdoor' | 'Greenhouse' | 'Lever' | 'Workday' | 'Direct'; export interface JobApplication { id: string; company: string; role: string; platform: PlatformType; location: string; salaryRange?: string; status: ApplicationStatus; matchScore: number; appliedAt: string; jobUrl?: string; jobDescription?: string; tailoredResume?: string; coverLetter?: string; interviewDate?: string; // ISO string calendarEventId?: string; notes?: string; autoApplied?: boolean; contactEmail?: string; timeline?: { date: string; timestamp?: string; action: string; stepType?: 'JOB_EXTRACTION' | 'RESUME_TAILORING' | 'FORM_FILLING' | 'CAPTCHA_CHECK' | 'SUBMISSION_VERIFIED' | 'WORKFLOW' | 'HTTP_REQUEST' | 'BROWSER_AUTOMATION'; level?: 'INFO' | 'SUCCESS' | 'WARNING' | 'ERROR'; details?: string; data?: any; }[]; executionLogs?: { step: number; timestamp: string; category: 'EXTRACTION' | 'AI_TAILORING' | 'FORM_DOM_FILL' | 'CAPTCHA_INTERVENTION' | 'NETWORK_POST' | 'SUBMISSION_VERIFICATION'; title: string; detail: string; httpStatus?: number; responsePayload?: string; domSelectorsFilled?: string[]; }[]; httpResponseDetails?: { statusCode: number; statusText: string; endpointUrl: string; responseHeaders?: Record; rawResponseBody?: string; submittedFields?: Record; }; } export interface JobFeedItem { id: string; title: string; company: string; location: string; salary: string; platform: PlatformType; url: string; postedDate: string; description: string; requiredSkills: string[]; estimatedMatch: number; type: 'Full-time' | 'Contract' | 'Remote' | 'Hybrid'; } export interface UserProfile { fullName: string; email: string; phone: string; location: string; linkedinUrl: string; githubUrl: string; portfolioUrl: string; summary: string; experience: { id: string; title: string; company: string; period: string; bullets: string[]; }[]; skills: string[]; education: { degree: string; institution: string; year: string; }[]; // Equal Employment Opportunity (EEO) & Legal Declarations eeoDeclarations?: { veteranStatus: 'NOT_VETERAN' | 'PROTECTED_VETERAN' | 'PREFER_NOT_TO_SAY'; disabilityStatus: 'NO_DISABILITY' | 'YES_DISABILITY' | 'PREFER_NOT_TO_SAY'; gender: 'MALE' | 'FEMALE' | 'NON_BINARY' | 'PREFER_NOT_TO_SAY'; ethnicity: 'WHITE' | 'HISPANIC' | 'BLACK' | 'ASIAN' | 'TWO_OR_MORE' | 'PREFER_NOT_TO_SAY'; workAuthorization: 'US_CITIZEN' | 'PERMANENT_RESIDENT' | 'VISA_SPONSORSHIP_REQUIRED' | 'NEED_SPONSORSHIP'; requiresSponsorshipNowOrFuture: boolean; clearanceLevel?: 'NONE' | 'SECRET' | 'TOP_SECRET' | 'TS_SCI'; }; autoApplyCriteria: { enabled: boolean; targetRoles: string[]; minMatchScore: number; maxDailyApplications: number; preferredLocations: string[]; minSalary: number; excludedCompanies: string[]; preferredPlatforms: PlatformType[]; }; // LLM Provider & Local LM Studio Fallback Settings llmConfig?: { primaryProvider: 'gemini' | 'lmstudio' | 'openai_compatible'; fallbackToLocal: boolean; lmStudioBaseUrl: string; // e.g., http://localhost:1234/v1 or http://127.0.0.1:1234/v1 lmStudioModel: string; // e.g., local-model or qwen2.5-coder-7b-instruct customApiKey?: string; }; } export interface NotificationLog { id: string; timestamp: string; type: 'AUTO_APPLY' | 'INTERVIEW_SCHEDULED' | 'STATUS_CHANGE' | 'WEEKLY_DIGEST' | 'SYSTEM'; recipient: string; subject: string; body: string; status: 'SENT' | 'FAILED' | 'QUEUED'; platform?: string; } export interface CalendarInterviewEvent { id: string; applicationId: string; company: string; role: string; interviewType: 'Phone Screen' | 'Technical Round' | 'Behavioral' | 'System Design' | 'Final Round'; startTime: string; endTime: string; locationOrUrl?: string; googleCalendarEventId?: string; syncedToGoogle: boolean; interviewer?: string; notes?: string; } export interface AutoApplyLog { id: string; timestamp: string; company: string; role: string; matchScore: number; status: 'SUCCESS' | 'SKIPPED' | 'FAILED'; reason?: string; resumeTailored: boolean; }