Skip to content

Commit

Permalink
feat: added a candidates api that matches resumes to jobs (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasdavis authored Jul 18, 2024
1 parent 5059f04 commit 6a1fe09
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
10 changes: 10 additions & 0 deletions apps/registry/app/[username]/jobs/JobList.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
CheckCircle,
Star,
} from 'lucide-react';
import Link from 'next/link';

const JobDescription = ({ job, makeCoverletter }) => {
const [expanded, setExpanded] = useState(false);
Expand Down Expand Up @@ -155,6 +156,15 @@ const JobDescription = ({ job, makeCoverletter }) => {
>
View Original Job
</a>

<Link
href={`/jobs/${job.raw.uuid}`}
target="_blank"
rel="noopener noreferrer"
className="bg-gray-200 text-gray-700 py-2 px-4 rounded hover:bg-gray-300 transition-colors duration-200"
>
View Job Candiates
</Link>
</div>
</div>
)}
Expand Down
5 changes: 5 additions & 0 deletions apps/registry/app/jobs/[uuid]/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use client';

export default function Home({ children }) {
return <>{children}</>;
}
7 changes: 7 additions & 0 deletions apps/registry/app/jobs/[uuid]/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

const JobList = () => {
return <div className="flex flex-col gap-5">List of jobs</div>;
};

export default JobList;
27 changes: 27 additions & 0 deletions apps/registry/pages/api/candidates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const { createClient } = require('@supabase/supabase-js');

const supabaseUrl = 'https://itxuhvvwryeuzuyihpkp.supabase.co';
const supabaseKey = process.env.SUPABASE_KEY;
const supabase = createClient(supabaseUrl, supabaseKey);

if (!process.env.OPENAI_API_KEY) {
throw new Error('Missing env var from OpenAI');
}

// This API route is used to match candidates to a job

export default async function handler(req, res) {
const jobId = 40224903;

const { data } = await supabase.from('jobs').select().eq('uuid', jobId);

const jdEmbedding = data[0].embedding_v5;

const { data: documents } = await supabase.rpc('match_resumes_v5', {
query_embedding: jdEmbedding,
match_threshold: 0.14, // Choose an appropriate threshold for your data
match_count: 40, // Choose the number of matches
});

return res.status(200).send(documents);
}
74 changes: 74 additions & 0 deletions apps/registry/scripts/jobs/jobs-embeddings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require('dotenv').config({ path: __dirname + '/./../../.env' });

const { createClient } = require('@supabase/supabase-js');
const OpenAI = require('openai');

const supabaseUrl = 'https://itxuhvvwryeuzuyihpkp.supabase.co';
const supabaseKey = process.env.SUPABASE_KEY;
const supabase = createClient(supabaseUrl, supabaseKey);
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});

async function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

async function main() {
const { data, error } = await supabase
.from('resumes')
.select('id::text, username, resume, embedding')
.is('embedding', null);
// .limit(300);
console.log({ data, error });

for (let i = 0; i < data.length; i++) {
const resume = data[i];
if (!resume.embedding) {
console.log('Create embedding for');
console.log('Username:', resume.username);
console.log('ID:', resume.id);

const completion1 = await openai.embeddings.create({
model: 'text-embedding-3-large',
input: resume.resume.substr(0, 8192),
});
console.log('Embedding done');

const desiredLength = 3072;

let embedding = completion1.data[0].embedding;

if (embedding.length < desiredLength) {
embedding = embedding.concat(
Array(desiredLength - embedding.length).fill(0)
);
}

console.log('Embedding to be saved:', embedding);

try {
console.log('Saving embedding for ID:', resume.id);

const updateResponse = await supabase
.from('resumes')
.update({ embedding })
.eq('id', resume.id);

console.log('Update response:', updateResponse);

if (updateResponse.error) {
console.log('Error updating embedding:', updateResponse.error);
} else {
console.log('Embedding updated successfully:', updateResponse.data);
}

await sleep(2000); // Sleep for 2 seconds
} catch (e) {
console.error(e);
}
}
}
}

main();

0 comments on commit 6a1fe09

Please sign in to comment.