TIMELINE
JUN 2026 – JUL 2026
PROJECT TYPE
Independent Project
ROLE
Full Stack Developer
STATUS
Completed
DEPLOYMENT
Render (Docker)
REPOSITORY
GitHub
Project Overview
ResumeTailor AI turns a single master resume into a version tailored to any job description, ready for both ATS filters and human recruiters. It analyzes the job posting, lets you choose which keywords to prioritize, and uses Google Gemini to rewrite your bullets, summary, and project descriptions around them. The finished resume is exported as a clean PDF built with Jinja2 and WeasyPrint. The main goal was accuracy. A Resume Completeness Validator checks the output against your original resume, so nothing is dropped and nothing is invented. Every line in the tailored version traces back to something you actually did.
Key highlights
- Built the full tailoring pipeline from scratch, from job description analysis to PDF export.
- Integrated Google Gemini for recruiter-style rewriting with context-aware keyword placement.
- Added a Completeness Validator that rejects any output with missing or invented sections.
- Designed a three-panel keyword picker: master, JD-aligned, and gap keywords.
- Created a scoring dashboard covering ATS match, readability, and capability fit.
- Blocked 200+ soft-skill buzzwords so only real technical keywords surface.
- Rendered ATS-safe PDFs with Jinja2 and WeasyPrint in reverse chronological order.
- Deployed on Render with Docker, session login, and IP-based rate limiting.
Problem Statement
Most AI resume tools rewrite resumes by introducing unsupported skills, fabricated projects, or generic recruiter buzzwords that never appeared in the candidate's original experience. This erodes hiring credibility and creates liability during background checks. Existing tools also fail at ATS compatibility — dumping keywords without context or semantic relevance. The core challenge was to build a resume tailoring engine that genuinely improves ATS compatibility and recruiter readability while ensuring every generated statement remains traceable to factual content in the original master resume.
Solution Approach
ResumeTailor AI solves this through a structured, multi-stage pipeline. Users upload a master resume and paste a target job description. The backend performs semantic JD analysis, extracts and classifies ATS keywords into three categories — keywords from the master resume, keywords present in the JD, and gap keywords the master supports — and presents an interactive selection interface. Users choose which keywords to prioritize. The AI then rewrites experience bullets, project descriptions, and the professional summary in recruiter-quality language, integrating selected keywords naturally. A Resume Completeness Validator cross-checks the output against every factual section of the uploaded resume and rejects any tailored version that drops or fabricates information. The validated resume is then exported as a professionally formatted, ATS-friendly PDF with hyperlinked GitHub, LinkedIn, and portfolio URLs.
Architecture Overview
ResumeTailor AI is a FastAPI application split into focused modules, so the web layer, the AI logic, and PDF rendering each stay independent and easy to change.
- FastAPI routes handle the four core jobs: keyword analysis, resume generation, text extraction, and PDF download.
- gemini_service.py holds every Gemini call, from tailoring and keyword analysis to bullet checks and summary fitting, so AI logic never leaks into the routes.
- pdf_service.py renders Jinja2 templates through WeasyPrint and trims content until the resume fits on a single page.
- storage.py keeps the resume bank and session data in memory across the multi-step generation flow.
- Session middleware protects every page, and a sliding-window rate limiter caps requests per IP to keep Gemini costs under control.
- Docker packages the app for Render, with the API key, session secret, and site passwords injected as environment variables.
Tech Stack
Backend
- Python 3.10+
- FastAPI
- Uvicorn
- Starlette
Artificial Intelligence
- Google Gemini API
- Semantic JD Matching
- Prompt Engineering
PDF Generation
- Jinja2 Templates
- WeasyPrint
- HTML Resume Templates
Frontend
- HTML
- CSS
- Vanilla JavaScript
Infrastructure
- Docker
- Render
- Environment Variables
Security
- Session Middleware
- Rate Limiting
- Password Auth
Key Features
- Semantic job description analysis that picks up intent and required skills, not just matching words.
- Three-panel keyword selector with master, JD-aligned, and gap keywords you can toggle.
- Gemini rewriting of bullets, summaries, and project descriptions in recruiter-style language.
- Completeness Validator that rejects any resume missing a section from the master.
- Prompt and validation checks that stop invented skills, projects, or experience.
- Scoring dashboard for ATS match, readability, and capability fit.
- Soft-skill blocklist that keeps 200+ generic buzzwords out of the keyword list.
- Bullet quality checks that run before the PDF is rendered.
- Page-fit optimization that trims bullets to keep the resume on one page.
- ATS-friendly PDF export with clickable GitHub, LinkedIn, and portfolio links.
- PDF and DOCX resume uploads with built-in text extraction.
- Password login and per-IP rate limiting to protect the Gemini API.
System Modules
- Step 1: Upload Resume (PDF or DOCX)
- Step 2: Paste Target Job Description
- Step 3: Semantic Keyword Analysis
- Step 4: Interactive Keyword Prioritization
- Step 5: AI Resume Generation
- Step 6: Completeness Validation
- Step 7: Scoring Dashboard Review
- Step 8: ATS PDF Download
Lessons Learned
Retrospective
The hardest part of ResumeTailor AI was not the Gemini integration. It was making the output trustworthy. Early versions sometimes dropped sections like certifications or internships without any warning, and a resume with missing sections is worse than no resume at all. Adding a completeness validator that checks every section against the master resume, and regenerates automatically when something is missing, fixed that. Prompt design mattered more than I expected. The same Gemini model behaved very differently depending on how the instructions were laid out. Splitting the persona, the factual constraints, and the formatting rules into separate prompt blocks gave far more consistent results than one long instruction. The keyword picker taught me a product lesson. People trust a tool more when they can see and control what it is optimizing for, so the three-panel layout turned a black box into a set of choices the user makes. Deployment had its own surprises. WeasyPrint needs system fonts and GTK libraries, so getting PDF rendering to work inside Docker took more effort than the rendering code itself. The biggest takeaway is that an AI tool is only as reliable as the checks around the model, and those checks deserve as much engineering time as the model call.
System Screenshots & Wireframes
01. Authentication Portal








