LLD
AI-Powered Recruitment Automation System
Low-Level Design Document (LLD)
📘 Table of Contents
- System Overview
- Module Breakdown
- API Design
- Database Design
- Business Workflow
- AI Integration Points
- System Architecture
1. System Overview
1.1 🎯 Purpose
Automate the recruitment pipeline from resume ingestion to candidate ranking using NLP-based parsing, vector embeddings, and AI-powered re-ranking.
1.2 ⚙️ Key Capabilities
- Incremental Resume Ingestion: Fetch new resumes from Gmail on schedule
- Automated Resume Parsing: Extract structured data (skills, experience, education, contact)
- Semantic Matching: Use embeddings to find similar candidates to job descriptions
- AI Re-Ranking: Re-rank top candidates using GPT-4o-mini for better precision
- Dashboard: HR views ranked candidates with explainability
1.3 🧰 Technology Stack
| Layer | Technology |
|---|---|
| Frontend | React.js + Tailwind CSS |
| Backend | Node.js + Express.js |
| Database | PostgreSQL 15+ with pgvector extension |
| AI/ML | OpenAI GPT-4o-mini |
| Embeddings | OpenAI text-embedding-3-small |
| Email Integration | Gmail API with OAuth 2.0 |
| Scheduler | node-cron |
2. Module Breakdown
Module 1: Gmail Module
Responsibility: Email integration and resume fetching
Functions:
- Authenticate with Gmail API using OAuth 2.0
- Fetch emails with attachments based on filters (date, keywords, labels)
- Download resume attachments (PDF, DOCX)
- Track last fetch timestamp for incremental processing
Key Operations:
fetchNewEmails(afterDate, filters)→ Returns array of email objects with attachmentsdownloadAttachment(messageId, attachmentId)→ Returns file buffergetLastFetchTime(jobId)→ Returns timestamp of last successful fetch
External Dependencies: Gmail API, Google OAuth 2.0
Module 2: Resume Parser Module
Responsibility: Extract structured data from resume text
Parsing Strategy: Rule-based NLP with regex patterns
Name Extraction: First line heuristics, capitalization patterns
Email Extraction: Regex pattern [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
Phone Extraction: Regex for various formats (+1-XXX-XXX-XXXX, (XXX) XXX-XXXX)
Skills Extraction: Keyword matching against predefined skill database
Experience Parsing: Section detection (keywords: "experience", "work history") + date parsing
Education Parsing: Section detection + degree/institution extraction
Functions:
extractText(fileBuffer, format)→ Returns plain text from PDF/DOCXparseResume(resumeText)→ Returns structured JSON objectvalidateParsedData(data)→ Returns boolean + error messagesnormalizeSkills(skillArray)→ Returns deduplicated, lowercase skills
Output Format (JSON):
{ "name": "John Doe", "email": "john@example.com", "phone": "+1-555-0123", "skills": ["javascript", "python", "sql"], "experience": [ { "title": "Software Engineer", "company": "Tech Corp", "duration": "2020-2023", "description": "Built REST APIs..." } ], "education": [ { "degree": "B.S. Computer Science", "institution": "MIT", "year": 2018 } ], "total_experience_years": 5 }
Alternative AI Approach (Optional Enhancement)
Instead of rule-based parsing, use GPT-4o-mini with structured JSON output. The flow would be: extract plain text -> send it to GPT-4o-mini with a schema-enforced prompt -> receive structured JSON (name, email, phone, skills, experience, education, total years).
Pros:
- Much higher accuracy across different resume formats and layouts
- Handles inconsistent structures, missing sections, and varied wording
- Reduces need for complex regex/heuristics
Cons:
- Incur API usage costs
- Slightly higher latency (~2–5 seconds per resume, depending on length)
- Requires API reliability and internet access