Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

8 Commits

Folders and files

Repository files navigation

πŸ›οΈ Somiishop Scaffold

Java Spring Boot Angular TypeScript PostgreSQL Docker License

A production-ready, full-stack e-commerce marketplace scaffold that connects buyers and sellers. Somiishop provides a fully configured, runnable starting point β€” complete with authentication, payments, product management, and order tracking β€” so you can focus on building your marketplace, not the boilerplate.


πŸ“‹ Table of Contents


✨ Features

  • Stripe Connect Payments β€” PaymentIntent creation with platform commission tracking (default 5%) and webhook handling [1]
  • Multi-role User System β€” BUYER, SELLER, and ADMIN roles with JWT-based access control [2]
  • Product Catalog β€” Full CRUD with category/price filtering, keyword search, and paginated browsing [3]
  • Order Lifecycle Management β€” Statuses: PENDING β†’ PAID β†’ SHIPPED β†’ DELIVERED β†’ COMPLETED / CANCELLED, with stock validation on creation [4]
  • Email Notifications via SendGrid β€” Verification, password reset, order confirmation, and seller notifications [5]
  • JWT Authentication with Token Refresh β€” 15-minute access tokens and 7-day refresh tokens [6]
  • Persistent Shopping Cart β€” Cart state stored in browser localStorage
  • Review & Rating System β€” Verified-purchase tracking with a one-review-per-product-per-user constraint [7]
  • Docker Compose β€” One-command local environment with PostgreSQL, backend, and frontend services wired together [8]
  • Database Migrations β€” Flyway-managed schema versioning with auto-migration at startup [9]

πŸ—οΈ Tech Stack

Backend

Technology Version Purpose
Java 21 Runtime [10]
Spring Boot 3.2.2 Application framework [11]
Maven 3.9+ Build tool [12]
Spring Data JPA β€” ORM & repository layer
Spring Security β€” Authentication & authorization
Spring Mail β€” Email dispatch
PostgreSQL 16 Primary database [13]
Flyway 10.8.1 Database migrations [14]
JJWT 0.12.3 JWT creation & validation, HS512 algorithm [14]
BCrypt β€” Password hashing (strength 12) [15]
Stripe Java SDK 24.14.0 Payment processing [14]
AWS SDK for S3 2.21.26 File/image storage [14]
Lombok 1.18.32 Boilerplate reduction
Testcontainers 1.19.3 Integration testing [14]

Frontend

Technology Version Purpose
Angular 17.3.0 UI framework [16]
TypeScript 5.4.2 (strict) Language [17]
RxJS 7.8.0 Reactive programming [18]
@stripe/stripe-js 2.4.0 Stripe.js integration [18]
Karma + Jasmine 6.4.0 + 5.1.0 Unit testing [19]

Infrastructure

Technology Version Purpose
Docker & Docker Compose 3.8 Container orchestration [20]
PostgreSQL (Alpine) 16 Containerized database [13]

πŸ“ Project Structure

somiishop-scaffold/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ src/main/java/com/somiishop/
β”‚   β”‚   β”œβ”€β”€ config/             # Security, CORS, BCrypt configuration
β”‚   β”‚   β”œβ”€β”€ controller/         # REST API endpoints (Auth, Product, Order, Payment, Category)
β”‚   β”‚   β”œβ”€β”€ dto/                # Data Transfer Objects
β”‚   β”‚   β”œβ”€β”€ entity/             # JPA entities (User, Product, Order, Payment, Review)
β”‚   β”‚   β”œβ”€β”€ repository/         # Spring Data repositories
β”‚   β”‚   β”œβ”€β”€ service/            # Business logic (JWT, Stripe, Cart, Email)
β”‚   β”‚   β”œβ”€β”€ security/           # JWT authentication filter
β”‚   β”‚   β”œβ”€β”€ exception/          # Global error handling
β”‚   β”‚   └── SomiishopApplication.java
β”‚   β”œβ”€β”€ src/main/resources/
β”‚   β”‚   β”œβ”€β”€ application.yml     # Main configuration
β”‚   β”‚   β”œβ”€β”€ application-local.yml
β”‚   β”‚   └── db/migration/       # Flyway SQL migrations
β”‚   β”œβ”€β”€ pom.xml
β”‚   └── Dockerfile
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/app/
β”‚   β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”‚   β”œβ”€β”€ services/       # Auth, Cart, Order, Payment, Product services
β”‚   β”‚   β”‚   β”œβ”€β”€ guards/         # AuthGuard, RoleGuard for route protection
β”‚   β”‚   β”‚   └── interceptors/   # JWT token attachment, 401 handling
β”‚   β”‚   β”œβ”€β”€ features/           # Feature modules (auth, checkout, home)
β”‚   β”‚   └── app.component.ts
β”‚   β”œβ”€β”€ src/environments/       # Environment configurations
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ angular.json
β”‚   └── Dockerfile
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ NEXT_STEPS.md               # 10-phase implementation roadmap
└── README.md

The backend follows a layered architecture [21]: controllers handle HTTP concerns, services own business logic, and repositories provide data access. The frontend organizes code into core/ (singleton services, guards, interceptors) and features/ (route-scoped modules) [22].


πŸ”§ Prerequisites

Before getting started, ensure the following are installed:

Requirement Version Notes
Java JDK 21 Required for backend [10]
Node.js + npm 18+ Required for frontend [23]
Docker & Docker Compose Latest Required for containerized setup
PostgreSQL 16 Only needed for non-Docker local dev
Maven 3.9+ Only needed for non-Docker local dev [12]

πŸš€ Quick Start with Docker

The fastest way to run the full stack locally. All services β€” PostgreSQL, backend, and frontend β€” start with a single command. [8]

1. Clone the repository

git clone https://github.com/your-org/somiishop-scaffold.git
cd somiishop-scaffold

2. Create your .env file

Create a .env file in the project root. The required and optional variables are listed below (see Environment Variables for the full reference).

# Required
STRIPE_API_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
JWT_SECRET=<your-256-bit-secret>

# Database (defaults shown)
DB_NAME=somiishop
DB_USER=somiishop
DB_PASSWORD=somiishop_dev

# Optional β€” AWS S3 image storage
AWS_S3_BUCKET=somiishop-uploads
AWS_REGION=us-east-1

Generating a JWT secret: Run openssl rand -base64 64 to generate a suitable 512-bit secret.

3. Start all services

docker-compose up --build

Docker Compose starts PostgreSQL first (with a health check), waits for it to be ready, then starts the backend, and finally the frontend. [24]

4. Verify everything is running

Service URL
Frontend http://localhost:4200
Backend API http://localhost:8080
PostgreSQL localhost:5432
curl http://localhost:8080/actuator/health
# Expected: {"status":"UP"}

5. Stop services

docker-compose down          # Stop containers
docker-compose down -v       # Stop and remove volumes (clears database)

πŸ’» Local Development

For faster iteration cycles without Docker, run the backend and frontend directly on your machine.

Backend

macOS (Homebrew):

brew services start postgresql@16
createdb somiishop
createuser somiishop

Start the backend:

cd backend
mvn spring-boot:run

Flyway will automatically apply all pending migrations on startup. [9] The API will be available at http://localhost:8080.

Frontend

cd frontend
npm install
ng serve

The Angular dev server starts at http://localhost:4200 with hot-reload enabled. [25] The frontend is configured to connect to the backend at http://localhost:8080/api/v1. [26]


βš™οΈ Environment Variables

All backend configuration is driven by environment variables, with sensible defaults defined in application.yml. [27]

Required

Variable Example Description
STRIPE_API_KEY sk_test_... Stripe secret key for payment processing [28]
STRIPE_WEBHOOK_SECRET whsec_... Stripe webhook endpoint secret for signature verification [28]
JWT_SECRET <256-bit string> HS512 signing secret for JWT tokens (minimum 256 bits) [6]

Database

Variable Default Description
DB_NAME somiishop PostgreSQL database name [9]
DB_USER somiishop PostgreSQL username [9]
DB_PASSWORD somiishop_dev PostgreSQL password [9]
DB_HOST localhost PostgreSQL host (use db inside Docker) [29]
DB_PORT 5432 PostgreSQL port [9]

Email (SendGrid)

Variable Default Description
MAIL_HOST smtp.sendgrid.net SMTP host [5]
MAIL_PORT 587 SMTP port with STARTTLS [5]
MAIL_USERNAME β€” SMTP username (typically apikey for SendGrid)
MAIL_PASSWORD β€” SendGrid API key used as SMTP password

AWS S3 (Optional)

Variable Default Description
AWS_S3_BUCKET somiishop-uploads S3 bucket for product image storage [28]
AWS_REGION us-east-1 AWS region [28]
AWS_ACCESS_KEY_ID β€” AWS access key ID
AWS_SECRET_ACCESS_KEY β€” AWS secret access key

Application

Variable Default Description
CORS_ALLOWED_ORIGINS http://localhost:4200 Comma-separated allowed CORS origins [28]
FRONTEND_URL http://localhost:4200 Frontend base URL for email links [28]

Token Expiry (application.yml defaults)

Setting Value Description
Access token expiry 900,000 ms (15 min) Short-lived JWT for API access [6]
Refresh token expiry 604,800,000 ms (7 days) Long-lived token for access token renewal [6]
Max file upload size 10 MB Per-file and per-request limit [30]

πŸ”Œ API Endpoints

All endpoints are prefixed with /api/v1. Authentication uses the Authorization: Bearer <token> header. [31]

Access levels used in the tables below:

  • 🌐 Public β€” No authentication required
  • πŸ”’ Authenticated β€” Valid JWT required
  • πŸͺ Seller β€” Must be the owning seller (verified in service layer)
  • πŸ‘‘ Admin β€” Admin role required

Authentication

Base path: /api/v1/auth [32]

Method Endpoint Description Access Notes
POST /register Register a new user 🌐 Public Auto-assigns BUYER role; sends verification email [33]
POST /login Login and receive tokens 🌐 Public Returns accessToken + refreshToken [34]
POST /refresh Exchange refresh token for new access token 🌐 Public Body: { "refreshToken": "..." } [35]
POST /logout Logout πŸ”’ Authenticated Stateless β€” client clears tokens from localStorage [36]

Register request body:

{
  "email": "user@example.com",
  "password": "minimum8chars"
}

Login / Register response:

{
  "userId": "uuid",
  "email": "user@example.com",
  "accessToken": "eyJ...",
  "refreshToken": "eyJ...",
  "tokenType": "Bearer",
  "expiresIn": 900,
  "roles": ["BUYER"]
}

Products

Base path: /api/v1/products [3]

Method Endpoint Description Access
GET / Browse products with pagination, search, and filters 🌐 Public [37]
GET /{id} Get product details by ID 🌐 Public [38]
GET /category/{categoryId} Browse products by category 🌐 Public [39]
GET /seller/{sellerId} List a seller's products 🌐 Public [40]
POST / Create a new product listing πŸͺ Seller [41]
PUT /{id} Update a product listing πŸͺ Seller [42]
DELETE /{id} Delete a product listing πŸͺ Seller [43]

GET / query parameters:

Parameter Type Default Description
page int 0 Page number
size int 20 Results per page
keyword string β€” Search term
categoryId UUID β€” Filter by category
minPrice decimal 0 Minimum price filter
maxPrice decimal 1000000 Maximum price filter
sortBy string createdAt Sort field

Orders

Base path: /api/v1/orders [44]

Method Endpoint Description Access
POST / Create an order with stock validation πŸ”’ Authenticated [4]
GET /{id} Get order details πŸ”’ Authenticated [45]
GET / Buyer's paginated order history πŸ”’ Authenticated [46]
GET /seller Seller's incoming orders πŸͺ Seller [47]
PUT /{id}/status Update order status πŸͺ Seller [48]
DELETE /{id} Cancel a pending order (restores stock) πŸ”’ Authenticated (buyer) [49]

Order statuses: PENDING β†’ PAID β†’ SHIPPED β†’ DELIVERED β†’ COMPLETED Β· CANCELLED [50]

Status update request body:

{
  "status": "SHIPPED"
}

Payments

Base path: /api/v1/payments [51]

Method Endpoint Description Access
POST /intent Create a Stripe PaymentIntent for an order πŸ”’ Authenticated [51]
POST /webhook Stripe webhook receiver 🌐 Public (Stripe-only) [52]

Create PaymentIntent request:

{
  "orderId": "uuid"
}

PaymentIntent response:

{
  "intentId": "pi_...",
  "clientSecret": "pi_..._secret_...",
  "amount": 4999,
  "currency": "usd",
  "status": "requires_payment_method"
}

The webhook endpoint handles payment_intent.succeeded events, updates the payment record, transitions the order status to PAID, and sends confirmation emails. [53]


Categories

Base path: /api/v1/categories [54]

Method Endpoint Description Access
GET / List all categories 🌐 Public [55]
GET /{id} Get category by ID 🌐 Public
POST / Create a category (auto-generates slug) πŸ‘‘ Admin [56]
PUT /{id} Update category name and slug πŸ‘‘ Admin [57]
DELETE /{id} Delete a category πŸ‘‘ Admin [58]

Create/update request body:

{
  "name": "Electronics"
}

Slugs are auto-generated from the name (lowercase, spaces β†’ hyphens). [59]


πŸ—„οΈ Database Schema

The full schema is created by a single Flyway migration: V1__initial_schema.sql. [7]

Table Description
users User accounts with email, hashed password, and role
user_roles Join table for user role assignments
profiles Extended user profile data
categories Product categories with auto-generated slugs
products Product listings linked to sellers and categories
orders Orders with status lifecycle and timestamps
order_items Line items within each order
payments Stripe payment records linked to orders
reviews Ratings with one-review-per-product-per-user constraint [7]
addresses Shipping and billing addresses
platform_settings Global settings (e.g., commission rate β€” default 5%) [1]
audit_logs Activity audit trail indexed by actor and timestamp

Key indexes

Performance indexes are created on high-traffic query paths [60]:

  • products β†’ seller_id, category_id, is_active, price, created_at
  • orders β†’ buyer_id, status, created_at
  • payments β†’ order_id, status
  • reviews β†’ product_id, reviewer_id

Connection pool

HikariCP is configured with a maximum of 10 connections and a minimum of 5 idle connections, with a 30-second connection timeout. [9]


πŸ› οΈ Development Commands

Backend

cd backend

# Run the application (hot-reload via Spring DevTools)
mvn spring-boot:run

# Build a production JAR (skipping tests)
mvn clean package -DskipTests

# Run unit and integration tests
mvn test

# Reset and re-run all Flyway migrations
mvn flyway:clean flyway:migrate

The backend Dockerfile uses a two-stage build: Maven 3.9 + Eclipse Temurin 21 (Alpine) for building, and Eclipse Temurin 21 JRE (Alpine) for the runtime image. [61]

Frontend

cd frontend

# Install dependencies
npm install

# Start the dev server (http://localhost:4200, with hot-reload)
npm start

# Production build (output to dist/somiishop-frontend)
npm run build

# Run unit tests (Karma + Jasmine)
npm test

# Run end-to-end tests
npm run e2e

# Lint the codebase
npm run lint

The frontend Dockerfile uses node:18-alpine and starts the Angular dev server bound to 0.0.0.0 with 2000 ms polling for file changes inside Docker. [62] The production build targets dist/somiishop-frontend. [63]


πŸ§ͺ Testing

Backend

Integration tests use Testcontainers to spin up a real PostgreSQL 16 instance, ensuring migrations and queries run against an authentic database. [14]

cd backend
mvn test

Frontend

Unit tests use Karma 6.4.0 as the test runner and Jasmine 5.1.0 as the assertion framework, with code coverage via karma-coverage. [19]

cd frontend
npm test          # Run unit tests once
npm run e2e       # Run end-to-end tests

TypeScript strict mode is enforced across the entire frontend codebase, including strictInjectionParameters and strictTemplates for Angular-specific checks. [17]


πŸ” Troubleshooting

Database won't connect

# Check if PostgreSQL is running and accepting connections
pg_isready -h localhost -p 5432

# Check Docker container health
docker-compose ps
docker logs somiishop-db

Ensure DB_HOST is set to db (the Docker service name) when running inside Docker, or localhost for local development. [29]

Port already in use

# Find and kill the process using port 8080
lsof -i :8080
kill -9 <PID>

# Or for the frontend port
lsof -i :4200
kill -9 <PID>

Flyway migration failed

If the database schema gets into an inconsistent state, reset and re-run all migrations:

cd backend
mvn flyway:clean flyway:migrate

⚠️ flyway:clean drops all database objects. Never run this against a production database.

Frontend can't reach the API

Verify the API_BASE_URL environment variable is set correctly [26]:

  • Docker: http://localhost:8080/api/v1
  • Local dev: Ensure the backend is running on port 8080 and CORS allows http://localhost:4200 [28]

Stripe webhook not firing locally

Use the Stripe CLI to forward events to your local server:

stripe listen --forward-to localhost:8080/api/v1/payments/webhook

The CLI will print a webhook signing secret β€” use that value as STRIPE_WEBHOOK_SECRET.


πŸ—ΊοΈ Implementation Roadmap

This scaffold ships with all infrastructure wired up. The NEXT_STEPS.md file contains a detailed 10-phase implementation guide to build out a production marketplace. [64]

What's already done [65]

  • βœ… Project structure (Spring Boot backend, Angular frontend, Docker)
  • βœ… PostgreSQL schema with Flyway migrations (all tables created)
  • βœ… Core entities: User, Profile, Product, Category, Order, OrderItem, Payment, Review, Address
  • βœ… Security scaffolding: CORS, BCrypt, session management, JWT filter
  • βœ… Frontend services: AuthService, AuthGuard, RoleGuard

Implementation phases

Phase Focus Area Estimated Effort
1 Complete Authentication (JWT service, AuthController, EmailService) 1–2 days
2 Product Catalog (ProductService, ProductController, S3 integration) 2–3 days
3 Shopping Cart (CartService, CartController) 1–2 days
4 Checkout & Stripe Connect (StripeService, webhooks) 3–4 days
5 Orders & Delivery Tracking (OrderService, OrderController) 2–3 days
6 Reviews (ReviewService with verified-purchase check) 1–2 days
7 Seller Onboarding (Stripe Connect account creation) 2 days
8 Admin Dashboard (KPIs, user management) 3–4 days
9 Profile & UI Polish (responsive design, ProfileController) 2–3 days
10 Testing & Deployment (unit, integration, E2E, CI/CD) 2–3 days

Post-MVP enhancements [66]

Real-time notifications (WebSocket) Β· Automated seller payouts Β· Seller analytics Β· Shipping API integration Β· Product variants Β· Wish lists Β· Advanced search (Elasticsearch) Β· Mobile app Β· Live chat Β· Loyalty programme


πŸ“„ License

This project is licensed under the MIT License. See the LICENSE file for details.

↑ Back to top

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages