Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

QuickBuy

QuickBuy is a secured Spring Boot e-commerce REST API for product catalog management, image storage, inventory-aware order placement, and customer order history.

Highlights

  • Stateless JWT bearer authentication with BCrypt password hashing
  • Customer and administrator authorization
  • Product CRUD, search, and multipart image upload
  • Transactional order placement with pessimistic inventory locking
  • Request validation and consistent JSON error responses
  • PostgreSQL persistence through Spring Data JPA
  • OpenAPI documentation with Swagger UI
  • 16 JUnit 5, Mockito, MockMvc, and H2 tests with 70.5% line coverage
  • Concurrent PowerShell load test with latency percentiles

Tech stack

  • Java 21
  • Spring Boot 4.1
  • Spring Web MVC, Security, Validation, and Data JPA
  • PostgreSQL; H2 for tests
  • JJWT 0.12.6
  • springdoc-openapi 3.1.0
  • JaCoCo 0.8.15
  • Maven and Lombok

Configuration

The application reads configuration from environment variables and provides development defaults:

Variable Default Purpose
DB_URL jdbc:postgresql://localhost:5432/products PostgreSQL JDBC URL
DB_USERNAME postgres Database username
DB_PASSWORD Required Database password
JWT_SECRET Required Base64-encoded key of at least 256 bits
JWT_EXPIRATION_MS 900000 Token lifetime in milliseconds
CORS_ALLOWED_ORIGINS http://localhost:3000 Comma-separated browser origins

Set a strong secret before running the application. One way to generate and configure it is:

$bytes = New-Object byte[] 32
[Security.Cryptography.RandomNumberGenerator]::Fill($bytes)
$env:JWT_SECRET = [Convert]::ToBase64String($bytes)
$env:DB_PASSWORD = "your-postgres-password"

Create the local database before starting the application:

CREATE DATABASE products;

Run locally

.\mvnw.cmd spring-boot:run

The API starts at http://localhost:8080.

Authentication

Register a customer:

POST /register
Content-Type: application/json

{
  "name": "nikhil",
  "password": "StrongPass123"
}

Log in:

POST /login
Content-Type: application/json

{
  "name": "nikhil",
  "password": "StrongPass123"
}

The response contains a token:

{
  "token": "eyJ...",
  "type": "Bearer",
  "expiresInSeconds": 900
}

Use it for protected requests:

Authorization: Bearer eyJ...

New registrations receive the CUSTOMER role. For local development, promote a user to administrator directly in PostgreSQL:

UPDATE users SET role = 'ADMIN' WHERE name = 'nikhil';

API endpoints

Method Endpoint Access Description
POST /register Public Register a customer
POST /login Public Obtain a JWT
GET /api/products Authenticated List products
GET /api/product/{id} Authenticated Get one product
GET /api/products/search?keyword=... Authenticated Search products
GET /api/product/{id}/image Authenticated Retrieve product image
POST /api/product Admin Create a product
PUT /api/product/{id} Admin Update a product
DELETE /api/product/{id} Admin Delete a product
POST /api/orders/place Authenticated Place an order
GET /api/orders/my Authenticated List the current user's orders
GET /api/orders Admin List all orders

Product create/update requests use multipart/form-data with a JSON part named product and an image part named imageFile. Updates may omit imageFile to keep the existing image.

{
  "name": "iPhone 15",
  "description": "Apple smartphone",
  "brand": "Apple",
  "price": 79999,
  "category": "Mobile",
  "releaseDate": "2026-01-10",
  "productAvailable": true,
  "stockQuantity": 20
}

Order request example:

{
  "customerName": "Nikhil",
  "email": "nikhil@example.com",
  "items": [
    {
      "productId": 1,
      "quantity": 2
    }
  ]
}

Order creation is transactional. Products are locked while stock is checked and reduced, preventing partial orders and concurrent overselling.

Swagger/OpenAPI

After starting the application:

  • Swagger UI: http://localhost:8080/swagger-ui.html
  • OpenAPI JSON: http://localhost:8080/v3/api-docs
  • OpenAPI YAML: http://localhost:8080/v3/api-docs.yaml

Use /login, copy the returned token, select Authorize in Swagger UI, and enter the token.

Tests

Run the complete suite and generate the coverage report:

.\mvnw.cmd verify

The 16 tests use an in-memory H2 database and do not require PostgreSQL. The suite achieves 70.5% line coverage and 70.9% instruction coverage, measured with JaCoCo. After the build, open target/site/jacoco/index.html for the detailed report.

Test coverage includes:

  • Application startup
  • JWT generation and verification
  • Password hashing and duplicate registration
  • Product image validation and update behavior
  • Successful inventory reduction and price calculation
  • Unknown products and insufficient stock
  • Product controller responses and structured errors

Load test

Start the API and run:

.\loadtest.ps1

The script creates a temporary user, logs in for a JWT, warms up the API, and reports throughput, success/error rates, and p50/p95/p99 latency for concurrent product-list requests.

Production follow-ups

Before a public deployment, add versioned Flyway migrations, replace database image storage with object storage, introduce pagination, and configure a managed secret store. Hibernate ddl-auto=update is retained for local development convenience.

About

this project is covering the standard ecommerce website including displaying ,updating, deleting and Ordering the product with spread dto classes, controller and repo layer for Order and products

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages