Work In Progress! 👷

I'm currently working on Coverr, I'll finish this site afterwards.

The summary is then used to generate a list of key details. These key details are then used to generate a list of keywords.

Tech Stack

  • Next.jsNext.js
  • TailwindCSSTailwindCSS
  • PrismaPrisma
  • OpenAIOpenAI
  • TypeScriptTypeScript
  • PostgreSQLPostgreSQL
  • VercelVercel

Description

Revolutionize your job search with Coverr - the ultimate tool that analyzes job descriptions, scours your resume, and generates personalized cover letters! Simply paste in the job description URL and upload your resume, and let our AI-powered system do the rest. Get valuable insights into the technical and soft skills employers are seeking, and receive a custom-crafted cover letter that sets you apart from the competition. With Coverr, your dream job is just a few clicks away!


As a developer, I've always been passionate about creating tools that make people's lives easier. And that's exactly what Coverr does - it streamlines the job search process and gives candidates a competitive edge in the job market. In this blog post, I'd like to share my experience developing Coverr and explain how it works.

The idea for Coverr came to me when I was searching for a job myself. I noticed that many job descriptions included specific technical and soft skills that were essential for the position. However, it was difficult to tailor my resume and cover letter to each job I applied for, especially when I was applying for multiple positions at once. That's when I realized that there had to be a better way to match candidates with job requirements.

Web Scraping

That's when I started working on Coverr. The first step was to create a system that could analyze job descriptions and identify key details such as technical skills, soft skills, and other requirements. I used web scraping techniques to extract the necessary information from job postings and then utilised OpenAI's API to analyze the data and extract the most relevant details. This was no small feat, as job postings can vary greatly in terms of structure and content, but after a lot of trial and error, I was able to create an algorithm that could handle the task.

Resume Analysis

The next step was to develop a system that could analyze resumes and match them with the job requirements identified by the AI. I used natural language processing techniques to identify the most important details in a resume, such as job titles, education, and work experience. This allowed the system to match a candidate's qualifications with the job requirements identified by the AI and generate a list of key details that the candidate should emphasize in their cover letter.

Generating the Cover Letter

Finally, I created a cover letter generator that could take the job requirements and the candidate's resume details and create a personalized cover letter that highlighted the candidate's strengths and qualifications. This was perhaps the most challenging part of the process, as I had to balance the need for personalization with the need for efficiency. However, after many iterations, I was able to create a system that could generate a high-quality cover letter in just 30 seconds.

Problems I Encountered

A problem I had to face was the inconsistency of the data format that was provided back from the LLM, my solution to this problem was to explicitly define the JSON format that I wanted, the code below shows how I did this:

1
const message3: IChatGPTMessage = {
2
role: "assistant",
3
content: "Provide your answer in JSON format, with the following parameters: {softSkills: [], hardSkills: [], otherDetails: []}"
4
}

One of the trickiest problems was making the Cover Letter generator be able to provide multiple options for the user to choose from if the AI wasn't quite sure on what to say. I solved this problem by using a combination of the OpenAI API and a custom algorithm that would generate multiple options for the user to choose from. The code below shows how I did this:

1
/**
2
* Expected data format:
3
* "This is a {test|test2|test3} string"
4
*/
5
6
// Split the text into parts that are surrounded by curly braces
7
const textParts = [...text.matchAll(/{[^}]*}/g)];
8
9
let previousIndex = [0];
10
return (
11
<div className="prose prose-invert whitespace-pre-wrap"
12
ref={innerRef} contentEditable={true}
13
suppressContentEditableWarning={true}>
14
{
15
textParts.map((textPart, i) => {
16
const match = textPart[0];
17
const index = textPart.index;
18
// Split the options by the pipe character
19
const options = match.slice(1, -1).split("|");
20
const selectedOptionIndex = selectedOptions[index] ?? 0;
21
previousIndex.push(index + match.length)
22
23
return (
24
<>
25
{text.slice(previousIndex[i], index)}
26
{/* If there are multiple options,
27
render a <select>
28
otherwise render an <input type="text"> component */}
29
{ options.length > 1 ?
30
<OptionsSelector
31
key={index}
32
options={options}
33
selectedOptionIndex={selectedOptionIndex}
34
onOptionSelect={optionIndex =>
35
handleOptionSelect(index, optionIndex)}
36
/> :
37
<InputSelector initialValue={options[0]} />
38
}
39
</>
40
)
41
})}
42
<>{text.slice(previousIndex[previousIndex.length - 1], text.length)}</>
43
</div>)

Overall, creating Coverr was a challenging but rewarding experience. I'm proud of the tool I've created and the positive impact it can have on job seekers. With Coverr, candidates can spend less time crafting custom cover letters and more time preparing for interviews and networking. And that's what it's all about - making the job search process as smooth and stress-free as possible.

It's not currently finished, but you can check it out here.