Three applications around one idea: read a candidate's CV, score live openings against it, and run the search as an ongoing campaign rather than a query typed each morning.

Where it started
Job search is repetitive work that candidates redo every day: the same searches, the same tailoring, no memory between sessions. Keyword matching filters out strong candidates whose CV uses different vocabulary from the posting. We wanted the platform to hold the state a candidate otherwise holds in their head, and to judge a role on meaning rather than wording.
CV parsing
An uploaded document becomes a structured profile — skills, seniority, domain and tools — rather than a block of text to keyword-search.
Guided onboarding
The candidate reviews and corrects whatever the parser inferred, so the profile the matching runs against is one they agree with.
Fit scoring
Each opening is scored against the structured profile, so relevance survives a job description and a CV using different words for the same thing.
Saved campaigns
A search runs as an ongoing campaign that keeps surfacing matches, instead of a query retyped every morning.
Assistant
A chat assistant answers against the candidate's own profile and application history rather than generic advice.
Operations console
A separate application for administration, so routine changes do not need an engineer.
- Three applications against one API: the candidate app, an operations console and a Python service.
- FastAPI backend with SQLAlchemy models and Alembic migrations, so schema changes are versioned and reversible.
- Token-based auth with per-user data isolation enforced server-side, never in the client.
- Containerised with Docker so local, CI and deployed environments run the same image.
- React with Vite and Tailwind on the front end; shared component primitives across both applications.
- 01
Built CV management that parses an uploaded document into a structured profile — skills, seniority, domain — which becomes the basis for every later match.
- 02
Implemented job scanning and scoring, so each opening is rated against that profile with a reason attached rather than returned as an unranked list.
- 03
Modelled saved searches as ongoing campaigns that keep running and keep surfacing matches, instead of a query repeated by hand.
- 04
Added an AI assistant that works against the candidate's own profile and application history, so its answers are grounded in their situation.
- 05
Built a separate operations console for administration, and a points wallet covering the platform's credit mechanics.
- 06
Backed all of it with a Python API using versioned database migrations and containerised deploys.
- React
- TypeScript
- Vite
- Tailwind
- FastAPI
- PostgreSQL
- Alembic
- Docker
Where it landed
A candidate uploads one document and the platform carries the search: scoring roles, tracking applications and holding context between sessions. The operations console runs administration without engineering involvement.
A short conversation with an engineer, not a sales qualification call. If we're the wrong people for it, we'll say so and point you somewhere better.


