Skip to content

hungCS22hcmiu/ecommerce-system

Repository files navigation

E-Commerce Microservices Platform

Distributed e-commerce backend built with Go, Java/Spring Boot, and Python. Six services communicate over synchronous REST and an asynchronous Kafka choreography saga, fronted by an Nginx gateway and a React 19 SPA. Includes semantic product search powered by pgvector, a reviews/ratings system, in-app notifications, and a seller management portal.

Service Map

Service Language Port Key Pattern
user-service Go (Gin + GORM) 8001 Bcrypt worker pool · Redis-only lockout · RS256 JWT
product-service Java/Spring Boot 8081 Conditional UPDATE (atomic stock) · Redis cache-aside · pgvector AI search · reviews/ratings
cart-service Go (Gin + GORM) 8002 Redis-first · WATCH/MULTI/EXEC · product-validation cache · circuit breaker
order-service Java/Spring Boot 8082 Pessimistic lock · Transactional outbox → Kafka · in-app notifications
payment-service Go (Gin) 8003 Idempotency key · Kafka saga · PENDING-resume · DLQ
ai-service Python (FastAPI) 9000 sentence-transformers sidecar · POST /embed
frontend React 19 + Vite → Nginx 3001 TanStack Query · Zustand · JWT interceptor
nginx nginx:alpine 80 Reverse proxy · rate limiting · CORS · dynamic DNS resolver

All external traffic enters through port 80 (Nginx). Services are not directly exposed in production.

Quick Start

# 1. Configure environment
cp .env.example .env          # fill in SMTP credentials if you want email verification

# 2. Generate JWT keys (first time only)
mkdir -p user-service/keys
openssl genrsa -out user-service/keys/private.pem 2048
openssl rsa -in user-service/keys/private.pem -pubout -out user-service/keys/public.pem

# 3. Start the full stack
docker compose up --build -d

# 4. Seed sample users (admin / customer / seller — all pre-verified)
make db-seed

The React frontend is available at http://localhost:3001 and the API at http://localhost/api/v1/....

Sample credentials (from script/sample_users.sql):

  • Customer: customer@example.com / Customer@123
  • Seller: seller@example.com / Seller@123
  • Admin: admin@example.com / Admin@123

Architecture

Browser → Nginx :80 → user-service   :8001  (auth, profiles, public seller profile)
                    → product-service:8081  (catalog, inventory, AI search, reviews)
                    → cart-service   :8002  (Redis-first cart)
                    → order-service  :8082  (orders, notifications, transactional outbox)
                    → payment-service:8003  (Kafka consumer, saga, PENDING-resume)

product-service ──REST──▶  ai-service:9000          (embed query / write-through re-embed)
product-service ──REST──▶  order-service:8082        (review notification, fire-and-forget)

order-service   ──outbox──▶  orders.created            ──▶  payment-service
payment-service ──kafka───▶  payments.completed/failed  ──▶  order-service

Databases: Single PostgreSQL instance, 5 logical databases (ecommerce_users/products/carts/orders/payments). Schemas auto-applied from script/init-databases.sql at container start.

Redis: sessions + JWT blacklist (user-service) · primary cart store (cart-service) · cache-aside (product-service). AOF (dev): appendfsync everysec + no-appendfsync-on-rewrite yes (eliminates fsync stalls during AOF rewrite). In production tune appendfsync to always for max durability or no for max throughput.

AI Search: ai-service runs all-MiniLM-L6-v2 (384 dims) locally. Products are embedded on create/update (write-through) and searchable via cosine similarity with pgvector.

Project Structure

ecommerce-system/
├── ai-service/                  # Python FastAPI — sentence-transformers embedding sidecar
│   ├── main.py
│   ├── scripts/embed_products.py
│   ├── tests/
│   └── Dockerfile
├── cart-service/                # Go (Gin + GORM) — Redis-first cart
│   ├── cmd/server/
│   ├── internal/                # handler · service · repository · cache · client · dto · model
│   ├── pkg/                     # jwt · response
│   ├── migrations/
│   └── Dockerfile
├── order-service/               # Java/Spring Boot — orders, outbox, notifications
│   ├── src/main/
│   ├── src/test/
│   └── Dockerfile
├── payment-service/             # Go (Gin) — Kafka saga, idempotency
│   ├── cmd/server/
│   ├── internal/                # handler · service · repository · kafka · gateway · dto · model
│   ├── pkg/                     # jwt · response
│   ├── migrations/
│   └── Dockerfile
├── product-service/             # Java/Spring Boot — catalog, AI search, reviews
│   ├── src/main/
│   ├── src/test/
│   └── Dockerfile
├── user-service/                # Go (Gin + GORM) — auth, profiles
│   ├── cmd/server/
│   ├── internal/                # handler · service · repository · middleware · dto · model
│   ├── pkg/                     # jwt · session · blacklist · password · email · verification
│   ├── migrations/
│   ├── keys/                    # RS256 PEM keys (gitignored in prod)
│   └── Dockerfile
├── frontend/                    # React 19 + Vite → Nginx SPA
│   ├── src/
│   │   ├── components/          # shared UI components
│   │   ├── features/            # domain hooks (cart, orders, products, payment, auth)
│   │   ├── pages/               # route-level page components
│   │   ├── store/               # Zustand auth store
│   │   ├── lib/                 # axios instance with JWT interceptor
│   │   └── types/
│   ├── tests/e2e/               # Playwright end-to-end tests
│   └── Dockerfile
├── nginx/
│   └── nginx.conf               # reverse proxy, rate limiting, CORS, security headers
├── api/
│   └── openapi.yaml             # full REST API contract
├── script/
│   ├── init-databases.sql       # all 5 DB schemas, auto-applied on startup
│   ├── sample_users.sql         # seed: admin / customer / seller (pre-verified)
│   ├── e2e-test.sh              # 14-assertion browse → cart → order test
│   ├── e2e-payment.sh           # 12-assertion Kafka saga test
│   ├── loadtest-orders.sh       # 100 concurrent orders race test
│   └── k6/                      # k6 load test scripts per scenario
├── docs/
│   ├── adrs/                    # architecture decision records
│   ├── planning/                # development and migration plans
│   ├── technical/               # deep-dive technical docs with diagrams
│   └── testing/                 # test plans and phase results
├── docker-compose.yml
├── Makefile
└── .env.example

Common Commands

# Infrastructure only
make infra-up          # postgres + redis
docker compose up -d zookeeper kafka   # add Kafka for order/payment flows

# Full stack
make up                # docker compose up -d
make down              # docker compose down
make ps                # container status

# Database
make db-shell          # psql shell
make db-seed           # insert sample users
make db-nuke           # wipe all volumes and reinitialise

# Rebuild a single service after code changes
docker compose build cart-service && docker compose up -d cart-service

# Backfill product embeddings (run once after seeding)
docker compose run --rm ai-service python scripts/embed_products.py

Testing

# Go services — unit tests (race detector)
cd user-service    && go test -race ./...
cd cart-service    && go test -race ./...
cd payment-service && go test -race ./...

# Go services — integration tests (requires postgres + redis running)
cd user-service    && go test -tags=integration -v -race ./internal/integration/
cd cart-service    && go test -tags=integration -v -race ./internal/integration/
cd payment-service && go test -tags=integration -v -race ./internal/integration/

# Java services (Testcontainers — no external deps needed)
cd product-service && ./mvnw test
cd order-service   && ./mvnw test

# ai-service
cd ai-service && pytest tests/

# End-to-end (full stack must be running on port 80)
bash script/e2e-test.sh          # browse → cart → order (14 assertions)
bash script/e2e-payment.sh       # Kafka saga: order → payment → confirm/cancel (12 assertions)
bash script/loadtest-orders.sh   # 100 orders at 10 concurrent, asserts 0 PENDING + 0 DLQ
bash script/perf-baseline.sh     # single-threaded latency baseline

Pages & Routes

Route Description Auth
/ Home — featured products No
/products Product list with keyword + AI search, pagination No
/products/:id Product detail — gallery, reviews, ratings, infinite-scroll related products No
/categories Category browse grid No
/categories/:slug Products filtered by category No
/sellers/:id Public seller shop page No
/cart Cart with item images and seller grouping Yes
/checkout Checkout — address selection, order summary Yes
/orders/:id/confirmation Order confirmation + payment polling Yes
/orders Order history Yes
/orders/:id Order detail — items, timeline, product thumbnails Yes
/profile Profile and address management Yes
/seller/products My Products — list, sort, filter, "Highest Rated" Seller
/seller/products/new Create product Seller
/seller/products/:id/edit Edit product Seller
/seller/orders Orders received — filter by status Seller
/seller/orders/:id Seller order detail Seller

Documentation

Document Description
docs/technical/service_integration.md How all services communicate (HTTP, Kafka, JWT) — with Mermaid diagrams
docs/technical/architecture.md Overall system design and data flow
docs/technical/concurrency_control.md Concurrency strategies per service (conditional UPDATE, WATCH/EXEC, pessimistic lock)
docs/technical/async_payment.md Async payment saga with Kafka — choreography, DLQ, idempotency
docs/technical/Redis-First Architect.md Redis-first cart architecture with circuit breaker deep dive
docs/technical/concurrent workloads.md Concurrent workloads — load-test scenarios and results
docs/technical/reliability.md Reliability validation — failure modes and recovery paths
docs/technical/security-checklist.md OWASP API Top 10 audit results per service
docs/planning/development.md Development environment setup guide
docs/planning/databaseMigration.md Migration strategy (Flyway + golang-migrate)
docs/planning/convention.md Code style and API conventions
docs/adrs/locking-strategy.md Concurrency strategy rationale per service
docs/adrs/saga-resilience.md Kafka saga and DLQ design decisions
cart-service/README.md cart-service deep dive (Redis WATCH, circuit breaker, sync worker)
order-service/README.md order-service deep dive (state machine, notifications, seller view)
ai-service/README.md ai-service deep dive (model, endpoints, backfill script)
api/openapi.yaml Full REST API contract
CLAUDE.md AI assistant context (service internals, key files, commands)

Environment Variables

Key variables (all documented in .env.example):

Variable Default Used by
PRODUCT_SERVICE_URL http://product-service:8081 cart-service, order-service
ORDER_SERVICE_URL http://order-service:8082 product-service (review notifications)
AI_SERVICE_URL http://ai-service:9000 product-service
KAFKA_BROKERS kafka:29092 order-service, payment-service
JWT_PRIVATE_KEY_PATH ./keys/private.pem user-service
JWT_PUBLIC_KEY_PATH ./keys/public.pem cart-service, payment-service, order-service
SMTP_HOST/PORT/USERNAME/PASSWORD user-service (email verification)

About

A Simple E-commerce Distributed System built with Claude Code

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors