AI-Powered Recruiter Marketplace
Four platforms sharing one set of permissions
Full-stack engineer · Octogle TechnologiesClient codebase, not public
The problem
Employers with vacancies and independent recruiters with candidate networks had no shared place to transact. The product opens that market: employers post vacancies, recruiters bid on them, refer candidates, and earn commission when a referral converts.
That commission is what makes the data model hard. A candidate record is visible to different parties for different reasons, and the referral chain that determines who gets paid has to hold even as the candidate moves through the pipeline.
My part
I implemented the permission hierarchies, the job-matching workflows and the candidate pipeline system across Employer, Recruiter, Candidate and Admin platforms.
The parts I was responsible for: permission hierarchies, job-matching workflows, candidate pipeline, REST API, frontend.
Built with
- React
- Vite
- TypeScript
- Node.js
- PostgreSQL
- JWT
The surfaces
Money changes what a permission means. A recruiter can see a candidate they referred, an employer can see candidates referred to their vacancy, and neither can see the other's book of business. All of it sits on shared records, with commission attached to who introduced whom.
Employer
Post vacancies, review referred candidates, accept bids.
Recruiter
Bid on vacancies, refer candidates, track commission.
Candidate
Their own profile and their own applications, and nothing else.
Admin
Oversight of the exchange, including disputes over attribution.
Decisions
A few decisions worth explaining.
Permissions derived from the referral relationship, not from a role alone
- Problem
- Role alone cannot answer whether a recruiter may see a candidate. Two recruiters have identical roles and must see completely different candidates.
- Decision
- Scope access by the relationship between the actor and the record, meaning who referred whom against which vacancy, and check it at the API boundary.
- Trade-off
- Every read carries a relationship check rather than a simple role comparison, which is more expensive and more code. It is also the only version that is correct when commission is on the line.
- Result
- A recruiter's book of business stays theirs, and attribution survives the candidate moving through the pipeline.
A pipeline with explicit states rather than a status string
- Problem
- A candidate moves through referral, review, interview and outcome, and several parties act on the same record. A free-form status field makes disputed transitions unanswerable.
- Decision
- Model the pipeline as explicit states with defined transitions, so who moved a candidate and when is a recorded fact.
- Trade-off
- Less flexible than a string. That is the point.
- Result
- Attribution disputes become a question of reading history rather than of arguing.
Outcome
- Four platforms running against one backend and one permission model.
- Commission attribution that holds across the full candidate pipeline.