A production-ready, modular monolith, event-driven REST API for an electronics e-commerce store. Built with Spring Boot 3.2, MySQL 8, Redis, and JWT authentication.
src/main/java/com/electronicsstore/
├── ElectronicsStoreApplication.java
├── shared/ ← Cross-cutting concerns (no business logic)
│ ├── config/ ← Security, JWT, WebClient, OpenAPI
│ ├── entity/ ← Enums, BaseEntity
│ ├── events/ ← DomainEvent base class + publisher interface
│ ├── exception/ ← Custom exceptions + GlobalExceptionHandler
│ ├── response/ ← ApiResponse<T>, PageResponse<T>
│ └── util/ ← SecurityUtils
└── modules/ ← Domain modules (self-contained)
├── auth/ ← Register, Login, JWT, Email Verification
├── product/ ← CRUD, JPA Spec filtering, caching
├── cart/ ← Cart management with stock validation
├── order/ ← Order placement and status machine
├── payment/ ← Paystack + Flutterwave adapters
├── inventory/ ← Stock movements + event-driven deduction
├── notification/ ← Async email dispatch
└── admin/ ← Dashboard, user management, analytics
Modules communicate only through domain events — never by calling each other's services directly.
UserRegistered → NotificationListener → send verification email
PasswordReset → NotificationListener → send reset email
OrderPlaced → NotificationListener → send order confirmation
PaymentSucceeded → OrderPaymentListener → mark order PAID
→ InventoryEventListener → deduct stock
→ NotificationListener → send payment confirmation
OrderStatusChanged → NotificationListener → send status update email
LowStock → NotificationListener → alert admin
OrderCancelled → InventoryEventListener → return stock (if was paid)
Kafka-ready:
DomainEventPublisheris an interface. SwapSpringDomainEventPublisherwith a Kafka implementation and nothing else changes.
- Java 21+
- Docker + Docker Compose
git clone https://github.com/your-org/electronics-store-backend.git
cd electronics-store-backend
cp .env.example .env
# Edit .env with your actual credentialsdocker compose up -dAPI is available at http://localhost:8080
Swagger UI at http://localhost:8080/swagger-ui.html
# Start MySQL + Redis only
docker compose up -d mysql redis
# Run the app
./mvnw spring-boot:run# Unit + slice tests (uses H2 in-memory, no Docker needed)
./mvnw test -Dspring.profiles.active=test
# Single test class
./mvnw test -Dtest=AuthServiceTest -Dspring.profiles.active=test| Module | Endpoint | Auth |
|---|---|---|
| Auth | POST /api/auth/register |
Public |
| Auth | POST /api/auth/login |
Public |
| Auth | POST /api/auth/refresh |
Public |
| Auth | GET /api/auth/verify-email?token= |
Public |
| Auth | POST /api/auth/forgot-password |
Public |
| Auth | POST /api/auth/reset-password |
Public |
| Products | GET /api/products |
Public |
| Products | GET /api/products/{id} |
Public |
| Products | POST /api/products |
ADMIN |
| Products | PUT /api/products/{id} |
ADMIN |
| Products | DELETE /api/products/{id} |
ADMIN |
| Categories | GET /api/categories |
Public |
| Categories | POST /api/categories |
ADMIN |
| Brands | GET /api/brands |
Public |
| Brands | POST /api/brands |
ADMIN |
| Cart | GET /api/cart |
CUSTOMER |
| Cart | POST /api/cart/items |
CUSTOMER |
| Cart | PUT /api/cart/items/{id} |
CUSTOMER |
| Cart | DELETE /api/cart/items/{id} |
CUSTOMER |
| Cart | DELETE /api/cart |
CUSTOMER |
| Orders | POST /api/orders |
CUSTOMER |
| Orders | GET /api/orders/me |
CUSTOMER |
| Orders | GET /api/orders/me/{id} |
CUSTOMER |
| Orders | DELETE /api/orders/me/{id} |
CUSTOMER |
| Orders | GET /api/orders |
ADMIN |
| Orders | PATCH /api/orders/{id}/status |
ADMIN |
| Payments | POST /api/payments/initialize |
CUSTOMER |
| Payments | GET /api/payments/verify?reference= |
CUSTOMER |
| Payments | POST /api/payments/webhook/{provider} |
Public (webhook) |
| Payments | GET /api/payments/me |
CUSTOMER |
| Payments | GET /api/payments |
ADMIN |
| Admin | GET /api/admin/dashboard |
ADMIN |
| Admin | GET /api/admin/users |
ADMIN |
| Admin | PATCH /api/admin/users/{id}/lock |
ADMIN |
| Admin | PATCH /api/admin/users/{id}/enable |
ADMIN |
| Admin | POST /api/admin/inventory/{productId}/restock |
ADMIN |
- JWT access tokens (24h) + refresh tokens (7d)
- BCrypt password hashing (strength 12)
- Role-based access control (
CUSTOMER,ADMIN) - Account locking after repeated failed logins
- Email verification before login
- CORS configured (update for production origins)
- Webhook signature validation (Paystack HMAC, Flutterwave hash)
See .env.example for a full list with descriptions.
| Layer | Technology |
|---|---|
| Framework | Spring Boot 3.2 |
| Language | Java 21 |
| Database | MySQL 8 |
| Cache | Redis 7 |
| Security | Spring Security + JWT (jjwt 0.12) |
| Migrations | Flyway |
| HTTP Client | WebFlux WebClient |
| API Docs | SpringDoc OpenAPI 3 |
| Testing | JUnit 5, Mockito, MockMvc |
| Build | Maven |
| Container | Docker + Compose |