Back to Portfolio

MatchPoint

AI job matcher that ingests 5,867 live roles from 70 Greenhouse boards, retrieves candidates with a precomputed embedding matrix, then scores fit with structured LLM output grounded in job facts.

React 19FastAPIOpenAITursoSupabaseVercel
MatchPoint
Live jobs
5,867
Greenhouse boards
70
Fit dimensions
8
Embedding dim
1536
Vector search
<10ms
Ingest cadence
Daily
As of 2026-07-02

Ask the Data

This assistant answers from MatchPoint documentation on this site: ingestion cadence, the two-stage matcher, split-database design, and resume pipeline.

MatchPoint Chat

Documentation-backed answers on ingestion, matching, and architecture.

Ask about the two-stage matcher, fit dimensions, resume pipeline, or split-database design. I answer from project docs.

Key Performance Indicators

Live product

Upload a resume, get ranked matches with grounded highlights, and explore fit signals across eight weighted dimensions. Anonymous visitors see a 3-match preview before signup.

Try MatchPoint

Split-database design

Jobs live in Turso (libSQL) for fast vector retrieval at scale. User state — profiles, matches, saved jobs, resume storage — lives in MatchPoint's own Supabase project with RLS. The FK between job matches and the Turso corpus was dropped intentionally; orphaned matches hydrate from Turso at read time.

Turso jobs corpus

Up to 5,867 live jobs from 70 Greenhouse boards. HTML stripped, embedded with OpenAI text-embedding-3-small (1536-dim). Jobs unseen for 7 days are purged.

Supabase user state

Auth, profiles, job_matches, resume storage bucket, and pgvector resume embeddings on profiles.resume_embedding.

MatchPoint system architecture: Greenhouse ingestion, Turso jobs corpus, FastAPI matching, Supabase user state, React SPA

Two-stage matching

1. Vector retrieval

Resume embedding queries a precomputed L2-normalized NumPy matrix (~33 MB) published to a data-cache git branch for warm sub-10ms search on Vercel serverless. Top 10 candidates for signed-in users; top 3 for anonymous visitors.

2. LLM scoring

gpt-5.4-nano structured output scores each candidate across eight fit dimensions, producing a weighted match_score, exactly three grounded highlights with citation quotes, and optional warnings.

Fit dimensionWeight
Skills overlap25%
Experience fit18%
Role alignment17%
Seniority match10%
Location10%
Compensation7.5%
Preferences7.5%
Interview likelihood5%

Resume pipeline

Upload → extract → embed

PDF upload → pypdf text extraction → embedding stored on profiles.resume_embedding.

Match persistence

Matches persisted via a replace_job_matches RPC. Extras: resume skill suggestions and an LLM bullet coach on gpt-4o-mini.

MatchPoint resume upload dropzone and preferences

Daily ingestion

GitHub Actions runs daily at 10:00 UTC: scrape up to 100 jobs per board across 70 Greenhouse companies (Stripe, Airbnb, Anthropic, Databricks, GitLab, …), embed new/changed rows, upsert to Turso, purge stale jobs, and force-push the embedding matrix to the data-cache branch.

.github/workflows/daily-pipeline.yml
schedule:
  - cron: "0 10 * * *"  # 10:00 UTC daily

steps:
  - scrape 70 Greenhouse boards (≤100 jobs each)
  - strip HTML, embed with text-embedding-3-small
  - upsert to Turso jobs table
  - purge jobs unseen for 7 days
  - publish L2-normalized embedding matrix → data-cache branch

Grounded output

Every highlight cites a verbatim quote from the job posting. The scorer receives structured job facts (title, requirements, location, comp when available) and must not invent qualifications. Warnings surface mismatches (seniority gap, location conflict, missing must-have skills).

MatchPoint match card with fit signals, highlights, and warnings