AI-Powered Resume-Driven Job Discovery, Live Vacancy Verification & Automated Career Alerts
JobPulse AI is an intelligent job search and matching platform that bridges the gap between candidates and legitimate career opportunities. Instead of relying on generic keyword searches, JobPulse AI parses uploaded resumes across diverse engineering and professional disciplines, constructs a structured candidate profile, discovers vacancies from verified job feeds, validates application link accessibility using an SSRF-guarded verification engine, and delivers personalized recommendations and daily email alerts.
Repository Destination: https://github.com/Pratikshaprabhakarbande/JobPulseAI.git Maintainer: @Pratikshaprabhakarbande
node-cron scheduler that periodically finds jobs, deduplicates listings, and dispatches responsive HTML email digests.%PDF- and PK\x03\x04).in). Requires ADZUNA_APP_ID & ADZUNA_APP_KEY.unverified and excluded from strict short-term (24h & 72h) windows.VERIFIED_OPEN: Accessible listing on official ATS (Greenhouse, Lever, Workday, etc.) or page contains functional application call-to-action.LIKELY_OPEN: Destination responds with HTTP 200 OK, but active application submission cannot be conclusively proven. (An accessible HTTP 200 response does not guarantee an open requisition).EXPIRED_OR_CLOSED: Conclusive closure detected (HTTP 404/410, or page contains phrases such as βjob is no longer availableβ, βposition has been filledβ, βthis vacancy has closedβ).INVALID_LINK: Malformed URL, unresolvable domain, or blocked by SSRF security guard.VERIFICATION_BLOCKED: Access restricted by Cloudflare or anti-bot controls (HTTP 403/429) or timed out (6s limit); reported honestly without guessing.UNKNOWN: Non-200 HTTP status or pending verification.EXPIRED_OR_CLOSED is automatically assigned a score of 0 and marked ineligible.node-cron daemon running daily at 09:00 IST (Asia/Kolkata). Requires the backend Node.js process and host machine to remain running.lastNotifiedJobIds) to prevent duplicate email alerts during scheduled runs.1. RESUME UPLOAD -> Upload PDF or DOCX file (magic-byte validated).
2. PROFILE PARSING -> Extracts degree, skills, certifications, and documented projects.
3. PROFILE EDITOR -> User reviews and adjusts target roles, skills, and locations.
4. JOB DISCOVERY -> Ingests vacancies from Adzuna (India), Remotive (Remote) & Arbeitnow.
5. SSRF VERIFICATION -> Safely resolves and audits application URLs against ATS platforms.
6. 5-FACTOR MATCHING -> Evaluates job family, skills, experience, degree, and location fit.
7. LIVE DASHBOARD -> Presents verified jobs with match breakdowns and filter controls.
8. DAILY DIGEST -> node-cron dispatches deduplicated email alerts for top verified roles.
flowchart TB
subgraph Client["Frontend Client (React 19 + TypeScript + Vite)"]
Dashboard["Dashboard View"]
JobsFeed["Live Jobs Feed"]
ProfileEditor["Candidate Profile Editor"]
SettingsPage["Settings & Automation"]
APIClient["API Client (`src/api.ts`)"]
Dashboard --> APIClient
JobsFeed --> APIClient
ProfileEditor --> APIClient
SettingsPage --> APIClient
end
subgraph Server["Backend Application (Express + TypeScript)"]
SecHeaders["Security Headers (`nosniff`, `DENY`)"]
RateLimits["Rate Limiters (Upload / Refresh / Email)"]
subgraph Routes["API Routes"]
R_Resume["`/api/resume`"]
R_Jobs["`/api/jobs`"]
R_Dash["`/api/dashboard/stats`"]
R_Settings["`/api/settings`"]
R_Sched["`/api/scheduler`"]
R_Health["`/api/health`"]
end
subgraph CoreServices["Services Layer"]
ResumeParser["Resume Analyzer (`resumeAnalyzer.ts`)"]
JobEngine["Job Discovery Engine (`jobService.ts`)"]
Verifier["Vacancy Verifier (`verificationService.ts`)"]
Matcher["5-Factor Matcher (`aiService.ts`)"]
Store["Local JSON DataStore (`dataStore.ts`)"]
Scheduler["Automation Scheduler (`schedulerService.ts`)"]
Emailer["Email Dispatcher (`emailService.ts`)"]
end
SecHeaders --> RateLimits --> Routes
R_Resume --> ResumeParser --> Store
R_Jobs --> JobEngine --> Verifier --> Matcher --> Store
R_Dash --> Store
R_Settings --> Store
R_Sched --> Scheduler
Scheduler --> JobEngine
Scheduler --> Matcher
Scheduler --> Emailer
end
subgraph External["External APIs & Services"]
Adzuna["Adzuna API (India)"]
Remotive["Remotive API (Remote)"]
Arbeitnow["Arbeitnow API (Public Board)"]
TargetATS["Employer ATS Systems"]
SMTP["Gmail SMTP / Nodemailer"]
end
JobEngine --> Adzuna
JobEngine --> Remotive
JobEngine --> Arbeitnow
Verifier --> TargetATS
Emailer --> SMTP
For an in-depth design specification and data flow diagrams, see docs/ARCHITECTURE.md.
| Layer | Technology | Purpose |
|---|---|---|
| Frontend Framework | React 19 (^19.3.0) |
Declarative, component-driven user interface |
| Frontend Language | TypeScript (~6.0.2) |
Strict client-side type safety |
| Bundler & Build Tool | Vite (^8.3.0) |
High-speed HMR development server and production bundler |
| Styling & Effects | Tailwind CSS v4 (^4.3.3) |
Modern CSS design with glassmorphic cards and responsive layouts |
| Icons | Lucide React (^1.52.0) |
Clean, accessible vector UI icons |
| Backend Runtime | Node.js (v18+ / v20+ / v24+) | Server-side JavaScript execution environment |
| Backend Framework | Express (^4.21.0) |
REST API routing and middleware pipeline |
| Backend Language | TypeScript (^5.6.2) |
Strict server-side type safety |
| Execution Engine | tsx (^4.19.1) |
Zero-compile TypeScript execution for development and tests |
| Document Parsing | pdf-parse (^1.1.1), mammoth (^1.8.0) |
Stream-based text extraction for PDF and DOCX files |
| File Handling | multer (^1.4.5-lts.1) |
Multipart form handling with in-memory validation |
| Job Discovery APIs | Adzuna API, Remotive API, Arbeitnow API | Live job feeds with authentic publication metadata |
| Job Verification | Built-in Node.js dns & fetch |
SSRF-guarded HTTP destination and ATS validation engine |
| Scheduler | node-cron (^4.6.0) |
Background automated discovery and digest daemon (09:00 IST) |
| Email Service | nodemailer (^6.9.15) |
Responsive HTML email digest generation via SMTP |
| Database / Store | JSON File Store (dataStore.ts) |
Persistent local candidate, settings, and job store in ./data/ with in-memory caching |
JobPulseAI/
βββ .github/workflows/ # GitHub Actions workflows
β βββ ci.yml # Automated test & Vite build pipeline
β βββ deploy.yml # GitHub Pages deployment workflow (client/dist)
βββ .env.example # Root environment template with safe placeholders
βββ .gitignore # Git ignore rules (node_modules, .env, uploads, logs)
βββ CONTRIBUTING.md # Contribution guidelines & security disclosure
βββ package.json # Root workspace convenience scripts (install, dev, test, build)
βββ README.md # Main project documentation
βββ docs/ # Technical documentation
β βββ API.md # Complete REST API reference
β βββ ARCHITECTURE.md # Architecture diagrams & component deep dive
βββ client/ # Frontend Single Page Application
β βββ index.html # HTML entry point with modern typography
β βββ package.json # Client dependencies & scripts
β βββ tsconfig.json # TypeScript configuration
β βββ vite.config.ts # Vite build config with /api reverse proxy
β βββ src/
β βββ main.tsx # React application mount
β βββ App.tsx # Main application UI, routing, and view components
β βββ api.ts # Typed API client functions
β βββ index.css # Tailwind CSS imports and theme tokens
β βββ vite-env.d.ts # Vite client environment typings
βββ server/ # Backend Express Application
βββ package.json # Server dependencies & scripts
βββ tsconfig.json # TypeScript server configuration
βββ .env.example # Backend-specific environment template
βββ src/
βββ index.ts # Server entry point, middleware & port listener
βββ config/
β βββ index.ts # Typed configuration loader & validation
βββ middleware/
β βββ errorHandler.ts # Global error & 404 response handlers
β βββ rateLimiter.ts # In-memory IP rate limiters
βββ routes/
β βββ dashboard.ts # /api/dashboard metrics endpoint
β βββ jobs.ts # /api/jobs listing, filtering & verification
β βββ resume.ts # /api/resume upload & candidate profile editor
β βββ scheduler.ts # /api/scheduler trigger & status controls
β βββ settings.ts # /api/settings preferences & test email
βββ services/
β βββ aiService.ts # 5-factor scoring & eligibility engine
β βββ dataStore.ts # In-memory & JSON persistence store
β βββ emailService.ts # Nodemailer HTML digest generator
β βββ jobService.ts # Adzuna, Remotive, and Arbeitnow connectors
β βββ resumeAnalyzer.ts# Universal multidisciplinary resume parser
β βββ schedulerService.ts# node-cron daily automation service
β βββ verificationService.ts# SSRF-guarded link verification engine
βββ tests/
β βββ automatedTests.ts# 10 integration & unit test suites
β βββ runAllTests.ts # Automated test runner script
βββ utils/
βββ types.ts # Core TypeScript domain models & interfaces
Before running JobPulse AI locally, ensure you have the following installed:
v18.0.0 or higher (Tested on v20.x LTS and v24.21.0).v9.0.0 or higher (Tested on v11.19.0).Open Windows PowerShell and follow these copyable steps:
git clone https://github.com/Pratikshaprabhakarbande/JobPulseAI.git
cd JobPulseAI
cd server
Copy-Item .env.example .env
Open server/.env in your code editor and configure your preferences (see the Environment Configuration table below).
You can install dependencies across the entire workspace in one command, or per directory:
Option A β Workspace Root (Convenience Script):
# From the JobPulseAI root directory:
npm run install:all
Option B β Per Directory:
# Install backend dependencies
cd server
npm install
# Install frontend dependencies
cd ../client
npm install
Open two separate PowerShell terminal windows:
Terminal 1 β Backend Server:
cd server
npm run dev
(Or from root: npm run dev:server)
The backend server will start at http://localhost:5000.
Terminal 2 β Frontend Client:
cd client
npm run dev
(Or from root: npm run dev:client)
The Vite development server will start at http://localhost:5173.
Open your browser and navigate to http://localhost:5173.
All backend settings are controlled through server/.env. Below is a comprehensive table of all supported variables:
| Variable Name | Purpose | Required / Optional | Safe Example / Placeholder | Default Value |
|---|---|---|---|---|
PORT |
Backend HTTP server port | Optional | 5000 |
5000 |
CORS_ORIGIN |
Allowed client origin for CORS | Optional | http://localhost:5173 |
http://localhost:5173 |
DATA_DIR |
Directory path for local JSON store | Optional | ./data |
./data |
ADZUNA_APP_ID |
Adzuna Job Board API Application ID | Optional | your_adzuna_app_id |
"" |
ADZUNA_APP_KEY |
Adzuna Job Board API Secret Key | Optional | your_adzuna_app_key |
"" |
ADZUNA_COUNTRY |
Adzuna target country code | Optional | in |
in |
JOB_PROVIDER |
Preferred primary provider | Optional | adzuna or arbeitnow |
adzuna (if keys set) or arbeitnow |
DEMO_MODE |
Load 10 synthetic test jobs for evaluation | Optional | false or true |
false (live feeds only) |
AI_PROVIDER |
Candidate matching engine type | Optional | demo, gemini, or openai |
demo (built-in 5-factor scoring) |
AI_API_KEY |
External AI API Key (if using Gemini/OpenAI) | Optional | your_ai_key |
"" |
AI_MODEL |
External AI Model identifier | Optional | gpt-4o-mini |
gpt-4o-mini |
EMAIL_HOST |
SMTP server hostname | Optional | smtp.gmail.com |
smtp.gmail.com |
EMAIL_PORT |
SMTP port | Optional | 587 |
587 |
EMAIL_SECURE |
Use SSL for SMTP | Optional | false |
false |
EMAIL_USER |
SMTP username / sender email | Optional | user@gmail.com |
"" |
EMAIL_PASS |
SMTP 16-character App Password | Optional | xxxx xxxx xxxx xxxx |
"" |
EMAIL_FROM |
Display sender email | Optional | JobPulse AI <user@gmail.com> |
"" |
EMAIL_TO |
Default notification recipient | Optional | candidate@example.com |
"" |
SCHEDULER_ENABLED |
Enable daily background discovery | Optional | true |
true |
SCHEDULER_DAILY_TIME |
24-hour time for daily run (IST) | Optional | 09:00 |
09:00 |
SCHEDULER_TIMEZONE |
Timezone identifier for cron | Optional | Asia/Kolkata |
Asia/Kolkata |
[!TIP] Gmail SMTP Setup: To enable email alerts via Gmail, enable 2-Step Verification in your Google Account, visit Google App Passwords, create an app named βJobPulse AIβ, and paste the generated 16-character code into
EMAIL_PASS. Email alerts requireEMAIL_USER,EMAIL_PASS, andEMAIL_TOto be configured, and email alerts must be enabled in Settings.
Verified Active, Accessible), and India location pills.JobPulse AI operates on principles of transparency and evidence-based reporting. Users and reviewers should note:
LIKELY_OPEN and never falsely labeled as conclusively verified unless confirmed on an official ATS domain or with explicit application call-to-action elements.postedDateSource: 'unverified' and are explicitly excluded from strict 24-hour and 72-hour filters. They appear only when the filter is widened to 7 days or 14 days (maxAge > 72).VERIFICATION_BLOCKED rather than guessing their status.node-cron runs in-process inside the Express backend server. The backend process and host machine must remain running for scheduled daily runs to trigger. Deduplication tracks the last 100 notified IDs in settings.json to prevent repeated alerts during scheduled runs../data/ (jobs.json, matches.json, profile.json, resume.json, settings.json, scheduler_status.json) with an in-memory cache. It does not use a distributed cloud database, making it ideal for desktop or single-server deployment.For detailed request and response payloads, see docs/API.md.
| Method | Endpoint | Purpose | Required Inputs |
|---|---|---|---|
GET |
/api/health |
Health check & active provider status | None |
GET |
/api/dashboard/stats |
Aggregated metrics, profile status, and scheduler state | None |
POST |
/api/resume/upload |
Upload & parse resume document | multipart/form-data with resume file |
GET |
/api/resume |
Retrieve current resume file metadata | None |
GET |
/api/resume/profile |
Retrieve structured candidate profile | None |
PUT |
/api/resume/profile |
Edit candidate profile preferences & recalculate matches | JSON body with profile updates |
DELETE |
/api/resume |
Remove resume and candidate profile | None |
GET |
/api/jobs |
Retrieve vacancies with filter and sort controls | Optional query parameters (search, maxAge, verifiedOnly, etc.) |
GET |
/api/jobs/:id |
Retrieve specific job details & analysis | Job ID in path |
POST |
/api/jobs/:id/verify |
Execute on-demand live link verification | Job ID in path |
POST |
/api/jobs/:id/analyze |
Evaluate a single job against candidate profile | Job ID in path |
POST |
/api/jobs/analyze-all |
Evaluate all loaded jobs against candidate profile | None |
POST |
/api/jobs/refresh |
Ingest fresh vacancies from configured providers | None |
GET |
/api/settings |
Retrieve user alert & email settings | None |
PUT |
/api/settings |
Update alert preferences | JSON body with settings updates |
POST |
/api/settings/email/test |
Send test job digest email | Optional JSON body { email: string } |
GET |
/api/scheduler/status |
Check background cron scheduler state | None |
POST |
/api/scheduler/trigger |
Manually trigger full background automation cycle | None |
POST |
/api/scheduler/start |
Start or resume cron scheduler | None |
POST |
/api/scheduler/stop |
Pause cron scheduler | None |
JobPulse AI includes an automated unit and integration test suite covering resume parsing, multi-domain mapping, location restrictions, experience barriers, closed-vacancy handling, SSRF guards, and recency filters.
cd server
npm test
Verified Test Output:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
JOBPULSE AI β AUTOMATED QA & INTEGRATION SUITE
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
PASS: Resume Parser: Multi-domain mapping (Cybersecurity, EEE, Civil)
β
PASS: Matching: Relevant Bengaluru Cybersecurity Internship matches Cyber profile
β
PASS: Matching: Hardware / Embedded Intern matches EEE resume
β
PASS: Matching: Site Engineer Trainee matches Civil resume
β
PASS: Matching: Unrelated parcel delivery vacancy penalized heavily
β
PASS: Location: Germany onsite job flagged when candidate prefers India
β
PASS: Experience Barrier: Senior 5+ years role penalized for fresher candidate
β
PASS: Verification: Closed vacancy produces score of 0 and is marked ineligible
β
PASS: Security SSRF Guard: Blocks localhost, internal IPs and cloud metadata
β
PASS: Recency Filter: Distinguishes genuine 24h publication timestamps from old/unverified
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Total: 10 | Passed: 10 | Failed: 0
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
cd client
npm run build
Successfully transforms all modules, completes TypeScript compilation, and bundles production assets with exit code 0.
JobPulse AI implements defense-in-depth security measures across both frontend and backend:
verificationService.ts):
127.0.0.1, ::1), private RFC1918 subnets (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), link-local IPs (169.254.0.0/16), and cloud instance metadata endpoints (169.254.169.254, metadata.google.internal).resume.ts):
.pdf or .docx extensions by validating file header signatures.path.basename() and regex filters, storing files in isolated directories.index.ts):
X-Content-Type-Options: nosniff, X-Frame-Options: DENY, and Referrer-Policy: strict-origin-when-cross-origin.rateLimiter.ts):
.env and are never exposed to the frontend or checked into version control.PORT=5001 in server/.env and update the proxy target in client/vite.config.ts.5174).DEMO_MODE=false is set, but ADZUNA_APP_ID and ADZUNA_APP_KEY are empty.server/.env.EMAIL_HOST=smtp.gmail.com and EMAIL_PORT=587.EMAIL_PASS is a valid 16-character Google App Password (not your standard Google account login password).Planned enhancements for future releases include:
Contributions, bug reports, and suggestions are welcome! Please review CONTRIBUTING.md for branch naming conventions, development guidelines, and pull request procedures.
To report bugs or request features, open a GitHub Issue.
No explicit license has been declared yet. An appropriate open-source license (such as MIT or Apache-2.0) should be selected prior to public redistribution.
Developed with precision for authentic career discovery by @Pratikshaprabhakarbande.