A full-stack, RAG-powered career platform that helps job seekers find relevant openings, understand how their skills stack up, and check whether their resume will survive an ATS (Applicant Tracking System) scan β all through a natural-language chat interface.
π Live demo: https://advanced-job-search.vercel.app (Note: backend runs on a free-tier host and may take ~30s to wake up on first request)
- Chat-based job search β ask "What jobs match my Python and ML skills?" and get a grounded answer plus matching job cards, generated via a RAG pipeline over live job postings.
- Resume parsing β upload a PDF resume; the app extracts 200+ technical skills across 7 categories, estimates years of experience, and pulls contact info.
- ATS scoring β get a 0β100 score across five dimensions (formatting, section completeness, action verbs, quantified achievements, keyword match against a job description) with specific, actionable suggestions.
- Live job board β semantic search over indexed postings, refreshed on demand from a free job-board API.
- Analytics dashboard β in-demand skills, job source breakdown, and search activity over time, computed from real Postgres data.
ββββββββββββββββββββββββββββββββ
β Next.js 14 + TypeScript β Vercel
β Tailwind CSS v4 β
βββββββββββββββββ¬βββββββββββββββββ
β REST (JSON)
βββββββββββββββββΌβββββββββββββββββ
β FastAPI backend β Render (Docker)
β ββ /api/chat (RAG) β
β ββ /api/jobs (search/scrape)β
β ββ /api/resume (parsing) β
β ββ /api/ats (scoring) β
β ββ /api/analytics β
ββββββββ¬βββββββββββββββ¬βββββββββββ
β β
ββββββββΌβββββββ βββββββΌβββββββββββ
β Qdrant β β PostgreSQL β
β (vectors) β β (Neon) β
ββββββββββββββββ ββββββββββββββββββ
β
ββββββββΌβββββββββββ
β Groq API β
β (Llama 3.3-70B) β
ββββββββββββββββββββ
Frontend
- Next.js 14 (App Router) + TypeScript
- Tailwind CSS v4
- Recharts (analytics charts)
- lucide-react (icons)
Backend
- FastAPI + Pydantic
- SQLAlchemy ORM
- Groq API (Llama 3.3-70B) for RAG responses
- Qdrant for vector search
- FastEmbed (
BAAI/bge-small-en-v1.5) for embeddings β chosen for its small footprint to fit free-tier memory limits - pdfplumber for resume PDF parsing
- BeautifulSoup for job description cleanup
Data & infrastructure
- PostgreSQL via Neon (serverless Postgres)
- Qdrant Cloud (vector database)
- Docker (backend containerization)
- Render (backend hosting)
- Vercel (frontend hosting)
- Arbeitnow public API (job postings source)
.
βββ backend/
β βββ app/
β β βββ main.py # FastAPI app, CORS, startup hooks
β β βββ config.py # env-based settings
β β βββ db/
β β β βββ database.py # SQLAlchemy engine/session
β β β βββ models.py # Job, Resume, ATSScore, SearchLog
β β βββ routers/
β β β βββ jobs.py # scrape, search, list, stats
β β β βββ resume.py # upload, parse
β β β βββ ats.py # ATS scoring
β β β βββ chat.py # RAG chat endpoint
β β β βββ analytics.py # dashboard aggregates
β β βββ services/
β β β βββ scraper.py # Arbeitnow job scraper
β β β βββ embedder.py # resume parsing + skill ontology
β β β βββ ats_scorer.py # ATS scoring logic
β β β βββ reranker.py # cross-encoder reranking (optional)
β β β βββ rag.py # RAG orchestration (Groq + Qdrant)
β β βββ vectorstore/
β β βββ qdrant_client.py # embeddings + vector search
β βββ requirements.txt
β βββ Dockerfile
β
βββ frontend/
βββ src/
β βββ app/
β β βββ page.tsx # chat page
β β βββ jobs/page.tsx # job board
β β βββ resume/page.tsx # resume upload + ATS
β β βββ analytics/page.tsx
β β βββ globals.css
β βββ components/
β β βββ Navbar.tsx
β β βββ ChatWindow.tsx
β β βββ JobCard.tsx
β β βββ ResumeUpload.tsx
β β βββ ATSScoreCard.tsx
β β βββ AnalyticsDashboard.tsx
β βββ lib/api.ts # typed API client
βββ tailwind.config.js
βββ postcss.config.mjs
| Endpoint | Method | Description |
|---|---|---|
/api/chat |
POST | RAG chat β semantic search + LLM-generated answer |
/api/jobs/scrape |
POST | Scrape job postings and index into Qdrant + Postgres |
/api/jobs/search |
POST | Semantic/hybrid search over indexed jobs |
/api/jobs/list |
GET | Browse indexed jobs |
/api/jobs/stats |
GET | Index + database stats |
/api/resume/upload |
POST | Upload and parse a resume PDF |
/api/resume/{id} |
GET | Retrieve a parsed resume profile |
/api/ats/score |
POST | Run ATS scoring against an optional job description |
/api/analytics |
GET | Aggregate stats for the dashboard |
Full interactive API docs available at <backend-url>/docs (Swagger UI).
- Python 3.11+
- Node.js 18+
- Free accounts: Groq, Qdrant Cloud, Neon
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
# create .env with:
# DATABASE_URL=postgresql://...
# QDRANT_URL=https://...
# QDRANT_API_KEY=...
# GROQ_API_KEY=gsk_...
# FRONTEND_URL=http://localhost:3000
uvicorn app.main:app --reloadBackend runs at http://localhost:8000 β Swagger docs at /docs.
cd frontend
npm install
# create .env.local with:
# NEXT_PUBLIC_API_URL=http://localhost:8000
npm run devFrontend runs at http://localhost:3000.
With the backend running, call POST /api/jobs/scrape via /docs with a body like:
{
"queries": ["python", "developer", "engineer"],
"location": "",
"max_per_query": 15
}- Frontend: deployed on Vercel, root directory
frontend, env varNEXT_PUBLIC_API_URLpointing at the backend. - Backend: deployed on Render as a Docker web service, root directory
backend. Environment variables:DATABASE_URL,QDRANT_URL,QDRANT_API_KEY,GROQ_API_KEY,FRONTEND_URL. - Vector DB: Qdrant Cloud free-tier cluster.
- Database: Neon serverless Postgres free tier.
- Render's free tier (512MB RAM) cannot run
sentence-transformers/torch β embeddings use FastEmbed with an ONNX-based model instead. - Hybrid (keyword + vector) search and cross-encoder reranking are implemented but disabled by default in production to stay within memory limits; pure semantic search is used instead.
- The backend spins down after ~15 minutes of inactivity on Render's free tier β first request after idle may take 30-60 seconds.
- FastEmbed over sentence-transformers: drops the torch dependency entirely, fitting comfortably within 512MB RAM while keeping a 384-dimension embedding model (
BAAI/bge-small-en-v1.5). - Skill ontology-based parsing: rather than relying solely on an LLM for resume parsing, a curated dictionary of 200+ skills across 7 categories (languages, ML/AI, frameworks, data, backend, cloud/DevOps, tools) enables fast, deterministic, and free skill extraction.
- Weighted ATS scoring: the five scoring dimensions are combined with configurable weights, and keyword matching dynamically re-weights when a job description is provided versus when it isn't.
- Decoupled architecture: frontend and backend are independently deployable services communicating over a typed REST API, mirroring real-world microservice patterns.
- Re-enable hybrid search + reranking on a higher-memory tier
- Add authentication and per-user saved searches / resume history
- Scheduled job-index refresh via GitHub Actions
- LinkedIn job source integration
- Cover letter generation from resume + job description
MIT