A full-stack e-commerce MVP with Spring Boot backend and Next.js frontend.
- Backend: Java 17+, Spring Boot 3, Spring Data JPA, Flyway, PostgreSQL
- Frontend: Next.js 14, TypeScript, Tailwind CSS
- Database: PostgreSQL 15
Before starting, ensure you have the following installed:
| Tool | Version | Check Command |
|---|---|---|
| Java | 17+ | java -version |
| Node.js | 18+ | node -v |
| npm | 9+ | npm -v |
| PostgreSQL | 15+ | psql --version |
# Install Homebrew (if not installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Java 17
brew install openjdk@17
echo 'export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Install Node.js
brew install node
# Install PostgreSQL
brew install postgresql@15
brew services start postgresql@15# Install Java 17
sudo apt update
sudo apt install openjdk-17-jdk
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
# Install PostgreSQL
sudo apt install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo systemctl enable postgresql- Java 17: Download from Adoptium
- Node.js: Download from nodejs.org
- PostgreSQL: Download from postgresql.org
git clone <repository-url>
cd ecommerce-mvp-monorepodocker-compose up -dThis starts PostgreSQL on port 5432 with:
- Database:
ecommerce - Username:
ecommerce - Password:
ecommerce123
# Create database and user
psql postgres <<EOF
CREATE USER ecommerce WITH PASSWORD 'ecommerce123';
CREATE DATABASE ecommerce OWNER ecommerce;
GRANT ALL PRIVILEGES ON DATABASE ecommerce TO ecommerce;
EOFVerify connection:
psql -h localhost -U ecommerce -d ecommerce -c "SELECT 1"
# Enter password: ecommerce123cd backend
# First time: Install dependencies and run
./mvnw spring-boot:run
# Or on Windows:
mvnw.cmd spring-boot:runWait for the message:
Started EcommerceApplication in X.XXX seconds
Backend URLs:
- API: http://localhost:8080
- Swagger UI: http://localhost:8080/swagger-ui.html
Open a new terminal:
cd frontend
# Install dependencies (first time only)
npm install
# Start development server
npm run devWait for the message:
✓ Ready in X.Xs
Frontend URL: http://localhost:3000
# Get all products
curl http://localhost:8080/api/products
# Get products by category
curl "http://localhost:8080/api/products?category=laptops"
# Search products
curl "http://localhost:8080/api/products?search=pro&sort=price_asc"
# Get shipping quote
curl -X POST http://localhost:8080/api/shipping/quote \
-H "Content-Type: application/json" \
-d '{"country":"US","items":[{"productId":1,"qty":1}]}'
# Validate coupon
curl -X POST http://localhost:8080/api/coupons/validate \
-H "Content-Type: application/json" \
-d '{"code":"SAVE10","cartTotal":100}'
# Subscribe to newsletter
curl -X POST http://localhost:8080/api/newsletter/subscribe \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com"}'- Open http://localhost:3000
- Browse products
- Add items to cart
- Click the heart icon to add to wishlist
- Use the search bar to search products
- Click category cards to filter
- Use the sort dropdown
- Subscribe to newsletter at the bottom
| Method | Endpoint | Description | Query Params |
|---|---|---|---|
| GET | /api/products |
List products | search, category, sort |
| GET | /api/products/{id} |
Get product | - |
| GET | /api/products/categories |
List categories | - |
Sort options: featured, price_asc, price_desc, newest
Categories: laptops, smartphones, audio, tablets, wearables
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/orders |
Create order |
| GET | /api/orders/{id} |
Get order details |
Create Order Request:
{
"email": "customer@example.com",
"items": [
{"productId": 1, "quantity": 2}
],
"shippingAddress": {
"country": "US",
"city": "San Francisco",
"street": "123 Main St",
"postalCode": "94102"
},
"couponCode": "SAVE10"
}| Method | Endpoint | Description |
|---|---|---|
| POST | /api/shipping/quote |
Calculate shipping |
Request:
{
"country": "US",
"items": [{"productId": 1, "qty": 2}]
}| Method | Endpoint | Description |
|---|---|---|
| POST | /api/coupons/validate |
Validate coupon |
Request:
{
"code": "SAVE10",
"cartTotal": 100.00
}Available Coupons:
SAVE10- 10% off (min $50)FLAT20- $20 off (min $100)WELCOME15- 15% off (min $0)
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/newsletter/subscribe |
Subscribe |
| POST | /api/newsletter/unsubscribe |
Unsubscribe |
ecommerce-mvp-monorepo/
├── backend/
│ ├── src/main/java/com/ecommerce/
│ │ ├── config/ # OpenAPI, CORS config
│ │ ├── controller/ # REST controllers
│ │ ├── dto/ # Request/Response DTOs
│ │ ├── entity/ # JPA entities
│ │ ├── exception/ # Custom exceptions
│ │ ├── repository/ # JPA repositories
│ │ └── service/ # Business logic
│ └── src/main/resources/
│ ├── application.yml # App configuration
│ └── db/migration/ # Flyway migrations
├── frontend/
│ ├── src/
│ │ ├── app/ # Next.js pages
│ │ ├── components/ # React components
│ │ ├── context/ # React contexts (Cart, Wishlist)
│ │ └── lib/ # API client, types
│ ├── package.json
│ └── tailwind.config.js
├── docker-compose.yml
├── SPEC.md # Full specification
└── README.md
cd backend
# Run with hot reload (requires spring-boot-devtools)
./mvnw spring-boot:run
# Build JAR
./mvnw clean package
# Run JAR
java -jar target/ecommerce-0.0.1-SNAPSHOT.jar
# Run tests
./mvnw testcd frontend
# Development server with hot reload
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Lint code
npm run lint# Connect to database
psql -h localhost -U ecommerce -d ecommerce
# View tables
\dt
# View products
SELECT id, name, category, base_price FROM products;
# View orders
SELECT * FROM orders;
# Reset database (dangerous!)
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
# Then restart backend to re-run migrations| Variable | Default | Description |
|---|---|---|
SPRING_DATASOURCE_URL |
jdbc:postgresql://localhost:5432/ecommerce |
Database URL |
SPRING_DATASOURCE_USERNAME |
ecommerce |
Database user |
SPRING_DATASOURCE_PASSWORD |
ecommerce123 |
Database password |
| Variable | Default | Description |
|---|---|---|
NEXT_PUBLIC_API_URL |
http://localhost:8080 |
Backend API URL |
Error: Connection refused to PostgreSQL
# Check if PostgreSQL is running
brew services list | grep postgresql # macOS
sudo systemctl status postgresql # Linux
# Start PostgreSQL
brew services start postgresql@15 # macOS
sudo systemctl start postgresql # LinuxError: Database does not exist
psql postgres -c "CREATE DATABASE ecommerce OWNER ecommerce;"Error: Port 8080 already in use
# Find and kill process
lsof -i :8080
kill -9 <PID>Error: Port 3000 already in use
# Find and kill process
lsof -i :3000
kill -9 <PID>
# Or use different port
npm run dev -- -p 3001Error: Module not found
rm -rf node_modules package-lock.json
npm installCORS error in browser
- Ensure backend is running on port 8080
- Check backend CORS config in
WebConfig.java
500 Internal Server Error
# Check backend logs
tail -100 /tmp/backend.logMIT