Introduction
Whire is a Singaporean Tech Startup which helps companies hire great people faster through its platform and a top tier community of hiring ambassadors, saving companies hours on pre-screening and outreach efforts as well as thousands of dollars on job ads and agency fees without compromising candidate quality.
Motivation
Benjamin Marsili (founder of Whire) hired me to help him build a recruiting network platform for companies to;
- Broadcast jobs from LinkedIn (and other sources)
- Directly interview candidates who are referred members of the Whire network
- Make hiring decisions and then pay for successfully hired candidates
For more information on Whire visit whire.net.
To try the Whire platform yourself, visit app.whire.net.
My Engagement with Whire
Initial Phase
Before engaging with me Whire already had 1 fulltime junior developer and a React (Typescript) UI component library consisting of simple UI components and some full screen layouts. The component library was also complete wth Story Book (UI Component Development Library). Up to this point, the component library was primarily used to show potential investors what they were trying to build.
Whire had also started work on a Next.JS web-app using their component library. The app to this point was also for demo purposes only; login/data/integrations were all mocked.
Phase 1 (2 weeks)
Objective
For phase 1, Whire’s initial aims were;
- Deploy existing web-app a cost effective and scalable way
Architecture
I strongly recommended to deploy to AWS for the following reasons:
- AWS can do a lot of undifferentiated heavy lifting (e.g: Fargate can be used to deploy and scale the web-app without having to do a lot of configuration)
- AWS allows a pay as you use payment model
Note: Vercel was also considered, however as their was a future plan to integrate other Amazon services it seemed better to keep everything under one roof. Also I had read that Vercel costs are expensive for sites once traffic increases
I proposed the following AWS architecture to Ben
- Web-app is containerized and pushed to ECR
- Web-app deployed managed and auto-scaled using Fargate
- AWS Code pipeline to automatically build/test and deploy code
Execution
In order to execute this plan I completed the following steps;
- Restructured the frontend into a mono-repo so that component library and web-app are built and tested independently (using shared extended configurations)
- Added (Jest) tests for web-app and component library
- Wrote a docker compose file to build web-app and component library into an image that could be pushed to Amazon ECR
- Created a CDK stack to deploy the planned architecture to staging and production environments
- Created a CDK pipeline to build, test and deploy the web-app and component library
Result
Whire web-app was successfully deployed on AWS
Phase 2 (4 weeks)
Objective
After successfully deploying their web-app to AWS. For phase 2, Whire’s aims were
- Start working on a backend API to store and serve data about jobs and candidates in the whire network
- Create an authentication solution so users could login to Whire
Architecture
For building Whire’s api I proposed creating a NodeJS GraphQL api in Typescript and deploying it to Lambda. This has the following advantages.
- Building everything in Typescript keeps development simple as skills/knowledge/tools are reusable
- Deploying to Lambda is very cheap and scalable
Note: AppSync was also considered for the GraphQL api. However I find it very awkward to extend beyond out of the box functionality (thought maybe now it has improved).
For storing Data I suggested using a serverless MongoDB. A schemaless DB was preferable as data such as job posts coming from different sources can be unstructured.
Note: The reason for choosing MongoDB and not Amazon’s own schemaless DB DynamoDB is that mongo has fantastic Typescript support. Namely, typegoose, an object document model written and managed by MongoDB’s creators.
For authenticating users I suggested AWS Cognito for user login along with AWS Api Gateway to authenticate user api requests.
I proposed the following AWS architecture to Ben
- GraphQL api built with NodeJS/Apollo Server
- Serverless MongoDB
- AWS Code pipeline to automatically build/test and deploy code
Execution
In order to execute this plan I completed the following steps;
- Created a GraphQL api in NodeJS using Apollo Server and TypeGraphQL
- Configured Api Gateway (using CDK) to allow api requests from authenticated cognito users (use access) and allowed IAM roles (role access)
- Created a CDK stack to deploy the planned architecture to staging and production environments
- Created a CDK pipeline to build, test and deploy the api
- Coached Whire’s junior developer so he could create his own GraphQL queries and mutations
Result
Whire api was successfully built and deployed on AWS
Phase 3 (8 weeks)
Objective
One of the key features for Whire is referring candidates. For referrals, both the referrer and referee should use LinkedIn to login and share their information.
For phase 3, Whire’s aims were;
- Users should be able to login to Whire using their LinkedIn credentials
- LinkedIn authenticated users should have api access
- On logging in for the first time a user should be created in Whire’s database
- Users LinkedIn profile information (name, nationality, skills etc…) should be pulled into Whire
Architecture
I proposed the following process for user registration, profile setup and sign in.
- Use LinkedIn as federated auth provider with Cognito
- A Lambda runs on user confirmation (after email validation) to fetch the users profile information. This is non blocking, incase the data can not be retrieved we do not block the user from being onboarded to Whire
Execution
After starting to execute this plan we ran into a problem. Cognito does not support LinkedIn login out of the box. Cognito only supports some federated providers (Facebook/Google) as well as OpenId/SAML identity providers (LinkedIn only has an Auth2 provider).
I then proposed 3 options
Option | Advantages | Disadvantages |
---|---|---|
Use a third party solution like Auth0/octa | Simple to set up LinkedIn login | Expensive (Auth0 $240/mo - octa $3/MAU) Outside the AWS ecosystem (bad for developers and CI/CD) API Access would require a custom lambda authorizer in AWS gateway Sign Up events would require custom setup outside of AWS |
Mixed approach. Use cognito with Auth0 OpenID provider (use Auth0 as a middleman) | Simplest solution | Bad user experience. We don’t control the Auth0 login flow Most expensive solution. As we pay for our LinkedIn users twice No one source of truth as users managed in Auth0 and cognito |
Write my own OpenId provider. | Cheap Everything kept in AWS |
Complex |
I chose to write my own OpenId provider, which adapts LinkedIn Auth2 provider to OpenId. Luckily I was able to find an existing project for the Github Auth2 provider and adapt the code to my needs (LinkedIn apis/scopes). I hosted the custom provider on AWS lambda and added the deployment to CDK along with the additional Cogntio OpenId configuration. The code more my standalone OpenId Auth2 wrapper can be found here.
Result
In the video below you can see Whire’s sign up process for referrers and referees. Users are able to sign up to Whire using their LinkedIn credentials and profile data (e.g. full name and profile photo) is pulled into Whire.
Phase 4 (4 weeks)
For phase 4 I added ATS integration using merge.dev which allows companies to integrate Whire with their existing recruiting flows and tools. In this phase Whire was successfully integrated with Recruitee and Greenhouse.
Impact
Whire Network has sofar grown to; 30 clients, 200 referrers and 100 posted jobs.
Whether you are starting a new project or restructuring an old stack, his work ethics, drive and sound engineering mind will make the difference between what could have been an expensive failure and a software stack providing a great user as well as developer experience. Working with Simon is investing in your company’s sustainable future.
— Benjamin Marsili
In June 2021, I took on a role as CTO of Whire.