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.
- ποΈ 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
| 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 |
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)
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
Represents application users.
- userId
- userName
- userEmail
- role
- skillsRequired
Represents companies posting jobs.
- companyId
- companyName
- companyIndustry
- companyRating
Represents job vacancies.
- postId
- postTitle
- postDescription
- postSalary
- createdAt
- jobStatus
- skillsRequired
- companyId
- Automatically assigns ACTIVE status for new job posts.
- Automatically expires old posts.
Represents user applications.
- jobApplicationId
- resumeUrl
- matchScore
- applicationStatus
- appliedAt
- userId
- jobPostId
- companyId
- Automatically sets default status to PENDING.
- Calculates skill matching score.
ADMIN
USER
COMPANY_RECRUITERACTIVE
EXPIRED
CLOSEDPENDING
SELECTED
REJECTED- JobApplication β User
- JobApplication β JobPost
- JobPost β Company
- User β Role
- User skills
- Job post required skills
The project uses MapStruct for:
- DTO to Domain mapping
- Domain to Entity mapping
- Entity to Domain mapping
- Aggregate response mapping
- Update entity mapping
- Persistence Mappers
- Web Mappers
- Aggregate Mappers
The project uses a custom @Authorize annotation.
@Authorize(RoleName.ADMIN)- ADMIN
- USER
- COMPANY_RECRUITER
A custom interceptor validates:
- User availability
- User roles
- Access permissions
- Request headers
X-User-IdThe project includes a custom request rate limiter.
- User-based request tracking
- Role-based request limits
- Automatic request count reset every minute
- ConcurrentHashMap for thread-safe tracking
@Scheduled(cron = "0 * * * * *")Automatically changes old ACTIVE job posts into EXPIRED status.
The application fetches external jobs from:
https://www.themuse.com/api/public
- Fetch external job listings
- Convert external jobs into domain models
- Aggregate local and external job recommendations
The project uses CompletableFuture for asynchronous processing.
- Fetching local job recommendations
- Fetching external API recommendations
- Combining multiple recommendation sources
The recommendation engine:
- Reads user skills
- Finds matching job skills
- Calculates matching score
- Returns recommended jobs
(matchCount / requiredSkills) * 100
The project uses Hibernate Soft Delete.
@SoftDelete(columnName = "is_deleted")Used in:
- UserEntity
- CompanyEntity
- JobPostEntity
- JobApplicationEntity
The project uses Jakarta Validation.
- @NotBlank
- @NotNull
- @NotEmpty
Custom exception handling is implemented using:
@RestControllerAdvice- BadRequestException -> 400
- UnauthorizedException -> 401
- ConflictException -> 409
- ForbiddenException -> 403
- ResourceNotFoundException -> 404
- Generic Exception β 500
All API responses follow a common structure.
{
"status": 200,
"message": "Success",
"timestamp": "2026-01-01T10:00:00",
"data": {}
}| 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 |
| 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 |
| 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 |
| 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 UI is enabled using SpringDoc OpenAPI.
/swagger-ui.html
/v3/api-docs
- 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
Developed as a Clean Architecture practice project focusing on:
- Real-world backend structure
- Scalable system design
- Separation of concerns
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