Full-stack resume analysis app with authentication, PDF upload, Gemini-powered evaluation, and a live dashboard fed by backend API aggregation.
- User signup and login with JWT token generation.
- Secure password hashing using
bcryptwith long-password-safe preprocessing. - Resume upload endpoint (PDF only).
- AI resume analysis via Google Gemini.
- Smart Gemini model fallback (auto-selects a supported model if configured model is unavailable).
- Dashboard metrics sourced from real backend data (
/dashboard-data), not hardcoded frontend values.
- Backend: FastAPI, PyMongo, PyPDF2, Google Generative AI SDK, bcrypt, python-dotenv
- Frontend: React, Vite, Axios, Recharts
- Database: MongoDB (Atlas)
AI-resume-analyzer/
backend/
main.py
auth.py
database.py
gemini_ai.py
routes/
auth_routes.py
resume_routes.py
utils/
pdf_parser.py
frontend/
src/
App.jsx
api.js
pages/
Login.jsx
Signup.jsx
Dashboard.jsx
UploadResume.jsx
- Python 3.10+
- Node.js 18+
- npm 9+
- MongoDB Atlas connection string
- Gemini API key
Run in a terminal from project root:
cd backend
python -m venv .venv
.\.venv\Scripts\activate
pip install fastapi "uvicorn[standard]" pymongo python-dotenv PyPDF2 google-generativeai bcrypt "python-jose[cryptography]" python-multipartCreate or update backend/.env:
GEMINI_API_KEY=your_gemini_api_key
GEMINI_MODEL=gemini-2.5-flash
JWT_SECRET_KEY=replace-with-a-strong-secretImportant:
- MongoDB URL is currently defined in
backend/database.py(MONGO_URL). - Replace it with your own connection string before running.
- For production, move
MONGO_URLto environment variables.
Start backend server:
uvicorn main:app --reloadBackend URLs:
- API base:
http://127.0.0.1:8000 - Swagger docs:
http://127.0.0.1:8000/docs
Run in a second terminal from project root:
cd frontend
npm install
npm run devFrontend URL:
- Vite dev server:
http://localhost:5173(or next available port like5174)
The backend CORS config allows localhost loopback ports, so alternate Vite ports still work.
Returns backend health status.
Request body:
{
"email": "user@example.com",
"password": "StrongPassword123!"
}Request body:
{
"email": "user@example.com",
"password": "StrongPassword123!"
}Response:
{
"token": "<jwt_token>"
}multipart/form-data- field name:
file - accepts:
.pdfonly
Response shape:
{
"analysis": {
"score": 75,
"skills": ["Python", "FastAPI"],
"missing_skills": ["Docker"],
"suggestions": ["Add quantified project outcomes"],
"model_used": "gemini-2.5-flash"
}
}Aggregates real data from stored resume analyses and returns:
overall_scoreats_pass_rateversions_uploadedissues_foundlatest_analysis- chart arrays:
radar_data,keyword_data,trend_data,section_data,activity_data action_items
- Every upload stores
{ filename, analysis, created_at }in MongoDB. GET /dashboard-datacalculates dashboard metrics from recent history.Dashboard.jsxfetches/dashboard-dataon load.- After a successful upload,
UploadResume.jsxtriggers a dashboard refresh so charts and counters update immediately.
-
AI analysis is unavailable:- Check
GEMINI_API_KEYinbackend/.env. - Restart backend after editing
.env.
- Check
-
Gemini model error (404/not found):
- The app auto-falls back to supported models.
- If needed, set
GEMINI_MODEL=gemini-2.5-flash.
-
Only PDF files are supported:- Upload a
.pdffile only.
- Upload a
-
Frontend cannot reach backend:
- Ensure backend is running on port
8000. - Confirm frontend uses
VITE_API_BASE_URLor defaults tohttp://localhost:8000.
- Ensure backend is running on port
-
Exit code
1afteruvicorn --reloadornpm run dev:- If you stopped with Ctrl+C or timeout, this can be expected.
- Never commit real API keys or database credentials.
- Rotate keys immediately if they are exposed.
- Use environment variables for all secrets in production.