A backend-focused Mini-ERP system built with Spring Boot. The project demonstrates REST architecture, business logic implementation, role-based security with JWT, and stock management.
- Create customer
- List customers
- Create product
- List products
- Manage stock quantity
- Create draft order
- Add items to order
- Confirm order
- Cancel order
- Stock reduction on confirmation
- Business rule enforcement (no empty orders, no cancel after confirmation)
- JWT authentication
- Role-based authorization (ADMIN, SALES)
- BCrypt password hashing
- Stateless session management
- api/ → REST Controllers
- domain/ → JPA Entities
- dto/ → Request & Response DTOs
- repository/ → Spring Data JPA Repositories
- security/ → JWT service + filter
- config/ → Spring Security configuration
The diagram reflects the relational database structure used by the application,
including primary keys, foreign keys, and business-relevant constraints.
- Orders must contain at least one item before confirmation
- Confirmed orders cannot be canceled
- Stock is reduced permanently upon confirmation
- Orders cannot be confirmed if stock is insufficient
- Price and VAT are stored as snapshots in OrderItem
POST /auth/login
Example:
{
"username": "sales",
"password": "sales123"
}Returns:
{
"token": "JWT_TOKEN"
}
- ADMIN
- SALES
All ERP endpoints require:
Authorization: Bearer <token>
GET /health
GET /admin/ping
POST /customers
GET /customers
POST /products
GET /products
Example product:
{
"sku": "P-001",
"name": "Laptop",
"description": "Business Laptop",
"unitPriceNet": 1200.00,
"vatRate": 0.19,
"stockQty": 10
}
Create draft:
POST /orders
Add item:
POST /orders/{orderId}/items
Confirm order:
PATCH /orders/{orderId}/confirm
Cancel order:
PATCH /orders/{orderId}/cancel
Example start command:
docker run --name minierp-postgres \
-e POSTGRES_USER=erp \
-e POSTGRES_PASSWORD=erp \
-e POSTGRES_DB=minierp \
-p 5432:5432 \
-d postgres:16
application.properties
- spring.datasource.url
- spring.datasource.username
- spring.datasource.password
- jwt.secret
- jwt.expiration
- Stateless API (no sessions)
- JWT signed with HS256
- BCrypt password hashing
- Roles mapped to Spring Security authorities
/errorendpoint permitted to allow proper HTTP error responses
1. Login → receive JWT
2. Create product
3. Create order (draft)
4. Add item
5. Confirm order → stock decreases
6. Attempt cancel → rejected (409 Conflict)
- Java 21
- Spring Boot
- Spring Web
- Spring Data JPA
- Spring Security
- JWT (jjwt)
- PostgreSQL
- Gradle
- Docker
- Users stored in database
- Role table and user-role mapping
- Global exception handling (@RestControllerAdvice)
- Invoice generation (PDF)
- Unit tests (JUnit)
- Integration tests
- OpenAPI / Swagger documentation