Skip to content

Latest commit

Β 

History

281 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Smart Job Aggregator API

πŸ“Œ Overview

Smart Job Aggregator is a backend REST API project built using Java and Spring Boot. The system manages users, companies, job posts, and job applications while also providing job recommendations based on user skills.

The project follows a layered and modular architecture with separate:

  • 🧠 Domain Layer
  • βš™οΈ Infrastructure Layer
  • πŸ› οΈ Use Case Layer
  • 🌐 Web Layer

The application also integrates with an external jobs API to aggregate job recommendations from multiple sources.


✨ Features

πŸ”₯ Core Features

  • πŸ›οΈ Clean-Architecture
  • πŸ‘€ User management
  • 🏒 Company management
  • πŸ’Ό Job post management
  • πŸ“„ Job application management
  • 🎯 Skill-based job recommendation system
  • 🌍 Multi-source job recommendations (Multi treading handle)
  • πŸ” Role-based authorization
  • 🚦 Request rate limiting
  • ⏰ Scheduled background tasks
  • ❌ Global exception handling
  • πŸ“¦ Standardized API responses
  • πŸ—‘οΈ Soft delete support
  • πŸ”— External API integration

🧰 Technologies Used

Technology Purpose
Java 21 Main programming language
Spring Boot 4 Backend framework
Spring Data JPA ORM and database operations
PostgreSQL Relational database
Spring Validation Request validation
Spring Security Security configuration
MapStruct Object mapping
Lombok Reduce boilerplate code
Spring Modulith Modular architecture support
Spring Web MVC REST API development
Spring WebFlux Reactive support
Spring RestClient External API communication
Swagger / OpenAPI API documentation
Hibernate ORM provider
Gradle Build tool
H2 Console Development/testing support

🧱 Project Architecture

πŸ›οΈ Clean Architecture

The project follows Clean Architecture principles.

               🌐 Web Layer
          (Controllers, DTOs, APIs)
                     ↓
             πŸ› οΈ Use Case Layer
          (Business Application Logic)
                     ↓
              🧠 Domain Layer
          (Core Business Rules & Models)
                     ↑
           βš™οΈ Infrastructure Layer
     (Database, External APIs, Persistence)

πŸ“‚ Project Structure


This project is built using **Clean Architecture** and **Domain-Driven Design (DDD)**. Each layer has a strict responsibility to ensure the business logic remains decoupled from external frameworks.

lk.job_finder_app.smart_job_aggregator
β”œβ”€β”€ πŸ“ domain                                        @Core Business Logic & Enterprise Rules
β”‚   β”œβ”€β”€ πŸ“ models                                    @Pure Domain Entities & Aggregates
β”‚   β”‚   β”œβ”€β”€ πŸ“ enums                                 @Domain Constants (Status & Roles)
β”‚   β”‚   β”‚   β”œβ”€β”€ ApplicationStatus.java
β”‚   β”‚   β”‚   β”œβ”€β”€ JobStatus.java
β”‚   β”‚   β”‚   └── RoleName.java
β”‚   β”‚   β”œβ”€β”€ Company.java                             # Company Domain Model
β”‚   β”‚   β”œβ”€β”€ JobApplication.java                      # Job Application Domain Model
β”‚   β”‚   β”œβ”€β”€ JobApplicationAggregate.java             # Combined Application & Job data
β”‚   β”‚   β”œβ”€β”€ JobPost.java                             # Job Post Domain Model
β”‚   β”‚   β”œβ”€β”€ JobPostWithCompanyAggregate.java         # Job Post with Company details
β”‚   β”‚   β”œβ”€β”€ Role.java                                # User Role Domain Model
β”‚   β”‚   └── User.java                                # User Domain Model (contains matching logic)
β”‚   └── πŸ“ repositories                              @Domain Repository Interfaces (Outbound Ports)
β”‚       β”œβ”€β”€ CompanyRepository.java
β”‚       β”œβ”€β”€ JobApplicationRepository.java
β”‚       β”œβ”€β”€ JobPostRepository.java
β”‚       └── UserRepository.java
β”‚
β”œβ”€β”€ πŸ“ usecase                                       @Application Specific Business Rules
β”‚   β”œβ”€β”€ πŸ“ company                                   @Inbound Port for Company Operations
β”‚   β”‚   β”œβ”€β”€ CompanyUseCase.java                      # Feature Interface
β”‚   β”‚   └── CompanyUseCaseImpl.java                  # Coordination of Domain & Repo
β”‚   β”œβ”€β”€ πŸ“ jobApplication                            @Application Lifecycle Logic
β”‚   β”‚   β”œβ”€β”€ JobApplicationUseCase.java
β”‚   β”‚   └── JobApplicationUseCaseImpl.java
β”‚   β”œβ”€β”€ πŸ“ jobPost                                   @Job Aggregation Logic (Local + External)
β”‚   β”‚   β”œβ”€β”€ JobPostUseCase.java
β”‚   β”‚   └── JobPostUseCaseImpl.java
β”‚   └── πŸ“ user                                      @User & Recommendation Workflows
β”‚       β”œβ”€β”€ UserUseCase.java
β”‚       └── UserUseCaseImpl.java
β”‚
β”œβ”€β”€ πŸ“ infrastructure                                @External Frameworks, Tools & Adapters
β”‚   β”œβ”€β”€ πŸ“ external_api                              @Integration with Third-Party Services
β”‚   β”‚   └── πŸ“ museAPI                               @The Muse API Integration
β”‚   β”‚       β”œβ”€β”€ πŸ“ client                            # RestClient Implementation
β”‚   β”‚       β”‚   └── TheMuseClient.java
β”‚   β”‚       β”œβ”€β”€ πŸ“ DTOs                              # External API Data Contracts
β”‚   β”‚       β”‚   └── ExternalJobResponseDTO.java
β”‚   β”‚       └── πŸ“ mappers                           # External DTO -> Domain Mapper
β”‚   β”‚           └── ExternalJobMapper.java
β”‚   β”œβ”€β”€ πŸ“ [module] (e.g., jobPost, user, company)   @Infrastructure Implementation per Module
β”‚   β”‚   β”œβ”€β”€ πŸ“ config                                # Bean Definition (DI Configuration)
β”‚   β”‚   β”‚   β”œβ”€β”€ [Module]PersistenceBeanConfig.java
β”‚   β”‚   β”‚   └── [Module]UseCaseBeanConfig.java
β”‚   β”‚   └── πŸ“ persistence                           # Database Layer (PostgreSQL/H2)
β”‚   β”‚       β”œβ”€β”€ πŸ“ entity                            # JPA @Entity Definitions
β”‚   β”‚       β”‚   └── [Module]Entity.java
β”‚   β”‚       β”œβ”€β”€ πŸ“ jpa                               # Spring Data JPA Interfaces
β”‚   β”‚       β”‚   └── Jpa[Module]Repository.java
β”‚   β”‚       β”œβ”€β”€ πŸ“ mapper                            # Domain <-> Entity Mapping (MapStruct)
β”‚   β”‚       β”‚   └── [Module]PersistenceMapper.java
β”‚   β”‚       └── [Module]RepositoryImpl.java          # Adapter connecting Domain to JPA
β”‚   └── πŸ“ role                                      # Persistence for Security Roles
β”‚
β”œβ”€β”€ πŸ“ web                                           @Entry Points & Delivery (UI/API)
β”‚   β”œβ”€β”€ πŸ“ [module] (e.g., jobPost, company, user)
β”‚   β”‚   β”œβ”€β”€ πŸ“ controllers                           # REST API Endpoints (@RestController)
β”‚   β”‚   β”œβ”€β”€ πŸ“ DTOs                                  # API Request/Response JSON structures
β”‚   β”‚   β”‚   β”œβ”€β”€ [Module]RequestDTO.java
β”‚   β”‚   β”‚   └── [Module]ResponseDTO.java
β”‚   β”‚   └── πŸ“ webMappers                            # Web DTO <-> Domain Mapping
β”‚   β”‚       └── [Module]WebMapper.java
β”‚   β”œβ”€β”€ πŸ“ security                                  @Custom Security Interceptors
β”‚   β”‚   β”œβ”€β”€ Authorize.java                           # Custom Authorization Annotation
β”‚   β”‚   └── SecurityInterceptor.java                 # RBAC Enforcement logic
β”‚   └── πŸ“ user
β”‚       β”œβ”€β”€ πŸ“ Config                                # MVC Interceptor Registration
β”‚       β”‚   └── WebConfig.java
β”‚       └── πŸ“ interceptor                            # API Protection logic
β”‚           └── RateLimitInterceptor.java            # Role-aware Request Throttling
β”‚
β”œβ”€β”€ πŸ“ globalExceptionHandler                        @Centralized Exception Management
β”‚   β”œβ”€β”€ πŸ“ superClasses                              # Custom Exception Types
β”‚   β”‚   β”œβ”€β”€ BadRequestException.java
β”‚   β”‚   β”œβ”€β”€ ResourceNotFoundException.java
β”‚   β”‚   └── ... (Unauthorized, Forbidden, Conflict)
β”‚   β”œβ”€β”€ ErrorMessage.java                            # Standardized Error Response Body
β”‚   └── GlobalExceptionHandler.java                  # @RestControllerAdvice for the App
β”‚
β”œβ”€β”€ πŸ“ globalResponseHandler                         @Generic Response Wrapping
β”‚   └── StandardResponse.java                        # Unified Success/Failure Envelope
β”‚
β”œβ”€β”€ πŸ“ spring_security_config                        @Security & Authentication Setup
β”‚   └── SecurityConfig.java                          # Stateless Auth & Filter Chain
β”‚
└── SmartJobAggregatorApplication.java               @Spring Boot Main Class


🧠 Domain Models

πŸ‘€ User

Represents application users.

Fields

  • userId
  • userName
  • userEmail
  • role
  • skillsRequired

🏒 Company

Represents companies posting jobs.

Fields

  • companyId
  • companyName
  • companyIndustry
  • companyRating

πŸ’Ό JobPost

Represents job vacancies.

Fields

  • postId
  • postTitle
  • postDescription
  • postSalary
  • createdAt
  • jobStatus
  • skillsRequired
  • companyId

βš™οΈ Business Logic

  • Automatically assigns ACTIVE status for new job posts.
  • Automatically expires old posts.

πŸ“„ JobApplication

Represents user applications.

Fields

  • jobApplicationId
  • resumeUrl
  • matchScore
  • applicationStatus
  • appliedAt
  • userId
  • jobPostId
  • companyId

βš™οΈ Business Logic

  • Automatically sets default status to PENDING.
  • Calculates skill matching score.

🏷️ Enums

πŸ‘₯ RoleName

ADMIN
USER
COMPANY_RECRUITER

πŸ“Œ JobStatus

ACTIVE
EXPIRED
CLOSED

πŸ“„ ApplicationStatus

PENDING
SELECTED
REJECTED

πŸ—„οΈ Database Features


πŸ”— JPA Relationships


Many-to-One Relationships

  • JobApplication β†’ User
  • JobApplication β†’ JobPost
  • JobPost β†’ Company
  • User β†’ Role

πŸ“š Element Collections

  • User skills
  • Job post required skills

πŸ”„ Object Mapping

The project uses MapStruct for:

  • DTO to Domain mapping
  • Domain to Entity mapping
  • Entity to Domain mapping
  • Aggregate response mapping
  • Update entity mapping

🧩 Mapper Types

  • Persistence Mappers
  • Web Mappers
  • Aggregate Mappers

πŸ” Security System

πŸ›‘οΈ Custom Authorization

The project uses a custom @Authorize annotation.

@Authorize(RoleName.ADMIN)

πŸ‘₯ Supported Roles

  • ADMIN
  • USER
  • COMPANY_RECRUITER

🚨 Security Interceptor

A custom interceptor validates:

  • User availability
  • User roles
  • Access permissions
  • Request headers

πŸ“¨ Required Header

X-User-Id

🚦 Rate Limiting

The project includes a custom request rate limiter.

✨ Features

  • User-based request tracking
  • Role-based request limits
  • Automatic request count reset every minute
  • ConcurrentHashMap for thread-safe tracking

⏰ Scheduled Tasks

🧹 Automatic Job Expiration

@Scheduled(cron = "0 * * * * *")

Automatically changes old ACTIVE job posts into EXPIRED status.


🌍 External API Integration

🎯 The Muse API

The application fetches external jobs from:

https://www.themuse.com/api/public

✨ Features

  • Fetch external job listings
  • Convert external jobs into domain models
  • Aggregate local and external job recommendations

⚑ Multi-Threading

The project uses CompletableFuture for asynchronous processing.

🧡 Used For

  • Fetching local job recommendations
  • Fetching external API recommendations
  • Combining multiple recommendation sources

🎯 Job Recommendation System

🧠 Skill Matching

The recommendation engine:

  1. Reads user skills
  2. Finds matching job skills
  3. Calculates matching score
  4. Returns recommended jobs

πŸ“Š Matching Score Formula

(matchCount / requiredSkills) * 100

πŸ—‘οΈ Soft Delete

The project uses Hibernate Soft Delete.

@SoftDelete(columnName = "is_deleted")

Used in:

  • UserEntity
  • CompanyEntity
  • JobPostEntity
  • JobApplicationEntity

βœ… Validation

The project uses Jakarta Validation.

πŸ“‹ Common Validations

  • @NotBlank
  • @NotNull
  • @NotEmpty
  • @Email

❌ Global Exception Handling

Custom exception handling is implemented using:

@RestControllerAdvice

🚨 Custom Exceptions

- BadRequestException -> 400
- UnauthorizedException -> 401
- ConflictException -> 409
- ForbiddenException -> 403
- ResourceNotFoundException -> 404
- Generic Exception β†’ 500

πŸ“¦ Standard API Response

All API responses follow a common structure.

{
  "status": 200,
  "message": "Success",
  "timestamp": "2026-01-01T10:00:00",
  "data": {}
}

🌐 REST API Endpoints

🏒 Company Endpoints

Method Endpoint Description
GET /api/v1/company/ Get all companies
POST /api/v1/company/ Create company
PUT /api/v1/company/{companyId} Update company
DELETE /api/v1/company/{companyId} Delete company

πŸ‘€ User Endpoints

Method Endpoint Description
GET /api/v1/user/ Get all users
GET /api/v1/user/recommendations/{userId} Recommended jobs
GET /api/v1/user/recommendations/multi-source/{userId} Multisources Recommended jobs
POST /api/v1/user/ Create user
PUT /api/v1/user/{userId} Update user
DELETE /api/v1/user/{userId} Delete user

πŸ’Ό Job Post Endpoints

Method Endpoint Description
GET /api/v1/job-post/ Get all job posts
POST /api/v1/job-post/ Create job post
PUT /api/v1/job-post/{postId} Update job post
DELETE /api/v1/job-post/{postId} Delete job post

πŸ“„ Job Application Endpoints

Method Endpoint Description
GET /api/v1/job-application/ Get all applications
POST /api/v1/job-application/apply Apply for a job
PUT /api/v1/job-application/{jobApplicationId} Update application

πŸ“˜ Swagger Documentation

Swagger UI is enabled using SpringDoc OpenAPI.

πŸ”— Swagger Endpoints

/swagger-ui.html
/v3/api-docs

πŸ“š Key Concepts Implemented

πŸ› οΈ Backend Concepts

  • REST API Development
  • Layered Architecture
  • Clean Architecture
  • Repository Pattern
  • DTO Pattern
  • Dependency Injection
  • Custom Interceptors
  • Exception Handling
  • Scheduling
  • Asynchronous Processing
  • External API Integration
  • Role-Based Access Control
  • Rate Limiting
  • Object Mapping
  • Modular Monolith Architecture

πŸ‘¨β€πŸ’» Author

Developed as a Clean Architecture practice project focusing on:

  • Real-world backend structure
  • Scalable system design
  • Separation of concerns

⭐ Project Purpose

This project was built to practice:

  • Clean Architecture
  • Spring Boot advanced structuring
  • DTO & mapping strategies
  • Business rule implementation
  • API design best practices
  • Multithreaded usage in multiple resources usage
  • Rich Domain Models
  • Stander Error Response

About

Smart Job Aggregator is a backend REST API project built using Java and Spring Boot. The system manages users, companies, job posts, and job applications while also providing job recommendations based on user skills.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages