### Run Development Server (Bash) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/README.md Commands to start the Next.js development server. These commands are executed in the terminal using different package managers. They require Node.js and npm/yarn/pnpm/bun to be installed. ```bash npm run dev # or yarn dev # or pnpm dev # or bun dev ``` -------------------------------- ### Resume Analysis: Step-by-Step Example (Python-like Pseudocode) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md Demonstrates a detailed step-by-step process for analyzing a resume PDF. This includes extracting text from the PDF, cleaning and preprocessing the raw text (tokenization, stop-word removal), extracting keywords from both the resume and job description, and simulating an AI response with match scores and suggestions. ```pseudocode print('Input: Resume PDF, Job Description') # Step 1: PDF Text Extraction raw_text = extract_text_from_pdf('Software Engineer Resume.pdf') print(f'Extracted Text: {raw_text[:100]}...') # Displaying a snippet # Step 2: Text Preprocessing cleaned_text = preprocess_text(raw_text) tokens = tokenize(cleaned_text) filtered_tokens = remove_stopwords(tokens) print(f'Processed Tokens: {filtered_tokens}') # Step 3: Keyword Extraction & Analysis resume_keywords = extract_keywords(filtered_tokens) job_keywords = extract_keywords(preprocess_text(job_description)) found_keywords = set(resume_keywords).intersection(job_keywords) missing_keywords = set(job_keywords).difference(resume_keywords) match_score = (len(found_keywords) / len(job_keywords)) * 100 print(f'Resume Keywords: {resume_keywords}') print(f'Job Keywords: {job_keywords}') print(f'Match Analysis: Found: {list(found_keywords)}, Missing: {list(missing_keywords)}, Score: {match_score:.0f}%') # Step 4: AI Contextual Analysis (Simulated) # This would involve sending resume_keywords, job_keywords, and other context to an AI model. # The response below is a simulated example. simulated_ai_response = { "match_score": 65, "missing_keywords": ["vue.js", "typescript", "css", "responsive design"], "present_keywords": ["react", "javascript", "web development"], "suggestions": [ "Add CSS/SCSS experience", "Include TypeScript projects", "Mention responsive design skills" ] } print(f'AI Response: {simulated_ai_response}') ``` -------------------------------- ### Real-time Data Sync with Supabase (TypeScript) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md Implements real-time data synchronization for job applications and resume analysis using Supabase. It sets up event listeners for database changes to update the application list and notify when analysis is complete. Requires Supabase client setup. ```typescript import { supabase } from './supabaseClient'; // Assuming supabase client is exported from here export class RealtimeSync { setupSubscriptions(userId: string) { // Listen to job application changes supabase .channel("job_applications") .on( "postgres_changes", { event: "*", schema: "public", table: "job_applications", filter: `user_id=eq.${userId}`, }, (payload) => { this.updateApplicationsList(payload) } ) .subscribe() // Listen to analysis completion supabase .channel("resume_analysis") .on( "postgres_changes", { event: "INSERT", schema: "public", table: "resume_analysis", }, (payload) => { this.notifyAnalysisComplete(payload) } ) .subscribe() } // Placeholder methods for actual logic private updateApplicationsList(payload: any) { console.log('Job application changed:', payload); // Implement logic to update the UI or data store } private notifyAnalysisComplete(payload: any) { console.log('Resume analysis complete:', payload); // Implement logic to notify the user or trigger next steps } } ``` -------------------------------- ### Cover Letter Generation: Step-by-Step Example (Python-like Pseudocode) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md Illustrates the detailed process of generating a cover letter. It covers input data collection and validation (user profile, job details), constructing a detailed AI prompt incorporating system instructions and user-specific information, and simulating the AI content generation output, including placeholders for dynamic content. ```pseudocode print('Input: Position, Company, User Resume, Job Description, Tone, Language') # Step 1: Data Collection & Validation user_profile = { "name": "John Doe", "experience": "3 years", "skills": ["React", "JavaScript", "Node.js"] } job_details = { "company": "TechCorp", "position": "Frontend Developer", "requirements": ["React", "TypeScript", "CSS"] } validation_status = validate_data(user_profile, job_details) print(f'Validation: {validation_status}') # Step 2: AI Prompt Construction system_prompt = "You are a professional cover letter writer. Adapt your tone and style based on the user's request." user_prompt = f"Generate a professional cover letter in English for:\n" user_prompt += f"- Position: {job_details['position']} at {job_details['company']}\n" user_prompt += f"- Candidate: {user_profile['name']} with {user_profile['experience']} {user_profile['skills'][0]} experience\n" user_prompt += f"- Key skills: {', '.join(user_profile['skills'])}\n" user_prompt += f"- Job requirements: {', '.join(job_details['requirements'])}\n" user_prompt += f"- Tone: Professional\n" user_prompt += f"- Length: Medium (300-400 words)" print('--- AI Prompt ---') print(system_prompt) print(user_prompt) print('--- End AI Prompt ---') # Step 3: AI Content Generation (Simulated) # This is a simulated output from an AI model. generated_content = "Dear Hiring Manager,\n\nI am writing to express my strong interest in the Frontend Developer position at TechCorp. With 3 years of experience in React development and a passion for creating intuitive user interfaces...\n\nMy experience with React and JavaScript aligns well with your requirements. While I have primarily worked with JavaScript, I am eager to expand my skills in TypeScript...\n\nBest regards,\nJohn Doe" print('--- Generated Content ---') print(generated_content) print('--- End Generated Content ---') ``` -------------------------------- ### Resume Analysis API - Analyze compatibility and get suggestions Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt This API endpoint analyzes a resume against a job description to determine compatibility and provide improvement suggestions. It takes job details and resume content as input and outputs missing keywords, suggestions for improvement, potential job title matches, and an overall match score. The 'language' parameter is optional for multilingual analysis. ```typescript // API Endpoint: POST /api/resume-analyze const response = await fetch('/api/resume-analyze', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ position: 'Senior Frontend Developer', company: 'Tech Corp', description: 'We are looking for an experienced React developer...', resume: 'John Doe\nSoftware Engineer with 5 years experience...', language: 'English' // Optional: supports multilingual analysis }) }); const result = await response.json(); console.log(result); /* Output: { keywords: { missing: ['TypeScript', 'Next.js', 'GraphQL'], present: ['React', 'JavaScript', 'CSS'], suggestions: ['Redux', 'Jest', 'CI/CD'] }, suggestions: [ { section: 'Skills', improvement: 'Add TypeScript and Next.js to your technical skills', priority: 'high' } ], jobTitleMissing: [ { title: 'Lead Developer', relevance: 'Shows progression to senior roles', where: 'under work experience' } ], matchScore: 72 } */ ``` -------------------------------- ### Resume Analysis Result Type Definition Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Defines a TypeScript interface `ResumeAnalysisResult` for structuring the output of an AI resume analysis. It includes properties for keywords (missing, present, suggestions), improvement suggestions categorized by section and priority, missing job titles with relevance, and a match score. An example function demonstrates how to fetch and process this analysis data. ```typescript // Resume Analysis Result Interface interface ResumeAnalysisResult { keywords: { missing: string[]; present: string[]; suggestions: string[]; }; suggestions: Array<{ section: string; improvement: string; priority: 'high' | 'medium' | 'low'; }>; jobTitleMissing: Array<{ title: string; relevance: string; where: string; }>; matchScore: number; // 0-100 } // Usage in component async function analyzeResume(jobId: string, resumeId: string) { const response = await fetch('/api/resume-analyze', { method: 'POST', body: JSON.stringify({ jobId, resumeId }) }); const analysis: ResumeAnalysisResult = await response.json(); // High priority suggestions const criticalImprovements = analysis.suggestions .filter(s => s.priority === 'high') .map(s => s.improvement); return analysis; } ``` -------------------------------- ### Supabase Client Initialization and Queries Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Server-side Supabase client initialization with SSR support. It demonstrates how to create a Supabase client in server components and perform data fetching operations, including selecting specific fields and joining related data with Row Level Security (RLS) considerations. ```typescript // Initialize Supabase client for server components import { createClient } from '@/utils/supabase/server'; async function getJobApplications() { const supabase = await createClient(); const { data, error } = await supabase .from('job_applications') .select('*') .order('created_at', { ascending: false }); if (error) throw error; return data; } // With Row Level Security (RLS) enabled const { data: userJobs } = await supabase .from('job_applications') .select ( ` id, position, company, status, resumes ( title, file_name ) `) .eq('user_id', userId); ``` -------------------------------- ### API Endpoints Structure Diagram Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/ARSITEKTUR_SISTEM_SILAMAR.md A Mermaid graph visualizing the structure of API routes and their corresponding server actions and external API integrations. It shows the flow from API endpoints to server logic and external services like OpenAI and Supabase. ```mermaid graph TD subgraph "API Routes" ParsePDF["/api/parse-pdf"] ResumeAnalyze["/api/resume-analyze"] CoverLetter["/api/cover-letter-generator"] ScrapeJob["/api/scrape-job"] end subgraph "Server Actions" JobActions["Job Application Actions"] DocumentActions["Document Actions"] AnalysisActions["Analysis Actions"] AuthActions["Auth Actions"] end subgraph "External APIs" OpenAI["OpenAI API"] JobSites["Job Scraping APIs"] Storage["Supabase Storage API"] end ParsePDF --> Storage ResumeAnalyze --> OpenAI CoverLetter --> OpenAI ScrapeJob --> JobSites JobActions --> Database[(Database)] DocumentActions --> Database AnalysisActions --> Database AuthActions --> Database style ParsePDF fill:#e3f2fd style ResumeAnalyze fill:#e8f5e8 style CoverLetter fill:#fce4ec style ScrapeJob fill:#fff3e0 ``` -------------------------------- ### Google OAuth Authentication with Supabase Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Implements Google OAuth authentication using Supabase. The `signInWithGoogle` server action initiates the OAuth flow, redirecting the user to Google for authentication and then back to a callback URL. It also demonstrates how to retrieve the currently authenticated user. ```typescript // Server Action:signInWithGoogle 'use server' import { createClient } from '@/utils/supabase/server'; export async function signInWithGoogle() { const supabase = await createClient(); const { data, error } = await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: `${process.env.NEXT_PUBLIC_BASE_URL}/auth/callback`, queryParams: { access_type: 'offline', prompt: 'consent', } } }); if (error) throw error; return data.url; // Redirect URL } // Get current authenticated user import { getCurrentUser } from '@/server/queries/get-current-user'; const [user, error] = await getCurrentUser(); if (!user) { redirect('/auth'); } ``` -------------------------------- ### Upload Resume Server Action Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Server action to upload PDF resumes. It accepts a file, title, and description, then processes the upload and extracts text. Dependencies include '@/features/documents/server/actions/uploud-resume'. This action stores files in Supabase Storage and text in the database. ```typescript // Server Action: uploadResume 'use server' import uploadResume from '@/features/documents/server/actions/uploud-resume'; // In a form submission handler const formData = new FormData(); const file = document.querySelector('input[type="file"]').files[0]; const result = await uploadResume({ file: file, title: 'Software Engineer Resume', description: 'Updated resume with latest projects' }); if (result[0] === undefined) { console.log('Resume uploaded and parsed successfully'); // File is stored in Supabase Storage // Text is extracted and stored in database // Path: /documents page is revalidated } else { console.error('Upload failed:', result[1].message); } ``` -------------------------------- ### Environment Configuration Interface (TypeScript) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/ARSITEKTUR_SISTEM_SILAMAR.md Defines the structure for environment variables used in the application. It includes variables for Supabase authentication, AI service API keys, and general application settings like the base URL and Node environment. This interface ensures type safety for configuration access. ```typescript interface Config { // Database NEXT_PUBLIC_SUPABASE_URL: string NEXT_PUBLIC_SUPABASE_ANON_KEY: string // AI Services OPENAI_API_KEY: string TOGETHER_AI_API_KEY: string // Application NEXT_PUBLIC_BASE_URL: string NODE_ENV: "development" | "production" } ``` -------------------------------- ### Cover Letter Generation API Flow Sequence Diagram Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/ARSITEKTUR_SISTEM_SILAMAR.md Sequence diagram illustrating the flow for the cover letter generation API endpoint. It shows how the client request triggers data retrieval from the database, content generation via OpenAI, and storage of the cover letter. ```mermaid sequenceDiagram participant Client participant API participant OpenAI participant DB as Database Client->>API: POST /api/cover-letter-generator API->>DB: Get user profile & job details API->>OpenAI: Generate cover letter OpenAI-->>API: Generated content API->>DB: Store cover letter API-->>Client: Return formatted letter ``` -------------------------------- ### Resume Analysis: PDF Text Extraction to AI Response Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md This process outlines the steps involved in analyzing a resume PDF for a specific job description. It includes extracting text from the PDF, preprocessing the text, extracting keywords, performing AI contextual analysis, and generating a final report with match scores, missing keywords, and improvement suggestions. ```mermaid flowchart TD A[๐Ÿ“„ Upload Resume PDF] --> B[๐Ÿ”ง Text Extraction] B --> C[๐Ÿงน Text Preprocessing] C --> D[๐Ÿ“Š Keyword Extraction] E[๐Ÿ“‹ Job Description Input] --> F[๐Ÿงน JD Preprocessing] F --> G[๐Ÿ“Š JD Keyword Extraction] D --> H[๐Ÿค– AI Analysis Engine] G --> H H --> I[๐Ÿ“ˆ Match Score Calculation] H --> J[๐Ÿ” Missing Keywords] H --> K[๐Ÿ’ก Improvement Suggestions] I --> L[๐Ÿ“Š Final Report] J --> L K --> L ``` -------------------------------- ### AI Prompt Engineering (TypeScript) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md This code demonstrates prompt engineering for AI models like GPT-4. It includes structured prompts for resume analysis and cover letter generation, specifying desired output formats and content. ```typescript // Resume Analysis Prompt const resumeContent = "..."; // Placeholder for actual resume text const jobDescription = "..."; // Placeholder for actual job description const analysisPrompt = ` Analyze this resume against the job description: RESUME CONTENT: ${resumeContent} JOB DESCRIPTION: ${jobDescription} Please provide: 1. Match score (0-100%) 2. Missing keywords 3. Present keywords 4. Improvement suggestions 5. Missing job titles Format as JSON response. `; // Cover Letter Generation Prompt const tone = "professional"; // Example tone const language = "English"; // Example language const position = "Software Engineer"; // Example position const company = "Tech Corp"; // Example company const length = "standard"; // Example length const coverLetterPrompt = ` Generate a ${tone} cover letter in ${language} for ${position} at ${company}. Resume: ${resumeContent} Job Description: ${jobDescription} Length: ${length} `; console.log('Analysis Prompt:', analysisPrompt); console.log('Cover Letter Prompt:', coverLetterPrompt); // In a real application, these prompts would be used to call an AI service like OpenAI: // const analysisResponse = await openai.chat.completions.create({ // model: "gpt-4", // messages: [{ role: "user", content: analysisPrompt }] // }); // const coverLetterResponse = await openai.chat.completions.create({ // model: "gpt-4", // messages: [{ role: "user", content: coverLetterPrompt }] // }); ``` -------------------------------- ### Database Schema for AI Resume Project Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/ARSITEKTUR_SISTEM_SILAMAR.md This Mermaid diagram defines the database schema for the AI Resume project, including tables for users, resumes, job applications, resume analysis, and cover letters. It shows relationships between tables using foreign keys. ```mermaid erDiagram users { uuid id PK string email string full_name timestamp created_at timestamp updated_at } resumes { uuid id PK uuid user_id FK string title string description string file_name string file_type integer file_size string storage_path string storage_url text extracted_text timestamp created_at timestamp updated_at } job_applications { uuid id PK uuid user_id FK uuid resume_id FK string position string company string location text description enum job_type enum status enum priority decimal salary string currency string source_url timestamp applied_at timestamp created_at timestamp updated_at } resume_analysis { uuid id PK uuid resume_id FK uuid job_application_id FK integer match_score jsonb suggestions jsonb job_title_missing array keywords_present array keywords_missing array keywords_suggestions timestamp created_at timestamp updated_at } cover_letters { uuid id PK uuid job_application_id FK text content timestamp generated_at timestamp created_at timestamp updated_at } users ||--o{ resumes : "owns" users ||--o{ job_applications : "creates" resumes ||--o{ job_applications : "used_for" job_applications ||--o{ resume_analysis : "analyzed" job_applications ||--o{ cover_letters : "has" resumes ||--o{ resume_analysis : "analyzed" ``` -------------------------------- ### Add Job Application Server Action Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Server action to create new job applications. It takes job details as input and returns a result indicating success or failure. Dependencies include '@/features/job-tracker/server/actions/add-job-application'. ```typescript // Server Action: addJobApplication 'use server' import addJobApplication from '@/features/job-tracker/server/actions/add-job-application'; const result = await addJobApplication({ company: 'Microsoft', position: 'Cloud Engineer', location: 'Seattle, WA', salary: 140000, description: 'Azure cloud infrastructure...', status: 'applied', // applied, interview, offer, rejected, accepted priority: 'high', // low, medium, high job_type: 'full_time', // full_time, part_time, contract, remote, hybrid, etc. source_url: 'https://careers.microsoft.com/job/12345' }); if (result[0]) { console.log('Job application added successfully'); } else { console.error('Error:', result[1].message); } ``` -------------------------------- ### Security Layers Diagram for AI Resume Project Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/ARSITEKTUR_SISTEM_SILAMAR.md Mermaid graph outlining the various security layers implemented in the AI Resume project, categorized into Client Security, Application Security, Data Security, and API Security. It highlights key security measures like CSP, RLS, and Rate Limiting. ```mermaid graph TB subgraph "Client Security" CSP[Content Security Policy] HTTPS[HTTPS Encryption] Auth[Client Authentication] end subgraph "Application Security" Middleware[Auth Middleware] Validation[Input Validation] CSRF[CSRF Protection] end subgraph "Data Security" RLS[Row Level Security] Encryption[Data Encryption] Backup[Encrypted Backups] end subgraph "API Security" RateLimit[Rate Limiting] APIKeys[API Key Management] CORS[CORS Policy] end Client --> Middleware Middleware --> RLS Validation --> Encryption APIKeys --> OpenAI[External APIs] style CSP fill:#ffebee style RLS fill:#e8f5e8 style RateLimit fill:#e3f2fd ``` -------------------------------- ### Resume Analysis API Flow Sequence Diagram Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/ARSITEKTUR_SISTEM_SILAMAR.md Sequence diagram illustrating the flow for the resume analysis API endpoint. It details the interaction between the client, API, OpenAI, and the database for fetching data, performing analysis, and storing results. ```mermaid sequenceDiagram participant Client participant API participant OpenAI participant DB as Database Client->>API: POST /api/resume-analyze API->>DB: Get resume & job data API->>OpenAI: Analyze compatibility OpenAI-->>API: Analysis results API->>DB: Store analysis API-->>Client: Return recommendations ``` -------------------------------- ### Cover Letter Generation: AI Prompt Engineering Strategy Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md The process for generating a cover letter involves user profile data, resume content, and job description as input. An AI prompt builder constructs the request, followed by template selection, content generation, and post-processing to produce a formatted output. AI configuration options include tone, language, and length preferences. ```mermaid flowchart TD A[๐Ÿ‘ค User Profile Data] --> D[๐Ÿค– AI Prompt Builder] B[๐Ÿ“„ Resume Content] --> D C[๐Ÿ“‹ Job Description] --> D D --> E[๐Ÿ”ง Template Selection] E --> F[โœ๏ธ Content Generation] F --> G[๐Ÿ“ Post-processing] G --> H[๐Ÿ“„ Formatted Output] H --> I[๐Ÿ’พ Save to Database] subgraph "AI Configuration" J[๐ŸŽฏ Tone Selection] K[๐ŸŒ Language Choice] L[๐Ÿ“ Length Preference] end J --> E K --> E L --> E ``` -------------------------------- ### Query Job Applications with Related Data using Supabase Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Fetches job application details along with related data from resumes, resume analysis, and cover letters using Supabase's client library. It uses `select` with nested relationships to retrieve all required information in a single query. The query filters by a specific job application ID and expects a single result. ```typescript // Get job application with resume and analysis const { data: jobDetails } = await supabase .from('job_applications') .select( ` id, position, company, location, description, status, priority, job_type, salary, applied_at, resumes ( id, title, file_name, storage_url, extracted_text ), resume_analysis ( match_score, keywords_present, keywords_missing, keywords_suggestions, suggestions ), cover_letters ( id, content, generated_at ) `) .eq('id', jobApplicationId) .single(); console.log(jobDetails); /* Output: { id: 'job-uuid', position: 'Frontend Developer', company: 'Tech Corp', resumes: { title: 'My Resume 2025', extracted_text: 'Resume content...' }, resume_analysis: { match_score: 85, keywords_missing: ['TypeScript', 'GraphQL'] }, cover_letters: { content: 'Dear Hiring Manager...' } } */ ``` -------------------------------- ### Cover Letter Generator Service Implementation (TypeScript) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md This service generates a formatted cover letter based on provided data. It involves building context from input, constructing a prompt for an AI model, generating content, and post-processing the output for formatting and personalization. Dependencies include an AI model API and data structures for cover letter requests. ```typescript // Cover Letter Generator Service export class CoverLetterService { async generateCoverLetter(data: CoverLetterRequest) { // Step 1: Build context const context = await this.buildContext(data) // Step 2: Construct prompt const prompt = this.buildPrompt(context) // Step 3: Generate content const content = await this.callAI(prompt) // Step 4: Post-process const formatted = this.formatContent(content, data.preferences) // Step 5: Save and return return await this.saveCoverLetter(formatted, data.userId) } private buildPrompt(context: Context): string { return ` Generate a ${context.tone} cover letter in ${context.language} for: Position: ${context.position} at ${context.company} Candidate: ${context.candidateName} Skills: ${context.skills.join(", ")} Experience: ${context.experience} Job Requirements: ${context.jobRequirements} Length: ${context.length} Format: Professional business letter with proper structure. ` } } ``` -------------------------------- ### Resume Analysis API Route (Next.js/TypeScript) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md This Next.js API route handles POST requests for resume analysis. It parses JSON input, extracts resume content, calls an AI model for analysis via OpenAI, and saves the results. ```typescript import { NextApiRequest, NextApiResponse } from 'next'; import OpenAI from 'openai'; // Assuming getResumeContent and saveAnalysisResult are defined elsewhere // declare function getResumeContent(resumeId: string): Promise; // declare function saveAnalysisResult(analysis: any): Promise; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, }); export async function POST(request: Request) { try { const body = await request.json(); const { resumeId, jobDescription } = body; if (!resumeId || !jobDescription) { return new Response(JSON.stringify({ error: 'Missing resumeId or jobDescription' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } // 1. Extract resume content const resume = await getResumeContent(resumeId); // 2. AI Analysis using OpenAI const analysis = await openai.chat.completions.create({ model: "gpt-4", messages: [ { role: "system", content: "You are an expert resume analyzer. Provide analysis in JSON format.", }, { role: "user", content: `Resume: ${resume}\nJob: ${jobDescription}`, }, ], response_format: { type: "json_object" } // Ensure JSON output }); const analysisContent = analysis.choices[0].message.content; if (!analysisContent) { throw new Error('OpenAI did not return analysis content.'); } const parsedAnalysis = JSON.parse(analysisContent); // 3. Save results const saveResult = await saveAnalysisResult(parsedAnalysis); return new Response(JSON.stringify({ message: 'Analysis successful', data: parsedAnalysis }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); } catch (error) { console.error('API Error:', error); return new Response(JSON.stringify({ error: 'Failed to analyze resume', details: error.message }), { status: 500, headers: { 'Content-Type': 'application/json' }, }); } } // Dummy implementations for demonstration async function getResumeContent(resumeId: string): Promise { // Replace with actual logic to fetch resume content from database or storage console.log(`Fetching content for resume ID: ${resumeId}`); return "Dummy resume content..."; } async function saveAnalysisResult(analysis: any): Promise { // Replace with actual logic to save analysis results to database console.log('Saving analysis result:', analysis); // Dummy response for success return new Response(JSON.stringify({ success: true }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); } ``` -------------------------------- ### Resume Analysis API Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Analyzes resume compatibility with job descriptions and provides improvement suggestions. It returns a match score, missing keywords, and specific suggestions for improvement. ```APIDOC ## POST /api/resume-analyze ### Description Analyzes resume compatibility with job descriptions and provides improvement suggestions. ### Method POST ### Endpoint /api/resume-analyze #### Request Body - **position** (string) - Required - The job position title. - **company** (string) - Required - The company name. - **description** (string) - Required - The job description text. - **resume** (string) - Required - The resume text. - **language** (string) - Optional - The language of the resume and job description for analysis (e.g., 'English'). ### Request Example ```json { "position": "Senior Frontend Developer", "company": "Tech Corp", "description": "We are looking for an experienced React developer...", "resume": "John Doe\nSoftware Engineer with 5 years experience...", "language": "English" } ``` ### Response #### Success Response (200) - **keywords** (object) - Analysis of keywords found in the resume compared to the job description. - **missing** (array) - List of keywords from the job description that are missing in the resume. - **present** (array) - List of keywords from the job description that are present in the resume. - **suggestions** (array) - Suggested keywords to add to the resume. - **suggestions** (array) - Specific improvement suggestions for different sections of the resume. - **section** (string) - The resume section to improve. - **improvement** (string) - The suggested improvement. - **priority** (string) - The priority of the suggestion (e.g., 'high'). - **jobTitleMissing** (array) - Potential job titles that could be added to showcase career progression. - **title** (string) - The suggested job title. - **relevance** (string) - The relevance or benefit of adding this title. - **where** (string) - Where in the resume this could be added. - **matchScore** (integer) - The overall compatibility score between the resume and the job description (0-100). #### Response Example ```json { "keywords": { "missing": ["TypeScript", "Next.js", "GraphQL"], "present": ["React", "JavaScript", "CSS"], "suggestions": ["Redux", "Jest", "CI/CD"] }, "suggestions": [ { "section": "Skills", "improvement": "Add TypeScript and Next.js to your technical skills", "priority": "high" } ], "jobTitleMissing": [ { "title": "Lead Developer", "relevance": "Shows progression to senior roles", "where": "under work experience" } ], "matchScore": 72 } ``` ``` -------------------------------- ### Resume Analysis Service Implementation (TypeScript) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md This service analyzes a resume against a job description to calculate a match score and extract relevant keywords. It involves extracting PDF text, preprocessing, keyword extraction, and AI analysis. Dependencies include functions for PDF text extraction, text preprocessing, keyword extraction, and AI analysis. ```typescript // Resume Analysis Service export class ResumeAnalysisService { async analyzeResume(resumeId: string, jobDescription: string) { // Step 1: Extract resume text const resumeText = await this.extractPDFText(resumeId) // Step 2: Preprocess text const cleanedResume = this.preprocessText(resumeText) const cleanedJob = this.preprocessText(jobDescription) // Step 3: Extract keywords const resumeKeywords = this.extractKeywords(cleanedResume) const jobKeywords = this.extractKeywords(cleanedJob) // Step 4: Calculate similarity const matchScore = this.calculateMatchScore(resumeKeywords, jobKeywords) // Step 5: AI analysis const aiAnalysis = await this.getAIAnalysis(resumeText, jobDescription) return { matchScore, keywords: { resume: resumeKeywords, job: jobKeywords }, analysis: aiAnalysis, } } private calculateMatchScore(resumeKW: string[], jobKW: string[]): number { const intersection = resumeKW.filter((kw) => jobKW.includes(kw)) return Math.round((intersection.length / jobKW.length) * 100) } } ``` -------------------------------- ### Cover Letter Generator API Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Generates personalized cover letters based on resume, company, and job description details. Supports customizable tone, language, and length, with streaming responses. ```APIDOC ## POST /api/cover-letter-generator ### Description Generates personalized cover letters with streaming responses based on provided resume, company, and job details. ### Method POST ### Endpoint /api/cover-letter-generator #### Request Body - **resume** (string) - Required - The resume text. - **company** (string) - Required - The name of the company. - **position** (string) - Required - The job position title. - **jobDescription** (string) - Required - The job description text. - **tone** (string) - Optional - The desired tone of the cover letter. Options: 'formal', 'semi-formal', 'friendly'. Defaults to 'semi-formal'. - **language** (string) - Optional - The language for the cover letter. Defaults to 'English'. - **length** (string) - Optional - The desired length of the cover letter. Options: 'short', 'medium', 'long'. Defaults to 'medium'. ### Request Example ```json { "resume": "John Doe\nSoftware Engineer...", "company": "Tech Innovations", "position": "Frontend Developer", "jobDescription": "Looking for a React expert...", "tone": "semi-formal", "language": "English", "length": "medium" } ``` ### Response #### Success Response (200) - **coverLetter** (string) - The generated cover letter content. The response is streamed. #### Response Example ``` [Current Date] Dear Hiring Manager at Tech Innovations, I am writing to express my strong interest in the Frontend Developer position... [Complete cover letter with 250-350 words in professional tone] Sincerely, John Doe ``` ``` -------------------------------- ### Environment Configuration with T3 Env Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Type-safe environment variables using T3 Env. This configuration defines server and client-side environment variables with Zod validation. It ensures that critical variables like API keys and Supabase credentials are correctly defined and accessed. ```typescript // src/config/env.ts import { createEnv } from '@t3-oss/env-nextjs'; import { z } from 'zod'; export const env = createEnv({ server: { TOGETHER_AI_API_KEY: z.string().min(1), OPENAI_API_KEY: z.string().min(1), }, client: { NEXT_PUBLIC_SUPABASE_URL: z.string().url(), NEXT_PUBLIC_SUPABASE_ANON_KEY: z.string().min(1), NEXT_PUBLIC_BASE_URL: z.string().url(), }, experimental__runtimeEnv: { NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL, } }); // Usage in application import { env } from '@/config/env'; const apiKey = env.OPENAI_API_KEY; // Type-safe access ``` -------------------------------- ### Job Scraper API Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Scrapes job posting details from a given URL, automatically detecting the platform (LinkedIn, JobStreet, etc.). ```APIDOC ## POST /api/scrape-job ### Description Scrapes job posting details from a given URL, automatically detecting the platform (e.g., LinkedIn, JobStreet). ### Method POST ### Endpoint /api/scrape-job #### Request Body - **url** (string) - Required - The URL of the job posting. ### Request Example ```json { "url": "https://www.linkedin.com/jobs/view/4058541593" } ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the scraping was successful. - **data** (object) - Contains the scraped job details if successful. - **position** (string) - The job title. - **company** (string) - The company name. - **location** (string) - The job location. - **description** (string) - The job description text. - **jobType** (string) - The type of employment (e.g., 'full_time'). - **salary** (string) - The salary range, if available. - **platform** (string) - The detected platform of the job posting. #### Response Example ```json { "success": true, "data": { "position": "Senior Software Engineer", "company": "Google", "location": "Mountain View, CA", "description": "We are looking for a talented engineer...", "jobType": "full_time", "salary": "$150,000 - $200,000", "platform": "linkedin" } } ``` #### Error Response (e.g., 400, 500) - **success** (boolean) - False. - **error** (string) - An error message describing the failure. #### Additional Example (JobStreet) ```json { "url": "https://id.jobstreet.com/id/job/123456" } ``` ``` -------------------------------- ### Resume Analysis Component (React/TypeScript) Source: https://github.com/thenotoriousgustav/ai-resume/blob/main/PRESENTASI_SIDANG_SKRIPSI.md This React component handles the user interface for resume analysis. It includes state management for analysis results and loading status, and an asynchronous function to call the backend for analysis. ```typescript import { useState } from 'react'; // Assuming AnalysisResult and aiAnalyzeResume are defined elsewhere // interface AnalysisResult { ... } // declare function aiAnalyzeResume(resumeId: string, jobDescription: string): Promise; export function ResumeAnalysisPage() { const [analysis, setAnalysis] = useState(null) const [isLoading, setIsLoading] = useState(false) const analyzeResume = async (resumeId: string, jobDescription: string) => { setIsLoading(true) try { const result = await aiAnalyzeResume(resumeId, jobDescription) setAnalysis(result) } catch (error) { console.error('Error analyzing resume:', error) // Handle error appropriately in UI } finally { setIsLoading(false) } } // ... JSX to render the UI, including buttons to trigger analyzeResume and display results/loading state return (
{isLoading ?

Analyzing...

: ( analysis ?
{JSON.stringify(analysis, null, 2)}
:

No analysis yet.

)} {/* Example button to trigger analysis */}
) } ``` -------------------------------- ### Cover Letter Generator API - Generate personalized cover letters Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt This API generates personalized cover letters based on resume details, job description, and user preferences for tone and length. It supports streaming responses for a more interactive user experience. Input includes resume content, company, position, job description, desired tone, language, and length. ```typescript // API Endpoint: POST /api/cover-letter-generator const response = await fetch('/api/cover-letter-generator', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ resume: 'John Doe\nSoftware Engineer...', company: 'Tech Innovations', position: 'Frontend Developer', jobDescription: 'Looking for a React expert...', tone: 'semi-formal', // Options: formal, semi-formal, friendly language: 'English', length: 'medium' // Options: short, medium, long }) }); // Stream the response const reader = response.body.getReader(); const decoder = new TextDecoder(); let coverLetter = ''; while (true) { const { done, value } = await reader.read(); if (done) break; coverLetter += decoder.decode(value); } console.log(coverLetter); /* Output: [Current Date] Dear Hiring Manager at Tech Innovations, I am writing to express my strong interest in the Frontend Developer position... [Complete cover letter with 250-350 words in professional tone] Sincerely, John Doe */ ``` -------------------------------- ### Update Job Application Status with Server Action Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Provides a server action to update the details of a job application, such as its status, priority, and notes. It imports and uses a hypothetical `updateJobDetail` function from '@/features/job-tracker/server/actions/update-job-detail'. The action logs success or error messages and indicates that the page is revalidated automatically upon successful update. ```typescript // Server Action: updateJobDetail 'use server' import { updateJobDetail } from '@/features/job-tracker/server/actions/update-job-detail'; const result = await updateJobDetail({ id: 'job-application-uuid', status: 'interview', priority: 'high', notes: 'Phone screen scheduled for next week' }); if (result[0]) { console.log('Job updated successfully'); // Page is revalidated automatically } else { console.error('Update failed:', result[1].message); } ``` -------------------------------- ### PDF Resume Parser API Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt Extracts and normalizes text content from PDF resumes provided via a URL. ```APIDOC ## POST /api/parse-pdf ### Description Extracts and normalizes text content from PDF resumes provided via a URL. ### Method POST ### Endpoint /api/parse-pdf #### Request Body - **resumeUrl** (string) - Required - The URL of the PDF resume file. ### Request Example ```json { "resumeUrl": "https://storage.supabase.co/documents/user-123/resume.pdf" } ``` ### Response #### Success Response (200) - **extractedText** (string) - The extracted and normalized text content from the PDF resume. #### Response Example ``` "John Doe\nSoftware Engineer\nEmail: john@example.com\nPhone: +1234567890\n\nEXPERIENCE\nFrontend Developer at Company A\n2020 - Present\n- Developed React applications\n- Implemented responsive designs\n\nSKILLS\nJavaScript, React, CSS, HTML..." ``` ``` -------------------------------- ### PDF Resume Parser API - Extract text from PDF resumes Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt This API extracts and normalizes text content from PDF resumes provided via a URL. It takes a resume URL as input and returns the extracted text content, making it easier to process resume information programmatically. This is useful for integrating with other resume analysis tools. ```typescript // API Endpoint: POST /api/parse-pdf const response = await fetch('/api/parse-pdf', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ resumeUrl: 'https://storage.supabase.co/documents/user-123/resume.pdf' }) }); const extractedText = await response.json(); console.log(extractedText); /* Output: "John Doe\nSoftware Engineer\nEmail: john@example.com\nPhone: +1234567890\n\nEXPERIENCE\nFrontend Developer at Company A\n2020 - Present\n- Developed React applications\n- Implemented responsive designs\n\nSKILLS\nJavaScript, React, CSS, HTML..." */ ``` -------------------------------- ### Job Scraper API - Scrape job postings from LinkedIn and JobStreet Source: https://context7.com/thenotoriousgustav/ai-resume/llms.txt This API scrapes job posting details from provided URLs, automatically detecting whether the URL is from LinkedIn or JobStreet. It returns structured data including position, company, location, description, job type, salary, and the platform it was scraped from. This enables easy aggregation of job opportunities. ```typescript // API Endpoint: POST /api/scrape-job const response = await fetch('/api/scrape-job', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: 'https://www.linkedin.com/jobs/view/4058541593' }) }); const result = await response.json(); if (result.success) { console.log(result.data); } /* Output: { success: true, data: { position: 'Senior Software Engineer', company: 'Google', location: 'Mountain View, CA', description: 'We are looking for a talented engineer...', jobType: 'full_time', salary: '$150,000 - $200,000', platform: 'linkedin' } } */ // Also supports JobStreet URLs const jobstreetResponse = await fetch('/api/scrape-job', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: 'https://id.jobstreet.com/id/job/123456' }) }); ```