Recruitify - Built using AWS Amplify, DynamoDB, Lambda, Bedrock
What I Built
Recruitify is a platform designed to bridge the gap between job seekers and employers. It provides a seamless experience for both parties to find the perfect match for their needs.
Features
Employer
Create Job Postings: Employers can create detailed job listings specifying required skills, experience, location, and more.
Manage Applications: Employers can efficiently manage and validate applications received for their job postings.
Job Seeker
Browse Jobs: Job seekers can search and filter job listings based on their preferences.
Apply for Jobs: Easily apply for various job opportunities.
Receive Notifications: Get notified about new job listings that match your skills
Demo and Code
Recruitify is available here and the code is available on GitHub.
Screenshots
Browse Jobs Page
Edit Profile
Create/Edit Job Posting
Generate Job Description
Job Details Page (Job Creator)
Job Details Page (Job Seeker)
Job Applications Page (Job Seeker)
Job Applications Page (Job Creator)
New Job Notification
Integrations
Tech Stack
Backend: AWS Amplify
Frontend: Angular 17, Angular Material, Tailwind CSS
AWS Technologies: Data (DynamoDB), Authentication (Cognito), Serverless Functions (Lambda), File Storage (S3), AI (Bedrock)
Hosting: AWS Amplify
Connected Components and Feature Full
This project uses Amplify-connected components for Angular - Authenticator for users to sign up and log in.
This project also integrates all four integrations - Data, Authentication, Serverless Functions, File Storage
AWS Amplify
Architecture
Authentication
Utilizes AWS Amplify Authentication for user sign-up and login via email which uses AWS Cognito services.
Configured in amplify/auth/resource.ts
export const auth = defineAuth({
loginWith: {
email: true,
}
});
Implemented with the Amplify UI component <amplify-authenticator>
for Angular.
Data
Utilizes AWS Amplify Data to store information about Users, Companies, and Jobs which uses AWS DynamoDB. Database Design is shown above.
Configured in amplify/data/resource.ts
Database Design
Storage
AWS Amplify S3 Storage is used for storing company logos and job seeker resumes.
Configured in amplify/storage/resource.ts
export const storage = defineStorage({
name: 'recruitifyFiles',
access: (allow) => ({
'companyLogos/*': [
allow.authenticated.to(['read', 'write']),
allow.guest.to(['read', 'write'])
],
'resumes/*': [
allow.authenticated.to(['read', 'write']),
allow.guest.to(['read', 'write'])
],
})
});
The files were uploaded using uploadData
like below
const result = await uploadData({
data: this.previewUrl,
path: `companyLogos/${this.authService?.userProfile?.id}`,
}).result;
And the files were downloaded when necessary using downloadData
like below
downloadData({ path: profile.data[0].resume })
Functions
AWS Amplify Lambda Functions are used to send New Job Notifications to job seekers matching their skill set and Generate Job Descriptions to generate job descriptions for job creators.
Used AWS Amplify AppSync GraphQL API inside the function to find relevant job seekers and create new job notifications.
Used AWS Bedrock with Mistral AI Model inside the function to generate job descriptions.
Configured in amplify/functions/new-job/handler.ts
Triggered when a new job is created by an employer using a mutation in data like the below:
sendJobNotification: a.mutation()
.arguments({ jobId: a.string(), companyId: a.string() })
.returns(a.string())
.authorization(allow => [allow.publicApiKey()])
.handler(a.handler.function(newJob))
client.mutations.sendJobNotification({
jobId: job.data?.id,
companyId: job.data?.companyId
}).then((job) => {
console.log(job)
})
Triggered generate job description like the below:
generateJobDescription: a.mutation()
.arguments({ title: a.string(), minExperience: a.float(), skills: a.string(), domain: a.string() })
.returns(a.string())
.authorization(allow => [allow.publicApiKey()])
.handler(a.handler.function(generateJobDescription))
client.mutations.generateJobDescription({
title: this.createJobForm.value.title,
skills: this.skills.join(','),
domain: this.createJobForm.value.domain,
minExperience: this.createJobForm.value.minExperience,
}).then((response) => {
console.log(response);
if (response?.data) {
this.createJobForm.patchValue({
description: response.data
})
}
}).finally(() => {
this.loadingService.hide();
})
Used Mistral 7B model with prompt like this:
const text = `
Job Title: ${title}
Job Domain: ${domain}
Job Min Experience: ${minExperience} years
Job Required Skills: ${skills}
`
const prompt = `Your task is to generate a job description for below-given job details.
Job Details: ${text}
Job Description: `
And invoke the model like below:
const input = {
modelId: "mistral.mistral-7b-instruct-v0:2",
contentType: "application/json",
accept: "application/json",
body: JSON.stringify({
prompt: `<s>[INST] ${prompt} [/INST]`,
max_tokens: 2000,
temperature: 0.5,
}),
} as InvokeModelCommandInput;
Hosting
Utilised AWS Hosting for seamless deployment of the application.
Future Scope
Application Notifications: Notifications for Job Application status changes for both job seekers and employers
Realtime chat messaging: Realtime chat messaging between job seeker and employer
Conclusion
Recruitify leverages the power of AWS Amplify to deliver a robust, full-stack application. There is a lot to learn while working with AWS and AWS Amplify toolkit along with Angular on this project.
Subscribe to my newsletter
Read articles from Amit Wani directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Amit Wani
Amit Wani
๐ช๐๐ฅ๐ฅ๐๐ข๐ฅ! Full Stack Developer | SDE Reliance Jio ๐ฅ๏ธ Tech Enthusiastic ๐ป Man Utd ๐ด Sachin & Dravid fan! โพ Photography ๐ธ Get Hands Dirty on Keyboard!