📋 cord CV

Generate a cord CV from your profile.

Project: 🗒️ cord CV Type: 🚀 Feature User: 💁🏻‍♀️ People

Key changes

Notion image

People looking for work on cord can download a CV automatically generated from their profile.

Why?

One of the most challenging parts of finding work is having to create (or update) your CV. Many people put off looking for work because of how painful this process can be.

What?

All people using cord to look for work will have access to a cord CV.

The cord CV is generated from the candidate profile. It is generated as soon as the candidate profile goes live, and is updated every time any change to the profile is made.

The CV can be downloaded via the CV icon dropdown on the candidate profile.
The CV can be downloaded via the CV icon dropdown on the candidate profile.

How?

Andrés, FE Lead
Andrés, FE Lead

Guest writer, FE Lead and AI magician Andrés is now going to step in and explain how this feature was built.


There’s a reason there exists a meme within developer circles about throwing out all the code and “refactoring” it. Often the hardest part about programming is that what’s already been built didn’t (and couldn’t) take into account this brand-new idea for a feature that we’ve just had.

That is what has been the most challenging part of building the CV compiler. At first glance, the task might seem fairly trivial. Just print out the profile to a pdf, right?

😑
No. Not right.

Turns out that there is a whole host of issues that present themselves when you start going down the rabbit hole of turning a webpage into a presentable pdf. The four biggest ones, in this case, are:

  1. We want clickable links and a consistent look
  1. Web components typically don't have to accept or deny content based on if they’re crossing a page boundary
  1. Users’ profiles vary wildly
  1. The way we’ve stored the relevant data makes it hard to manipulate

The big picture

One way to solve the first issue is actually to simply render the CV in a browser and print it to a pdf. We decided we would do this by setting up a serverless endpoint that essentially spins up a browser (via Puppeteer), authenticates, and accesses a page we’ve set up to render the CV correctly, and then saves the results to a pdf on our servers.

There were some challenges getting this to work perfectly within the limits of what a serverless function can do, but in the end, it came together. On the backend, we also have some logic that decides when we need to generate a new CV and when a previously rendered one is still fresh. So we only spin up the serverless function when we need to.

Rendering: What page am I on?

When designing a webpage you absolutely do have to think about screen size, but a lot of the details are taken care of for you if you just give the components the right instructions:

  • Chuck a bunch of items into a container
  • Tell the container how to order them, space them…
  • Voilá!

If you look at the design for the cord CV, however, you’ll notice that each page starts with its own “container”. On top of that, we don’t know how many chunks of text (experience, education, etc) we need to place, or even how long each one will be. As a bonus, the chunks of text have already been formatted by the users and they are likely to want to keep that formatting.

The only way we could come up with, without having to redo completely how we handle the data, was to iteratively load the page, chunk by chunk, rendering the full page each time and essentially asking the components:

How tall are you? Do we need another page? Are you okayyy?!!

This actually sounds like a reasonable solution, but implementing it became quite tricky, again, because of how we store the data.

It’s loops all the way down

Without going into too much detail, a common pattern when developing an app like this is that you iterate over things, and then within those things, you iterate over their content, and within the content you iterate over the details… and then, finally at the bottom, you take action.

The issue is that at each level you only have access to so much knowledge and you only have so much responsibility.

🤏🏽
It’s typically not the responsibility of a paragraph to decide in which container it lands

Here, however, you could argue that is the case. At least, it’s at the level of our smaller units of data that we send a message to the top level saying:

“Hey! I’m the latest chunk to be rendered and here is some information about my position and size”.

Now the top-level compiler knows what’s going on and can plan the next render appropriately. If this bit of data crossed into a new page, then we create a new page and during the next iteration we tell the current page that when it reaches that point, it can stop.

 

And that is currently where we’re at. We can now automatically generate a very nice-looking CV for anyone that has a profile with us here at cord.


What’s next?

After conducting user research to understand our users’ pain points when creating a CV, we will be introducing a CV enhancer which will allow all cord users to improve their profile (and thereby their CV) using AI. Watch this space! 👀

 
Did this answer your question?
😞
😐
🤩