Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

23 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿง  AI Hiring Job โ€” Resume Intelligence & Hiring Assistant Platform

Production-Grade Full-Stack SaaS for Smarter, Faster Recruitment

Parse resumes in bulk. Score candidates against jobs with transparent, explainable logic. Manage your entire hiring pipeline โ€” in one platform.

Node.js React Express MySQL Docker Kubernetes JWT License

Repo Size Last Commit Issues Stars

Live Demo ยท Report Bug ยท Request Feature


๐Ÿ“– Overview

Recruiting teams routinely receive hundreds of resumes per role and spend hours manually screening, comparing, and shortlisting candidates. AI Hiring Job automates the heavy lifting of that workflow with a rules-based, fully explainable scoring engine โ€” no black-box AI, no unexplainable rankings.

The Business Problem

  • Manual resume screening doesn't scale past a handful of applicants.
  • Recruiters lack a consistent, repeatable way to compare candidates against a role's requirements.
  • Hiring managers need evidence, not just a score, to justify a shortlist decision.
  • Disconnected spreadsheets and email threads make pipeline tracking unreliable.

The Technical Solution

AI Hiring Job centralizes the entire hiring lifecycle โ€” job creation, bulk resume ingestion, structured parsing, weighted candidate-to-job matching, pipeline tracking, and analytics โ€” behind a single authenticated React dashboard backed by a hardened Express + MySQL API.

  • Resume Parsing Engine โ€” extracts skills, experience, and education from PDF/DOCX resumes using pdf-parse and mammoth, normalized against a curated skills taxonomy.
  • Explainable Matching Engine โ€” deterministic, weighted scoring (Required Skills 50% ยท Nice-to-have 20% ยท Experience 20% ยท Education 10%) with a full score breakdown returned per candidate โ€” every score is traceable to its inputs.
  • Duplicate Detection โ€” content-hash based de-duplication prevents the same resume being scored twice for a role.
  • Interview Question Generator โ€” produces role- and skill-tailored behavioral/technical question banks per candidate-job pair.
  • Operational Analytics โ€” dashboard and per-job funnel metrics for data-driven hiring decisions.

Real-World Use Case

A startup HR team posts a "Senior Backend Engineer" role, bulk-uploads 150 resumes received via email, and within seconds gets a ranked shortlist with a transparent breakdown of why each candidate ranked where they did โ€” then moves top candidates through a pipeline (Screening โ†’ Interview โ†’ Offer) directly in the app.

Scalability Considerations

  • Stateless Express API designed for horizontal scaling โ€” see the included Kubernetes manifests with 2-replica Deployments, liveness/readiness probes, and an Ingress with TLS.
  • File uploads persisted to a dedicated ReadWriteMany PVC so any pod replica can serve uploaded resumes.
  • Rate limiting (express-rate-limit) isolates auth endpoints (20 req/15min) from general API traffic (200 req/15min) to absorb brute-force attempts without degrading normal usage.
  • MySQL schema is fully normalized with foreign keys and targeted indexes (idx_applications_job_id, idx_resumes_user_id, etc.) to keep matching queries performant as data grows.

โœจ Key Features

Feature Description
๐Ÿ” JWT + OTP Authentication Email/password registration with OTP email verification, short-lived access tokens + refresh tokens, secure logout/session invalidation
๐Ÿ“„ Bulk Resume Upload Upload up to 20 resumes at once (PDF/DOCX), parsed automatically into structured candidate profiles
๐Ÿงฎ Explainable Matching Engine Transparent, weighted scoring against job requirements with a full breakdown โ€” not a black box
๐Ÿงฌ Duplicate Resume Detection SHA-based content hashing flags duplicate submissions per recruiter account
๐Ÿ“ AI-Style Job Description Generator Auto-drafts a structured job description from title, skills, and experience range
๐Ÿ—‚๏ธ Candidate Pipeline Tracking Move candidates through configurable pipeline stages (screening โ†’ interview โ†’ offer)
๐ŸŽฏ Interview Question Generator Generates behavioral & role-specific technical questions per candidate-job pairing
๐Ÿ“Š Recruiter Analytics Dashboard Visual funnel metrics, per-job analytics, and hiring KPIs via Recharts
๐Ÿ”” In-App Notifications Real-time-style notification feed with unread tracking
๐Ÿ›ก๏ธ Hardened API Surface Helmet, CORS, rate limiting, centralized error handling, structured Winston logging
๐Ÿณ Container-Native Multi-stage Dockerfiles, Docker Compose orchestration with health checks
โ˜ธ๏ธ Kubernetes-Ready Deployments, Services, ConfigMap/Secret, PVC, and Ingress manifests included

๐Ÿ—๏ธ System Architecture

flowchart TD
    User["๐Ÿ‘ค Recruiter / Hiring Manager"] -->|HTTPS| FE["โš›๏ธ React 18 + Vite SPA<br/>(Zustand ยท Recharts ยท Axios)"]
    FE -->|REST /api/*| GW["๐ŸŒ Nginx Reverse Proxy<br/>(Frontend Container)"]
    GW --> API["๐Ÿš€ Express.js API<br/>(Helmet ยท CORS ยท Rate Limiting)"]

    API --> AUTH["๐Ÿ” Auth Controller<br/>JWT + OTP + bcrypt"]
    API --> JOBS["๐Ÿ’ผ Job Controller"]
    API --> RES["๐Ÿ“„ Resume Controller"]
    API --> CAND["๐Ÿง‘โ€๐Ÿ’ป Candidate Controller"]
    API --> ANA["๐Ÿ“Š Analytics Controller"]
    API --> NOTIF["๐Ÿ”” Notification Controller"]

    RES --> PARSE["๐Ÿง  Resume Parser Service<br/>(pdf-parse ยท mammoth)"]
    CAND --> MATCH["๐ŸŽฏ Matching Service<br/>(weighted scoring engine)"]
    JOBS --> JDGEN["๐Ÿ“ Job Description Service"]
    CAND --> INTV["โ“ Interview Question Service"]

    AUTH --> DB[("๐Ÿ—„๏ธ MySQL 8.0<br/>users ยท jobs ยท candidates<br/>resumes ยท applications")]
    JOBS --> DB
    RES --> DB
    CAND --> DB
    ANA --> DB
    NOTIF --> DB

    AUTH -.->|OTP email| SMTP["๐Ÿ“ง SMTP (Gmail)"]
    RES -.->|stores files| FS[("๐Ÿ“ Uploads Volume")]

    style FE fill:#61DAFB,color:#000
    style API fill:#000,color:#fff
    style DB fill:#4479A1,color:#fff
Loading

๐Ÿ”„ Application Flow

User Journey

flowchart LR
    A[Register Account] --> B[Verify OTP via Email]
    B --> C[Login โ†’ JWT Issued]
    C --> D[Create Job Posting]
    D --> E[Generate Job Description]
    D --> F[Bulk Upload Resumes]
    F --> G[Resumes Auto-Parsed]
    G --> H[Run Candidate Matching]
    H --> I[Review Ranked Shortlist]
    I --> J[Move Candidates Through Pipeline]
    J --> K[Generate Interview Questions]
    K --> L[View Analytics Dashboard]
Loading

Request Lifecycle (Resume Upload โ†’ Match)

sequenceDiagram
    participant U as Recruiter (Browser)
    participant FE as React SPA
    participant API as Express API
    participant MW as Auth Middleware
    participant Parser as Resume Parser Service
    participant Match as Matching Service
    participant DB as MySQL

    U->>FE: Selects resumes + clicks Upload
    FE->>API: POST /api/resumes/upload (multipart)
    API->>MW: authenticate(JWT)
    MW-->>API: user verified
    API->>Parser: extract text + skills (pdf-parse/mammoth)
    Parser->>DB: INSERT candidates, resumes
    API-->>FE: 201 Created (parsed_data, quality_score)
    U->>FE: Clicks "Match Candidates"
    FE->>API: POST /api/candidates/match/:jobId
    API->>Match: calculateMatch(candidate, job)
    Match->>DB: SELECT job requirements
    Match-->>API: match_score + score_breakdown
    API->>DB: UPSERT applications
    API-->>FE: Ranked candidate list
Loading

๐Ÿ“ธ Screenshots

Replace these placeholders with real screenshots from /docs/screenshots/.

Login Dashboard
Login Page Dashboard
Candidate Matching Job Builder
Candidate Results Job Builder
Analytics Resume Upload
Analytics Resume Upload

๐Ÿ› ๏ธ Technology Stack

Layer Technologies
Frontend React 18, Vite, React Router 6, Zustand, Axios, Recharts, React Dropzone, Tailwind CSS, Lucide Icons, React Hot Toast
Backend Node.js 20, Express 4, express-async-errors, express-validator
Database MySQL 8.0 (mysql2 driver), normalized relational schema with UUID primary keys
Authentication JWT (access + refresh tokens), bcryptjs password hashing, email OTP verification
File Processing Multer (uploads), pdf-parse, mammoth (DOCX parsing)
Email Nodemailer over SMTP (Gmail App Passwords)
Security Helmet, CORS, express-rate-limit, centralized error handler
Observability Winston structured logging, Morgan HTTP request logs
Containerization Docker (multi-stage builds), Docker Compose, Nginx (frontend static serving)
Orchestration Kubernetes (Deployments, Services, Ingress, ConfigMap, Secret, PVC)
Deployment Targets Vercel (frontend), Render/EKS (backend), Clever Cloud / managed MySQL

Note on "AI": The matching, scoring, and job-description-generation engines in this codebase are deterministic, rules-based algorithms (weighted skill comparison, template generation) โ€” not third-party LLM API calls. This makes every score fully explainable and reproducible, which is a deliberate design choice for hiring use cases where decisions must be defensible.


๐Ÿ“‚ Project Structure

AiHiringJob/
โ”œโ”€โ”€ backend/
โ”‚   โ”œโ”€โ”€ config/
โ”‚   โ”‚   โ””โ”€โ”€ database.js              # MySQL connection pool + config validation
โ”‚   โ”œโ”€โ”€ controllers/
โ”‚   โ”‚   โ”œโ”€โ”€ authController.js        # Register, login, OTP, refresh, profile
โ”‚   โ”‚   โ”œโ”€โ”€ jobController.js         # CRUD + description generation
โ”‚   โ”‚   โ”œโ”€โ”€ candidateController.js   # Matching, pipeline, interview Qs
โ”‚   โ”‚   โ”œโ”€โ”€ resumeController.js      # Upload, parse, list, delete
โ”‚   โ”‚   โ”œโ”€โ”€ analyticsController.js   # Dashboard + per-job analytics
โ”‚   โ”‚   โ””โ”€โ”€ notificationController.js
โ”‚   โ”œโ”€โ”€ middleware/
โ”‚   โ”‚   โ”œโ”€โ”€ authMiddleware.js        # JWT verification
โ”‚   โ”‚   โ”œโ”€โ”€ errorHandler.js          # Centralized AppError handling
โ”‚   โ”‚   โ””โ”€โ”€ uploadMiddleware.js      # Multer config
โ”‚   โ”œโ”€โ”€ services/
โ”‚   โ”‚   โ”œโ”€โ”€ matchingService.js       # Weighted scoring engine
โ”‚   โ”‚   โ”œโ”€โ”€ resumeParserService.js   # Skill extraction + parsing
โ”‚   โ”‚   โ”œโ”€โ”€ jobDescriptionService.js # Template-based JD generator
โ”‚   โ”‚   โ”œโ”€โ”€ interviewService.js      # Question bank generator
โ”‚   โ”‚   โ””โ”€โ”€ emailService.js          # OTP + notification emails
โ”‚   โ”œโ”€โ”€ routes/                      # authRoutes, jobRoutes, resumeRoutes, ...
โ”‚   โ”œโ”€โ”€ sql/
โ”‚   โ”‚   โ”œโ”€โ”€ mysql-schema.sql         # Full relational schema
โ”‚   โ”‚   โ””โ”€โ”€ notifications.sql
โ”‚   โ”œโ”€โ”€ utils/logger.js
โ”‚   โ”œโ”€โ”€ Dockerfile
โ”‚   โ”œโ”€โ”€ .env.example
โ”‚   โ””โ”€โ”€ server.js / app.js
โ”œโ”€โ”€ frontend/
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ components/              # Breadcrumb, NotificationsDropdown, ProfileDropdown
โ”‚   โ”‚   โ”œโ”€โ”€ layouts/DashboardLayout.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ pages/                   # Login, Register, OTP, Dashboard, JobBuilder, Candidates...
โ”‚   โ”‚   โ”œโ”€โ”€ services/api.js          # Axios instance
โ”‚   โ”‚   โ””โ”€โ”€ store/authStore.js       # Zustand auth store
โ”‚   โ”œโ”€โ”€ Dockerfile
โ”‚   โ”œโ”€โ”€ nginx.conf
โ”‚   โ””โ”€โ”€ vercel.json
โ”œโ”€โ”€ kubernetes/
โ”‚   โ”œโ”€โ”€ deployment.yaml              # Backend + Frontend Deployments
โ”‚   โ””โ”€โ”€ k8s-resources.yaml           # Services, ConfigMap, Secret, PVC, Ingress
โ”œโ”€โ”€ docker-compose.yml                # mysql + backend + frontend orchestration
โ””โ”€โ”€ README.md

๐ŸŒ API Documentation

Auth Routes โ€” /api/auth

Method Endpoint Description Auth
POST /register Create a recruiter account Public
POST /login Authenticate, issue JWT pair Public
POST /verify-otp Verify OTP sent to email Public
POST /resend-otp Resend OTP code Public
POST /refresh Exchange refresh token for new access token Public
POST /logout Invalidate session ๐Ÿ”’
GET /me Get current user profile ๐Ÿ”’
PUT /update-profile Update recruiter profile ๐Ÿ”’

Job Routes โ€” /api/jobs

Method Endpoint Description
POST / Create a job posting
GET / List jobs
GET /:id Get a single job
PUT /:id Update a job
DELETE /:id Delete a job
POST /generate-description Auto-generate a job description

Resume Routes โ€” /api/resumes

Method Endpoint Description
POST /upload Bulk upload up to 20 resumes (multipart)
GET / List parsed resumes
GET /:id Get resume detail + parsed data
DELETE /:id Delete a resume

Candidate Routes โ€” /api/candidates

Method Endpoint Description
GET / List candidates
GET /:id Candidate detail
POST /match/:jobId Run matching engine against a job
PUT /pipeline/:applicationId Update pipeline stage
POST /:candidateId/interview-questions/:jobId Generate interview questions

Analytics & Notifications

Method Endpoint Description
GET /api/analytics/dashboard Aggregate hiring metrics
GET /api/analytics/jobs/:jobId Per-job funnel analytics
GET /api/notifications List notifications
PATCH /api/notifications/:id/read Mark notification as read

All routes other than /auth/register, /auth/login, /auth/verify-otp, /auth/resend-otp, and /auth/refresh require a valid Authorization: Bearer <token> header.


๐Ÿ—„๏ธ Database Design

erDiagram
    USERS ||--o{ JOBS : creates
    USERS ||--o{ CANDIDATES : owns
    USERS ||--o{ RESUMES : owns
    USERS ||--o{ NOTIFICATIONS : receives
    USERS ||--|| RECRUITERS : "has profile"
    JOBS ||--o{ APPLICATIONS : receives
    CANDIDATES ||--o{ APPLICATIONS : submits
    CANDIDATES ||--o{ RESUMES : has
    RESUMES ||--o| APPLICATIONS : "linked to"

    USERS {
        char id PK
        string name
        string email
        string password_hash
        string role
        boolean is_verified
        string otp_code
        datetime otp_expires_at
    }
    RECRUITERS {
        char id PK
        char user_id FK
        string company_name
        string job_title
    }
    JOBS {
        char id PK
        char user_id FK
        string title
        json required_skills
        json nice_to_have_skills
        int experience_min
        int experience_max
        string status
    }
    CANDIDATES {
        char id PK
        char user_id FK
        string name
        json skills
        int experience_years
        json education
    }
    RESUMES {
        char id PK
        char candidate_id FK
        string filename
        json parsed_data
        int quality_score
        boolean is_duplicate
    }
    APPLICATIONS {
        char id PK
        char job_id FK
        char candidate_id FK
        char resume_id FK
        int match_score
        json score_breakdown
        string pipeline_stage
    }
    NOTIFICATIONS {
        char id PK
        char user_id FK
        text message
        boolean is_read
    }
Loading

โš™๏ธ Installation Guide

Prerequisites

  • Node.js โ‰ฅ 20
  • MySQL โ‰ฅ 8.0 (or use the bundled Docker MySQL container)
  • npm

1. Clone the Repository

git clone https://github.com/GIRICHANDAN125/AiHiringJob.git
cd AiHiringJob

2. Backend Setup

cd backend
cp .env.example .env     # fill in DB + JWT + SMTP values
npm install
npm run dev               # nodemon, http://localhost:5000 (or 5002)

3. Frontend Setup

cd frontend
npm install
npm run dev               # Vite dev server

4. Database Setup

mysql -u root -p < backend/sql/mysql-schema.sql
mysql -u root -p < backend/sql/notifications.sql

5. Environment Variables (backend/.env)

NODE_ENV=production
PORT=5002
FRONTEND_URL=https://your-vercel-app.vercel.app

DB_HOST=
DB_PORT=3306
DB_NAME=
DB_USER=
DB_PASSWORD=
# Or: DATABASE_URL=mysql://user:password@host:port/dbname

JWT_SECRET=
JWT_REFRESH_SECRET=
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d

SMTP_USER=your-email@gmail.com
SMTP_PASS=xxxx xxxx xxxx xxxx
EMAIL_FROM=your-email@gmail.com

UPLOAD_DIR=./uploads
MAX_FILE_SIZE=10485760

๐Ÿณ Docker

The project ships with a full Docker Compose stack: MySQL โ†’ Backend โ†’ Frontend, wired together with health checks and dependency ordering.

cp backend/.env.example backend/.env
docker-compose up --build
Service Image Port Notes
mysql mysql:8.0 3306 Healthcheck via mysqladmin ping
backend built from backend/Dockerfile (node:20-alpine) 5000 Waits for MySQL healthcheck, runs as non-root node user
frontend multi-stage build โ†’ nginx:1.27-alpine 3000 โ†’ 80 Serves Vite production build via Nginx

Build an individual image:

docker build -t ai-hiring-backend ./backend
docker build -t ai-hiring-frontend ./frontend --build-arg VITE_API_URL=/api

โ˜ธ๏ธ Kubernetes

Production-style manifests live in kubernetes/:

  • Deployments โ€” backend and frontend, 2 replicas each, with CPU/memory requests & limits, liveness and readiness probes (/health for backend, / for frontend).
  • Services โ€” backend-service and frontend-service (ClusterIP).
  • ConfigMap โ€” non-secret runtime config (NODE_ENV, DB_HOST, etc.).
  • Secret โ€” JWT_SECRET, DB credentials, SMTP credentials (replace placeholder values before applying).
  • PersistentVolumeClaim โ€” ReadWriteMany, 10Gi, for the shared /app/uploads volume across backend pods.
  • Ingress โ€” Nginx ingress class with TLS via cert-manager (letsencrypt-prod cluster issuer), routing /api โ†’ backend, / โ†’ frontend.
kubectl create namespace ai-hiring
kubectl apply -f kubernetes/ -n ai-hiring
kubectl get pods -n ai-hiring -w

Scaling Strategy

  • Backend pods are stateless โ€” scale horizontally with kubectl scale deployment/backend --replicas=N or attach a Horizontal Pod Autoscaler (HPA) on CPU utilization (not yet included โ€” see Future Enhancements).
  • The shared uploads PVC means any replica can serve any user's files, avoiding sticky-session requirements Improved project overview.

๐Ÿ” CI/CD

Current state: No GitHub Actions / CI pipeline is present in the repository yet. The suggested pipeline below reflects the natural next step given the existing Docker and Kubernetes assets, and is listed under Future Enhancements.

flowchart LR
    A[Push to main] --> B[Lint & Test]
    B --> C[Build Docker Images]
    C --> D[Push to Registry]
    D --> E[kubectl apply -f kubernetes/]
    E --> F[Rolling Update on Cluster]
Loading

๐Ÿš€ Deployment

Component Target
Frontend Vercel (static build, VITE_API_URL env var)
Backend Render / Railway / AWS EKS (containerized)
Database Clever Cloud MySQL / Amazon RDS for MySQL
File Storage Persistent volume (local) or swap for S3-compatible storage at scale

The live demo (https://ai-hiring-job.vercel.app) follows this exact split: Vercel for the SPA, a managed Node host for the API, and a managed MySQL instance for persistence.


๐Ÿ”’ Security Features

  • JWT Authentication โ€” short-lived access tokens (15 min) paired with longer-lived refresh tokens (7 days) to limit exposure of compromised tokens.
  • Password Hashing โ€” bcryptjs with salted hashing; raw passwords are never stored or logged.
  • Email OTP Verification โ€” accounts must verify a one-time code before becoming active.
  • API Protection โ€” helmet security headers, strict CORS policy, and tiered rate limiting (general API vs. auth endpoints).
  • Environment Security โ€” all secrets (JWT_SECRET, DB credentials, SMTP credentials) are externalized via .env / Kubernetes Secrets and never committed to source control.
  • Centralized Error Handling โ€” AppError + errorHandler middleware prevent stack traces or internal details from leaking to clients.

โšก Performance Optimizations

  • Compression โ€” compression middleware gzips API responses.
  • Connection Pooling โ€” mysql2 connection pool avoids per-request connection overhead.
  • Indexed Queries โ€” targeted indexes on applications(job_id), applications(candidate_id), resumes(user_id), and notifications(user_id, created_at) keep dashboard and matching queries fast as data scales.
  • Multi-Stage Docker Builds โ€” frontend image discards the Node build toolchain, shipping only static assets via Nginx for a minimal runtime footprint.
  • Duplicate Detection โ€” hash-based dedup avoids re-parsing and re-scoring identical resumes.

๐Ÿ”ฎ Future Enhancements

  1. Real LLM-backed semantic resume matching (embeddings) as an optional upgrade path over the current rules engine
  2. GitHub Actions CI/CD pipeline (lint โ†’ test โ†’ build โ†’ deploy)
  3. Horizontal Pod Autoscaler (HPA) for the backend Deployment
  4. Redis caching layer for analytics/dashboard queries
  5. S3-compatible object storage for resumes instead of local PVC
  6. Role-based access control for multi-recruiter organizations
  7. Candidate-facing portal for self-service applications
  8. Calendar integration for interview scheduling
  9. Webhooks for ATS (Applicant Tracking System) integrations
  10. Resume parsing support for additional formats (RTF, scanned PDFs via OCR)
  11. Audit logging for compliance-sensitive hiring decisions
  12. Multi-language resume parsing
  13. Automated email digests of weekly hiring funnel metrics
  14. Dark mode for the dashboard
  15. End-to-end test suite (Playwright/Cypress) and backend integration tests

๐Ÿ‘จโ€๐Ÿ’ป Author

Chandu Giri Full Stack Developer ยท B.Tech Computer Science & Engineering

LinkedIn Email GitHub


๐Ÿ’ฌ Support

If you run into issues or have questions:

  • Open an issue
  • Start a discussion
  • Reach out directly via the contact links above

If this project helped you, consider giving it a โญ โ€” it genuinely helps visibility.


๐Ÿ“„ License

This project is licensed under the MIT License. See LICENSE for details.

Made with โ˜• and a lot of console.log by Chandu Giri

About

Full-stack hiring platform with bulk resume parsing, explainable candidate-job matching, pipeline tracking & analytics. Node/Express + React + MySQL, Docker & Kubernetes-ready.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages