MatchlyPro is a production-oriented resume matcher web app that compares a resume against a job description, highlights keyword coverage, surfaces ATS risks, and suggests practical improvements. It now supports server-side AI analysis through the Gemini API.
This repository is designed as a portfolio project that shows both product engineering and delivery discipline:
- product design and implementation
- client-side PDF parsing with PDF.js
- production-ready hosting with a lightweight Node server
- containerized runtime with Node and Docker
- CI checks with GitHub Actions
- release-gated production promotion
- basic security scanning and smoke validation
- Production app: https://matchlypro.vercel.app
- Repository: https://github.com/muhammadhammad2005/MatchlyPro
This is a strong portfolio example for:
- frontend product engineering
- shipping polished browser-based tools
- practical CI/CD ownership
- containerization and deployment workflows
- release-based production control for the app runtime
It is not a full multi-tenant SaaS yet because there is no database, authentication, billing, or persistent user accounts. It is better described as a production-minded web product with AI-assisted analysis and practical DevOps discipline than as a complete SaaS platform.
- compares a resume with a job description in real time
- features deep AI analysis using a customized "Elite Recruiter" prompt for robust, context-aware scoring
- extracts text from uploaded PDF resumes natively in the browser
- calculates an overall match score and categorizes results (strong, partial, missing)
- dynamically sizes complex AI feedback using robust flexbox/grid UI wrapping (prevents UI blowout)
- provides clean error-handling for API rate-limits and safely parses markdown-polluted JSON
- flags ATS issues and resume risks
- offers copy, export, and local save actions
- works on desktop and mobile
- HTML5
- CSS3
- Vanilla JavaScript
- PDF.js
- Node.js
- Docker
- GitHub Actions
- GitHub Releases
- Vercel
- Snyk
- gitleaks
flowchart LR
U[User Browser] --> V[Vercel Edge Network]
V --> S[Static Assets<br/>index.html]
V --> A[Vercel Serverless Function<br/>@vercel/node API]
A --> R[Gemini API<br/>gemini-2.5-flash-lite]
S --> J[Browser App Logic]
J --> P[PDF.js Parsing In Browser]
J --> L[Local Storage Session History]
flowchart TD
D[Developer] --> B[Feature or Fix Branch]
B --> PR[Pull Request to main]
PR --> CI[CI Workflow]
CI --> M[Merge to main]
M --> R[Version Tag or Release Trigger]
R --> REL[Production Release Workflow]
REL --> V[Vercel Production]
REL --> I[Docker Images]
sequenceDiagram
participant User
participant App as MatchlyPro App
participant PDF as PDF.js
User->>App: Paste job description
User->>App: Upload resume PDF
App->>PDF: Extract resume text
PDF-->>App: Parsed content
App-->>User: Match score, keyword gaps, ATS risks
- deployed as a high-performance hybrid app with Vercel Serverless Functions powering the AI backend
- deep AI integration with graceful fallbacks and user-friendly quota/rate-limit alerts
- robust, dynamic UI that intelligently handles long AI-generated text without breaking layouts
- browser-first workflow with secure, client-side PDF parsing and no account required
- privacy-friendly resume analysis
- responsive single-page interface
- dynamic local history that automatically names sessions based on AI-detected job titles
- CI runs on branches, pull requests, and main
- Docker smoke validation is part of CI
- production deployment is separated from ordinary CI runs
- Vercel Git auto-deploy is disabled for tighter release control
- gitleaks scan for secret detection
npm auditat high severity threshold- Snyk dependency scanning
- health endpoint verification in container checks
File: .github/workflows/ci-cd.yml
Pipeline stages:
Quality Gate -> Security Checks -> Docker Smoke Test -> Notification Stage
CI runs on:
- pushes to
main - pushes to delivery branches such as
feature/**,fix/**,chore/** - pull requests targeting
main - manual workflow dispatch
CI does not deploy production.
flowchart LR
Q[Quality Gate] --> S[Security Checks]
S --> D[Docker Smoke Test]
D --> N[Notification Stage]
File: .github/workflows/release.yml
Production release stages:
Release Quality Gate -> Release Security Checks -> Release Docker Smoke Test -> Publish Release Images -> Deploy Release to Vercel Production -> Publish GitHub Release -> Release Notification Stage
This release workflow is separated from routine CI so production is not updated by every merge.
flowchart LR
T[Push Version Tag] --> RQ[Release Quality Gate]
RQ --> RS[Release Security Checks]
RS --> RD[Release Docker Smoke Test]
RD --> DP[Publish Docker Images]
DP --> VV[Deploy to Vercel Production]
VV --> GR[Create GitHub Release]
GR --> RN[Release Notification]
This repository is public, but that does not mean random users can deploy production.
Production deployment remains under maintainer control because:
- only users with write access can push tags to the upstream repository
- GitHub Actions secrets are only available in the main repository context
- forks do not get access to production secrets like
VERCEL_TOKEN - Vercel Git auto-deploy is disabled in vercel.json
In practical terms, someone can fork the repo and run their own copy, but they cannot deploy this repository's production environment without maintainer permissions and secrets.
- normal pushes and pull requests run CI only
- production deployment is promoted through the release workflow
- Vercel production is deployed via CLI with repository secrets
- Docker images are published as release artifacts
- Create a local env file from the example:
cp .env.example .env- Set these values:
AI_API_KEYAI_BASE_URLAI_MODELAI_PROVIDER(optional, for display only)
OpenAI example:
AI_BASE_URL=https://api.openai.com/v1AI_MODEL=gpt-4.1-mini
Gemini OpenAI-compatible example:
AI_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai/AI_MODEL=gemini-2.5-flash-lite
- Start the app:
npm ci
npm startOpen http://localhost:3000
Legacy OPENAI_* and GEMINI_* env vars are still supported, but AI_* is the recommended format for local use and Vercel.
If no AI env vars are set, the app still runs and falls back to local heuristic analysis.
Set the same AI_* variables in your Vercel project settings:
AI_API_KEYAI_BASE_URLAI_MODELAI_PROVIDER(optional)
docker build --target production -t resume-matcher .
docker run --rm -p 8080:8080 resume-matcherOpen http://localhost:8080
npm run ci:validateThis validates project structure and runs static smoke checks.
Current production promotion is tag-driven.
git checkout main
git pull origin main
git tag v1.0.0
git push origin v1.0.0That release tag triggers the production workflow, publishes release artifacts, and deploys the tagged version to Vercel production.
- explicit Builder architecture in
vercel.jsonelegantly runs the same Node codebase locally via Docker and in the cloud as a Vercel Serverless Function vercel.jsondisables Git-based Vercel auto deployment for manual, tagged release control- the app exposes
/healthfor CI deployment verification - Docker runtime uses the Node server for app and API delivery
- CI and release jobs depend on repository secrets for external integrations
.
|-- .github/
| |-- CODEOWNERS
| |-- pull_request_template.md
| `-- workflows/
| |-- ci-cd.yml
| `-- release.yml
|-- scripts/
| |-- smoke-static-site.mjs
| `-- validate-project.mjs
|-- CONTRIBUTING.md
|-- Dockerfile
|-- LICENSE
|-- README.md
|-- .env.example
|-- health.html
|-- index.html
|-- nginx.conf
|-- package.json
|-- server.mjs
`-- vercel.json
This repository is portfolio-ready for a production-minded web app because it includes:
- a deployed live product
- a clear branching and promotion story
- CI separate from production deployment
- containerization and runtime health checks
- release automation
- security scanning
- reviewer-facing documentation
- no persistent backend storage
- no persistent database
- no authentication or user accounts
- no billing or subscriptions
- no staging environment yet
- no end-to-end browser test suite yet
- add a staging deployment environment
- add Playwright end-to-end tests
- add Lighthouse and accessibility checks in CI
- add a custom domain
- add analytics and error monitoring
- add persistent storage for saved sessions or team features
Muhammad Hammad
Built, containerized, documented, deployed, and automated as a portfolio project to demonstrate product engineering with practical DevOps ownership.