Skip to content

lee777maker/Job-Applier

Repository files navigation

JobApplier AI 🤖

JobApplier AI Home

React Spring Boot Python FastAPI OpenAI Version Beta License: MIT

AI-Powered Job Application Assistant for South African Job Seekers
Automate your job search with intelligent resume tailoring, ATS optimization, live job listings, career coaching, job market insights and personalised cover letters.

Discord LinkedIn

--- *Note*: This project is proprietary. While the source code is public for portfolio evaluation, all commercial rights are reserved by the author. See LICENSE for details. ---

What Is This?

JobApplier AI is an end-to-end job application assistant that reduces the time you spend on repetitive job search tasks from hours to minutes. Upload your CV once, set your preferences, and let AI handle the tailoring, scoring, cover letter writing, and motivation scripting for every application.

Current status: Beta (v3) — core features working, some agents still in active development.


Key Features

Feature Description Status
Live Job Listings Real jobs from Indeed & LinkedIn, filtered to South Africa (last 30 days) ✅ Working
CV Intelligence Upload PDF/DOCX — AI auto-extracts skills, experience, education, and certifications ✅ Working
ATS Score Match score + missing keyword recommendations for any job posting 95% Complete
Cover Letter Generator Tailored cover letters in seconds from your profile + job description 80% Complete
CV Tailoring AI rewrites your CV to align with a specific job 90% Complete
AI Coach (Neilwe) Personal AI career coach for job search strategy 80% Complete
Dashboard Analytics Application tracking and match score history 40% Complete
Application Tracker Track applications with status, notes, and outcomes 30% Complete
Career Insights AI-powered personalised career news using live web search — hiring trends, salary insights, interview tips, in-demand skills tailored to your role, seniority, and location ✅ Working
Auto-Application Automatically submit applications on your behalf 📋 Planned
Mobile App React Native companion app 📋 Planned

'Status' is based on production level readiness. All features work in development phase apart from features with "Planned" status


Screenshots

Welcome Create Account CV Upload

Dashboard Job Preferences Profile

AI CV Optimization Cover Letter Email Generation


Architecture

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Frontend      │────▶│    Backend      │────▶│   AI Service    │
│   React 18      │◀────│  Spring Boot 3  │◀────│   FastAPI       │
│   :5173         │     │  :8080          │     │   :8001         │
└─────────────────┘     └────────┬────────┘     └─────────────────┘
                                 │
                    ┌────────────┼────────────┐
                    │            │            │
             ┌──────▼──┐  ┌─────▼─────┐  ┌──▼──────┐
             │ JobSpy  │  │PostgreSQL │  │  Redis  │
             │ :8002   │  │  :5432    │  │  :6379  │
             └─────────┘  └───────────┘  └─────────┘

Tech Stack

Layer Technology
Frontend React 18 + TypeScript + Vite + Tailwind CSS + shadcn/ui
Backend Spring Boot 3.2 + Java 21 + Spring Security (Argon2) + JPA/Hibernate
AI Service Python 3.11 + FastAPI + OpenAI GPT-5 + Sentence Transformers + PDFMiner
Job Scraping JobSpy (Indeed primary, LinkedIn backup) — South Africa focused
Career Insights OpenAI WebSearchTool — live web search for personalised career news (no third-party news API)
Database PostgreSQL 15 (production) / H2 (development)
Cache Redis 7 (session management)
Deployment Docker Compose

Future stack include Kubernetes for load management, Google Cloud Platform for cloud deployment, Cloudflare for security

Key System Behaviours

Personalised Career Insights (no news API)

The dashboard's Career Insights panel runs 4 concurrent web searches via OpenAI's WebSearchTool inside a FastAPI agent. Queries are generated from the user's profile:

  • Seniority — inferred from experience count + most recent job title (Executive / Senior / Mid-level / Junior / Graduate) ^
  • Career field — matched from role title and skills against 12 domains (Software Engineering, Finance, Marketing, etc.)
  • Location — from the user's saved preferences

Java's NewsController reads the profile from PostgreSQL, derives the context, and POSTs it to Python. Python runs the 4 searches concurrently (asyncio.gather) so total latency equals the cost of one search, not four. Results are deduplicated by URL and tagged with categories (Hiring Trends, In-Demand Skills, Interview Tips, Salary Insights).^

Profile-Based AI Match Scoring (homepage jobs)

Job cards on the homepage show AI-computed match scores from the match-score agent, not just keyword overlap from JobSpy. After the job list loads, the top 20 jobs are scored in parallel batches of 5 against the user's live profile. resume_text is synthesised from the profile if no CV has been uploaded — meaning scores update dynamically whenever the user updates their profile.

DB-Aware Agent Chat (AgentController)

Neilwe's chat is routed through AgentController.java, which:

  1. Fetches the user's full profile fresh from PostgreSQL on every message
  2. Fetches all applications from the DB
  3. Forwards both to Python with the backend's own base URL
  4. Gives the Python agent function tools to POST/PUT/DELETE back to Java endpoints for live DB writes (adding applications, updating status, etc.)

This ensures the agent always has current data, not stale frontend state.

^ Subject to future improvement

Quick Start

Prerequisites

  • Docker & Docker Compose (recommended)
    OR: Java 21 + Maven, Python 3.11, Node.js 18+, OpenAI API key

Docker (Easiest)

# 1. Clone
git clone https://github.com/yourusername/jobapplier-ai.git
cd jobapplier-ai

# 2. Set environment variables
cp .env.example .env
# Edit .env with your values:
#   OPENAI_API_KEY=sk-your-key-here
#   DB_PASSWORD=yourpassword
#   JWT_SECRET=yoursecret

# 3. Start all services
docker-compose up --build

# 4. Open the app
open http://localhost:5173

Access Points

Service URL
Frontend http://localhost:5173
Backend API http://localhost:8080
AI Service http://localhost:8001
JobSpy http://localhost:8002

API Reference

AI Service (:8001)

Endpoint Method Description
/agents/neilwe-chat POST Chat with AI career coach
/agents/match-score POST Calculate ATS match score
/agents/tailor-resume POST Tailor resume for job posting
/agents/generate-cover-letter POST Generate personalised cover letter
/agents/generate-email POST Generate outreach email
/agents/extract-cv POST Parse and extract CV data (PDF/DOCX)
/agents/autofill POST Autofill from CV text
/agents/extract-job-titles POST Extract job titles from CV
/agents/career-insights POST Personalised career news via live web search (4 concurrent queries: hiring trends, skills, interview tips, salary)
/health GET Health check

JobSpy Service (:8002)

Endpoint Method Description
/search POST Search Indeed/LinkedIn jobs
/search-by-profile POST Search using full user profile
/health GET Health check

Backend (:8080)

Endpoint Method Description
/api/auth/register POST Register new user
/api/auth/login POST Login
/api/profile/{userId} GET/PUT User profile management
/api/jobs/recommendations/{userId} GET Personalised job recommendations
/api/jobs/search-by-profile POST Search jobs by profile
/api/applications POST Create application
/api/applications/user/{userId} GET Get user applications
/api/dashboard/** Various Dashboard analytics
/api/ai/** Various Proxy to AI service
/api/agent/chat POST DB-aware AI agent chat (AgentController fetches fresh profile + applications, forwards to Python with function tools for live DB writes)
/api/agent/context/{userId} GET Debug: view exact context the agent receives
/api/news/career-resources GET Personalised career insights — fetches profile from DB, calls Python /agents/career-insights

Configuration

Copy .env.example and fill in your values:

OPENAI_API_KEY=sk-your-key-here
DB_PASSWORD=your-postgres-password
JWT_SECRET=your-jwt-secret-key
AI_SERVICE_URL=http://ai-service:8001        # default
JOBSPY_SERVICE_URL=http://jobspy-service:8002 # default
CORS_ALLOWED_ORIGINS=http://localhost:5173    # add production domain

To switch to PostgreSQL for local dev, set:

SPRING_PROFILES_ACTIVE=prod

Testing

# AI Service
cd ai-service && pytest tests/

# Backend
cd backend && ./mvnw test

# Frontend
cd frontend && npm test

# Manual: Test job scraper
curl -X POST http://localhost:8002/search \
  -H "Content-Type: application/json" \
  -d '{"keyword":"software engineer","location":"Johannesburg","max_results":5,"days_old":30}'

Project Structure

jobapplier-ai/
├── frontend/                 # React + TypeScript + Vite
│   ├── src/
│   │   ├── components/       # UI components (shadcn/ui)
│   │   ├── context/          # React context (AppContext)
│   │   ├── lib/              # API clients, utilities
│   │   ├── pages/            # Page components
│   │   └── types/            # TypeScript types
│   └── package.json
|   └── Dockerfile
├── backend/                  # Spring Boot 3.2
│   ├── src/main/java/
│   │   └── jobapplier/
│   │       ├── api/          # REST controllers
│   │       ├── config/       # Security, App config
│   │       ├── model/        # JPA entities
│   │       ├── repository/   # Spring Data JPA
│   │       └── service/      # Business logic
│   └── pom.xml
|   └── Dockerfile
├── ai-service/               # Python FastAPI
│   ├── app.py                # Main FastAPI app
│   ├── requirements.txt
│   └── Dockerfile
├── jobspy-service/           # Job scraping service
│   ├── jobspy_service.py
│   ├── requirements.txt
│   └── Dockerfile
├── docs/                     # Documentation
│   ├── Architecture-Overview.md
│   ├── Product-Specification.md
│   ├── Testing-Strategy.md
│   └── Design-Decisions.md
├── docker-compose.yml
└── README.md

Roadmap

  • User authentication & profiles
  • CV upload & AI extraction
  • ATS match scoring
  • Cover letter generation
  • Live job listings (Indeed)
  • Resume tailoring
  • AI Coach (Neilwe)
  • Application tracking
  • Dashboard analytics
  • Career insights (AI-powered, profile-personalised, live web search)
  • LinkedIn job integration
  • Email notifications
  • Interview preparation module
  • Automated application submission
  • Mobile app (React Native)
  • POPIA compliance audit

Documentation


Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Commit your changes: git commit -m 'Add your feature'
  4. Push to the branch: git push origin feature/your-feature
  5. Open a Pull Request

Please read CONTRIBUTING.md for more details.


License

MIT License — see LICENSE for details.


Acknowledgments


Made with ❤️ for job seekers everywhere · Join the community

About

This is automated Job Application System using AI

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors