Skip to content

vikas9013/EmployeePayrollSystem

Repository files navigation

🧾 Employee Payroll System

Java Spring Boot PostgreSQL Redis Docker License

A production-ready Spring Boot backend that manages employee payroll for full-time and part-time employees β€” with a fully AI-Powered Onboarding Pipeline that automates email creation, Slack invites, training assignments, payroll configuration, and generates a personalized welcome message using Groq (LLaMA 3.3) whenever a new employee is hired.

πŸ’‘ Handles complete employee lifecycle β€” from onboarding to payroll β€” with automation, security, and scalability in mind. πŸš€ Designed as a production-level backend system, not just a CRUD API.


🌐 Live Demo

πŸ”— Swagger UI: https://employeepayroll-app.onrender.com/swagger-ui.html

πŸ”— Health Check: https://employeepayroll-app.onrender.com/actuator/health

⚠️ Hosted on Render free tier β€” may take 50 seconds to wake up on first request. Please wait and retry if it doesn't load immediately.

Test credentials:

Username Password Role
admin admin123 ROLE_ADMIN
hr hr123 ROLE_HR

⚑ Quick Overview

  • πŸ” JWT Authentication + Role-Based Access Control (RBAC)
  • πŸ€– AI-powered onboarding via Groq LLaMA 3.3 70B
  • ⚑ Redis caching with smart eviction strategy
  • 🧱 Flyway database migrations (version-controlled schema)
  • πŸ›‘οΈ Rate limiting with Bucket4j (prevents AI API abuse)
  • πŸ“Š Prometheus metrics + Spring Actuator health checks
  • πŸ—‘οΈ Soft-delete (no permanent data loss)
  • 🐳 Fully Dockerized (PostgreSQL + Redis + App)
  • πŸ§ͺ Unit + Integration testing with Testcontainers + JaCoCo

🎯 Real-World Use Case

This project simulates an internal HR system used by companies to:

  • Automate employee onboarding workflows end-to-end
  • Reduce manual HR operations with a 5-step pipeline
  • Ensure consistent payroll configuration for all employee types
  • Improve new employee experience using AI-generated welcome messages

πŸ—οΈ System Architecture

Client (Swagger UI / curl / Postman)
         β”‚
         β–Ό
  Spring Security (JWT Filter)
         β”‚
         β–Ό
   REST Controllers
         β”‚
         β”œβ”€β”€β†’ Redis Cache (GET by ID)
         β”‚
         β”œβ”€β”€β†’ Service Layer
         β”‚         β”‚
         β”‚         β”œβ”€β”€β†’ PostgreSQL (via JPA + Flyway)
         β”‚         β”‚
         β”‚         └──→ Onboarding Pipeline
         β”‚                   β”‚
         β”‚                   β”œβ”€β”€β†’ Email Service
         β”‚                   β”œβ”€β”€β†’ Slack Service
         β”‚                   β”œβ”€β”€β†’ Training Service
         β”‚                   β”œβ”€β”€β†’ Payroll Setup Service
         β”‚                   └──→ Groq AI API (WebClient)
         β”‚
         β–Ό
    JSON Response (DTO)

Note: This is a modular monolith designed with microservice principles.


πŸš€ Tech Stack

Category Technology Details
Backend Java 21, Spring Boot 3.3.4 Core framework
Security Spring Security + JJWT 0.12.6 JWT stateless auth
Database PostgreSQL + Spring Data JPA Hibernate ORM
Migrations Flyway Version-controlled schema
Caching Redis + Spring Cache Response caching
AI Groq API (LLaMA 3.3 70B) Welcome message generation
HTTP Client Spring WebFlux WebClient Async AI API calls
Rate Limiting Bucket4j 10 req/min on onboard
Observability Spring Actuator + Micrometer + Prometheus Health + metrics
API Docs SpringDoc OpenAPI (Swagger UI) Interactive docs
Mapping MapStruct DTO mapping
Boilerplate Lombok Clean code
Testing JUnit + Mockito + Testcontainers + JaCoCo Full test suite
Build Maven Dependency management
Deployment Docker + Docker Compose + Render One-command setup

🧠 OOP Concepts Demonstrated

Concept How It's Used
Abstraction Employee is an abstract class with abstract calculateSalary() method
Inheritance FullTimeEmployee and PartTimeEmployee extend Employee
Polymorphism Each subclass overrides calculateSalary() with its own logic
Encapsulation All fields are private with public getters/setters via Lombok

πŸ” Security & Roles

The entire API is secured with JWT (JSON Web Token) stateless authentication and role-based access control.

Roles & Permissions

Role Permissions
ROLE_ADMIN Full access β€” GET, POST, PUT, DELETE
ROLE_HR Read-only access β€” GET endpoints only

Default Users (auto-created on first startup by DataSeeder)

Username Password Role
admin admin123 ROLE_ADMIN
hr hr123 ROLE_HR

⚠️ Change these passwords immediately before going to production!

How Authentication Works

  1. Call POST /api/auth/login with your credentials
  2. Receive a signed JWT token in the response
  3. Pass the token as Authorization: Bearer <token> on every subsequent request
  4. Tokens are fully stateless β€” no sessions stored on the server

πŸ“ Project Structure

src/
└── main/java/com/vikas/
    β”œβ”€β”€ PayrollApplication.java
    β”œβ”€β”€ config/
    β”‚   β”œβ”€β”€ SecurityConfig.java              # JWT auth, CORS, role-based route protection
    β”‚   β”œβ”€β”€ SwaggerConfig.java               # Swagger UI + Bearer auth configuration
    β”‚   └── DataSeeder.java                  # Seeds default admin & HR users on startup
    β”œβ”€β”€ controller/
    β”‚   β”œβ”€β”€ AuthController.java              # POST /api/auth/login
    β”‚   └── EmployeeController.java          # Employee CRUD + onboarding (rate limited)
    β”œβ”€β”€ service/
    β”‚   β”œβ”€β”€ AuthService.java                 # Login β€” verifies credentials, issues JWT
    β”‚   β”œβ”€β”€ EmployeeService.java             # Core CRUD + Redis caching + soft-delete
    β”‚   β”œβ”€β”€ OnboardingService.java           # Orchestrates the 5-step onboarding pipeline
    β”‚   β”œβ”€β”€ AIOnboardingService.java         # AI welcome message via Groq API
    β”‚   β”œβ”€β”€ EmailService.java                # Generates work email address
    β”‚   β”œβ”€β”€ SlackService.java                # Sends Slack workspace invite
    β”‚   β”œβ”€β”€ TrainingService.java             # Assigns training modules by designation
    β”‚   └── PayrollSetupService.java         # Configures payroll (FULLTIME or PARTTIME)
    β”œβ”€β”€ entity/
    β”‚   β”œβ”€β”€ Employee.java                    # Abstract base β€” soft-delete, audit timestamps
    β”‚   β”œβ”€β”€ FullTimeEmployee.java            # monthlySalary field
    β”‚   β”œβ”€β”€ PartTimeEmployee.java            # hoursWorked + hourlyRate fields
    β”‚   └── User.java                        # Login credentials (BCrypt hashed)
    β”œβ”€β”€ security/
    β”‚   β”œβ”€β”€ JwtUtil.java                     # Token generation & validation
    β”‚   └── JwtAuthFilter.java               # Per-request JWT filter
    β”œβ”€β”€ repository/
    β”‚   β”œβ”€β”€ EmployeeRepository.java
    β”‚   └── UserRepository.java
    β”œβ”€β”€ dto/
    β”‚   β”œβ”€β”€ EmployeeRequestDTO.java
    β”‚   β”œβ”€β”€ EmployeeResponseDTO.java
    β”‚   β”œβ”€β”€ SalaryResponseDTO.java
    β”‚   β”œβ”€β”€ OnboardingResponseDTO.java
    β”‚   β”œβ”€β”€ LoginRequestDTO.java
    β”‚   └── LoginResponseDTO.java
    β”œβ”€β”€ enums/
    β”‚   └── EmployeeType.java                # FULLTIME | PARTTIME
    β”œβ”€β”€ exception/
    β”‚   β”œβ”€β”€ EmployeeNotFoundException.java
    β”‚   └── OnboardingException.java
    └── ExceptionHandler/
        └── GlobalExceptionHandler.java      # Handles 400, 401, 403, 404, 429, 500

πŸ—„οΈ Database Schema (Flyway Managed)

Schema is version-controlled via V1__init_schema.sql and applied automatically on startup β€” no manual SQL needed.

Table Contents
employees id, name, designation, deleted_at (soft-delete), created_at, updated_at
fulltime_employees monthly_salary
parttime_employees hours_worked, hourly_rate
users username, BCrypt-hashed password, role
audit_log entity_type, action, changed_by, old_value, new_value, changed_at

Records are never physically deleted. DELETE sets the deleted_at timestamp (soft-delete).


☁️ Deployed on Render

The app is live on Render (free tier) with PostgreSQL as the database.

Required Environment Variables

Key Description
spring.datasource.url PostgreSQL connection URL
spring.datasource.username Database username
spring.datasource.password Database password
jwt.secret Random string, minimum 32 characters
jwt.expiration-ms Token expiry in ms (e.g. 86400000 = 24 hours)
groq.api.key Groq API key from console.groq.com
spring.cache.type Set to none on free tier (no Redis available)
management.health.redis.enabled Set to false on free tier

⚠️ Free tier instances spin down after inactivity β€” first request may take 50+ seconds.


βš™οΈ Local Setup & Configuration

Prerequisites

  • Java 21+
  • Maven
  • PostgreSQL running locally
  • Redis running locally
  • Groq API Key β€” free at console.groq.com

1. Clone the repository

git clone https://github.com/vikas9013/EmployeePayrollSystem.git
cd EmployeePayrollSystem

2. Create the database

CREATE DATABASE payrolldb;

3. Configure credentials

Set these environment variables:

Variable Description
DB_USERNAME Your PostgreSQL username
DB_PASSWORD Your PostgreSQL password
GROQ_API_KEY Your Groq API key from console.groq.com
JWT_SECRET A random string, minimum 32 characters

Windows CMD:

set DB_USERNAME=postgres
set DB_PASSWORD=yourpassword
set GROQ_API_KEY=gsk_your_key_here
set JWT_SECRET=ThisIsASecretKeyThatMustBe32CharsLong!!

Mac/Linux:

export DB_USERNAME=postgres
export DB_PASSWORD=yourpassword
export GROQ_API_KEY=gsk_your_key_here
export JWT_SECRET=ThisIsASecretKeyThatMustBe32CharsLong!!

4. Run the application

mvn spring-boot:run

App starts at: http://localhost:8080

Flyway automatically creates all tables on first startup. No manual SQL needed.


🐳 Docker Deployment

Run the full stack β€” App + PostgreSQL + Redis β€” with a single command:

docker-compose up --build
Service Port
App 8080
PostgreSQL 5432
Redis 6379
# Stop all services
docker-compose down

# Stop and wipe the database
docker-compose down -v

Replace placeholder credentials in docker-compose.yml before deploying to any environment.


πŸ“– Swagger UI

Interactive API documentation β€” test every endpoint directly in the browser.

URL Description
https://employeepayroll-app.onrender.com/swagger-ui.html Live Swagger UI
https://employeepayroll-app.onrender.com/v3/api-docs Live OpenAPI JSON
http://localhost:8080/swagger-ui.html Local Swagger UI
http://localhost:8080/v3/api-docs Local OpenAPI JSON

How to authenticate in Swagger UI

  1. Call POST /api/auth/login β†’ Try it out β†’ Execute
  2. Copy the token from the response
  3. Click Authorize πŸ”’ at the top of the page
  4. Enter Bearer <your-token> β†’ click Authorize
  5. All subsequent requests will include the token automatically βœ…

πŸ“‘ API Endpoints

Authentication

Method Endpoint Auth Description
POST /api/auth/login ❌ Public Login and receive a JWT token

Employee Management

Method Endpoint Role Required Description
GET /api/employees ADMIN or HR Get all employees (paginated)
GET /api/employees/{id} ADMIN or HR Get employee by ID (Redis cached)
GET /api/employees/{id}/salary ADMIN or HR Get calculated salary
POST /api/employees/onboard ADMIN only Add employee + full onboarding pipeline
PUT /api/employees/{id} ADMIN only Update an employee
DELETE /api/employees/{id} ADMIN only Soft-delete an employee

Observability

Method Endpoint Auth Description
GET /actuator/health ❌ Public Application health check
GET /actuator/prometheus ❌ Public Prometheus metrics

πŸ“ Sample Requests & Responses

Step 1 β€” Login

POST /api/auth/login
{
  "username": "admin",
  "password": "admin123"
}
{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "username": "admin",
  "role": "ROLE_ADMIN"
}

Use as: Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...


Step 2 β€” Onboard a Full-Time Employee

POST /api/employees/onboard
Authorization: Bearer <your-token>
{
  "name": "Vikas Singh Rawat",
  "designation": "Software Engineer",
  "type": "FULLTIME",
  "monthlySalary": 85000,
  "hoursWorked": 0,
  "hourlyRate": 0
}

Onboard a Part-Time Employee

POST /api/employees/onboard
Authorization: Bearer <your-token>
{
  "name": "Rahul Mehta",
  "designation": "Intern",
  "type": "PARTTIME",
  "monthlySalary": 0,
  "hoursWorked": 40,
  "hourlyRate": 200
}

Onboarding Success Response

{
  "employeeId": 1,
  "employeeName": "Vikas Singh Rawat",
  "workEmail": "vikas.singh.rawat@company.com",
  "slackInviteSent": true,
  "trainingAssigned": true,
  "payrollConfigured": true,
  "message": "Onboarding completed successfully for Vikas Singh Rawat",
  "aiOnboardingMessage": "Welcome aboard, Vikas! We are thrilled to have you join our Engineering team."
}

Get All Employees (Paginated)

GET /api/employees?page=0&size=10&sort=id,asc
Authorization: Bearer <your-token>

πŸ§ͺ Testing the API

Using Swagger UI (Recommended)

  1. Open https://employeepayroll-app.onrender.com/swagger-ui.html
  2. Login β†’ copy token β†’ click Authorize πŸ”’
  3. Use Try it out on any endpoint

Recommended Testing Order

  1. POST /api/auth/login β†’ get JWT token
  2. POST /api/employees/onboard β†’ create employee, note the id
  3. GET /api/employees β†’ confirm employee is listed
  4. GET /api/employees/{id} β†’ fetch by id (Redis cached on second call)
  5. GET /api/employees/{id}/salary β†’ verify salary calculation
  6. PUT /api/employees/{id} β†’ update (clears Redis cache)
  7. DELETE /api/employees/{id} β†’ soft-delete (clears Redis cache)

Using curl (Windows CMD)

:: Login
curl -X POST https://employeepayroll-app.onrender.com/api/auth/login -H "Content-Type: application/json" -d "{\"username\": \"admin\", \"password\": \"admin123\"}"

:: Get all employees
curl -X GET https://employeepayroll-app.onrender.com/api/employees -H "Authorization: Bearer TOKEN"

:: Get by ID
curl -X GET https://employeepayroll-app.onrender.com/api/employees/1 -H "Authorization: Bearer TOKEN"

:: Get salary
curl -X GET https://employeepayroll-app.onrender.com/api/employees/1/salary -H "Authorization: Bearer TOKEN"

:: Onboard full-time
curl -X POST https://employeepayroll-app.onrender.com/api/employees/onboard -H "Content-Type: application/json" -H "Authorization: Bearer TOKEN" -d "{\"name\": \"Vikas\", \"designation\": \"Software Engineer\", \"type\": \"FULLTIME\", \"monthlySalary\": 85000, \"hoursWorked\": 0, \"hourlyRate\": 0}"

:: Onboard part-time
curl -X POST https://employeepayroll-app.onrender.com/api/employees/onboard -H "Content-Type: application/json" -H "Authorization: Bearer TOKEN" -d "{\"name\": \"Rahul\", \"designation\": \"Intern\", \"type\": \"PARTTIME\", \"monthlySalary\": 0, \"hoursWorked\": 40, \"hourlyRate\": 200}"

:: Update
curl -X PUT https://employeepayroll-app.onrender.com/api/employees/1 -H "Content-Type: application/json" -H "Authorization: Bearer TOKEN" -d "{\"name\": \"Vikas Updated\", \"designation\": \"Senior Engineer\", \"type\": \"FULLTIME\", \"monthlySalary\": 95000, \"hoursWorked\": 0, \"hourlyRate\": 0}"

:: Delete
curl -X DELETE https://employeepayroll-app.onrender.com/api/employees/1 -H "Authorization: Bearer TOKEN"

πŸ€– AI-Powered Onboarding Pipeline

When POST /api/employees/onboard is called, 5 steps execute automatically:

New Employee Saved to DB
        β”‚
        β–Ό
1. EmailService           β†’ Creates work email (name@company.com)
        β”‚
        β–Ό
2. SlackService           β†’ Sends Slack workspace invite
        β”‚
        β–Ό
3. TrainingService        β†’ Assigns training modules by designation
        β”‚
        β–Ό
4. PayrollSetupService    β†’ Configures payroll (FULLTIME or PARTTIME)
        β”‚
        β–Ό
5. AIOnboardingService    β†’ Generates personalized welcome message via Groq AI
        β”‚
        β–Ό
   OnboardingResponseDTO returned βœ…

The onboard endpoint is rate-limited to 10 requests per minute to prevent AI API abuse.

Training Modules by Designation

Designation Modules Assigned
Engineer / Developer / SDE Company Orientation, Secure Coding Practices, Git Workflow
Manager / Team Lead Company Orientation, Leadership Fundamentals, HR Policies
HR / Human Resources Company Orientation, Recruitment Basics, Compliance Training
Any other Company Orientation, Code of Conduct

⚑ Redis Caching

Operation Cache Behaviour
GET /api/employees/{id} Cached under key employees::{id}
PUT /api/employees/{id} Cache evicted on update
DELETE /api/employees/{id} Cache evicted on delete

πŸ“Š Observability

Feature Details
Health Check GET /actuator/health β€” reports UP/DOWN
Prometheus Metrics GET /actuator/prometheus β€” JVM, HTTP, custom metrics
Structured Logging All controllers & services use @Slf4j with consistent log levels

πŸ§ͺ Running Tests

# Run all tests
mvn test

# Run tests + generate JaCoCo coverage report
mvn verify

Coverage report: target/site/jacoco/index.html

Test Suite

Test Class What It Covers
EmployeeControllerTest Full HTTP layer tests with MockMvc
EmployeeEntityTest OOP inheritance & salary calculation
OnboardingServiceTest Mocked 5-step pipeline
AIOnboardServiceTest Mocked Groq API calls
ServiceUnitTests Core service logic
PayrollSystemTest Integration tests with real PostgreSQL (Testcontainers)

πŸš€ Future Improvements

  • Convert into a fully distributed microservices architecture
  • Add Kafka / RabbitMQ for event-driven async onboarding
  • Integrate real email (SendGrid) and Slack APIs
  • Add a React frontend dashboard
  • Deploy on AWS with a CI/CD pipeline (GitHub Actions)
  • Add refresh token support for longer JWT sessions

This project is actively evolving towards a full production-grade system.


πŸ“Έ Screenshots

Swagger UI β€” All Endpoints

Login

Login β€” JWT Token Response

Swagger UI

Onboarding β€” AI Pipeline Response

Onboarding

Salary Calculation Response

Salary


πŸ”’ Security Notes

  • Never commit application.properties with real credentials β€” it is in .gitignore
  • Always use environment variables for DB_PASSWORD, GROQ_API_KEY, and JWT_SECRET
  • Use application.properties.example as a safe template for new contributors
  • Change default admin/HR passwords before any production deployment
  • In production, replace allowedOrigins("*") in SecurityConfig with your actual frontend URL

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

Vikas Singh Rawat β€” Backend Developer | Java | Spring Boot | System Design

GitHub LinkedIn

πŸš€ Open to internship and backend development opportunities

About

Production-ready Spring Boot REST API for Employee Payroll Management with JWT Security, Redis Caching, Flyway Migrations, Soft Delete, Rate Limiting, Structured Logging, and an AI-Powered Onboarding Pipeline using Groq (LLaMA 3.3-70b).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages