Skip to content

SOURABHs23/ECommerce

Repository files navigation

πŸ›’ ShopHub β€” E-Commerce Application

A full-stack E-Commerce application built with Angular 18 and Spring Boot 3, featuring a modern storefront, role-based access, concurrency-safe inventory management, and a complete order lifecycle.


πŸš€ Features

Storefront

  • Home Page β€” Dynamic landing page with hero banner, personalized greetings (logged-in users), category showcase, and featured products
  • Product Browsing β€” Paginated product listing with keyword search, category filtering, and price-range filtering
  • Product Detail β€” Rich product view with image gallery, quantity selector, and stock status
  • Shopping Cart β€” Add, update quantity, remove items, and real-time cart totals via Angular signals
  • Add-to-Cart Feedback β€” Premium toast notifications (Angular Material Snackbar) showing product name and a "View Cart" action button
  • Auth-Guarded Cart β€” Unauthenticated users clicking "Add to Cart" are redirected to login with a returnUrl, then sent back after authentication
  • Checkout β€” Select/create shipping addresses, review order summary, and place orders
  • Order History β€” View past orders and their statuses

User Account

  • JWT Authentication β€” Secure signup, sign-in, and token-protected API routes
  • Auto-Login on Signup β€” Token returned on registration for seamless onboarding
  • Session Token Storage β€” Server-side token stored in DB for logout and single-session enforcement
  • Cart Sync on Login β€” Cart state loads immediately after login/signup so the header badge is always accurate
  • OTP Verification β€” Phone number verification via Twilio SMS with scheduled cleanup of expired OTPs
  • Address Book β€” Full CRUD for shipping addresses with default address management

Admin Panel

  • Dashboard β€” Admin overview of the store
  • Product Management β€” Create, edit, and delete products with image uploads
  • Category Management β€” Full CRUD for product categories
  • Order Management β€” View all orders and update order statuses

Cross-Cutting Concerns

  • Atomic Stock Management β€” Race-condition-free inventory via JPQL @Modifying queries (decrementStock / restoreStock) β€” no concurrent overselling
  • Database Indexing β€” Composite indexes on high-traffic query paths (product active/category, order user/date, cart item uniqueness) for optimized performance
  • Email Notifications β€” Order confirmation emails via Gmail SMTP with HTML templates (OrderEmailComposer)
  • SMS Notifications β€” OTP delivery via Twilio
  • Global Exception Handling β€” Structured error responses via GlobalExceptionHandler for ResourceNotFoundException, BadRequestException, and validation errors
  • Input Validation β€” Request DTO validation with Bean Validation annotations
  • CORS Configuration β€” Pre-configured for Angular dev server on localhost:4200
  • Responsive UI β€” Modern interface built with Angular Material + CSS Grid/Flexbox
  • Angular Signals β€” Reactive state management for cart, products, and UI state (no RxJS BehaviorSubject boilerplate)

πŸ› οΈ Technology Stack

Backend

Component Technology
Framework Spring Boot 3.2.1
Language Java 21
Database PostgreSQL
ORM Spring Data JPA / Hibernate
Security Spring Security + JWT (jjwt 0.12.3)
Validation Spring Boot Starter Validation
Email Spring Boot Starter Mail
SMS Twilio SDK 9.14.1
Scheduling Spring @Scheduled (OTP cleanup)
Auditing JPA @EntityListeners + @CreatedDate / @LastModifiedDate
Boilerplate Lombok 1.18.42
Build Tool Maven

Frontend

Component Technology
Framework Angular 18 (Standalone Components)
Language TypeScript 5.5
UI Library Angular Material 18 + Angular CDK
State Management Angular Signals (signal, computed)
Notifications Angular Material Snackbar
Styling SCSS + CSS Grid / Flexbox
HTTP HttpClient + functional interceptors
Routing Lazy-loaded standalone components
JWT Handling jwt-decode
Build Tool Angular CLI

πŸ“‚ Project Structure

ECommerce/
β”œβ”€β”€ backend/                              # Spring Boot Application
β”‚   β”œβ”€β”€ src/main/java/com/ecommerce/
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ common/                       # ── Shared Infrastructure ──
β”‚   β”‚   β”‚   β”œβ”€β”€ config/                   #   SecurityConfig
β”‚   β”‚   β”‚   β”œβ”€β”€ security/                 #   JwtAuthenticationFilter, JwtTokenProvider,
β”‚   β”‚   β”‚   β”‚                             #   JwtUtils, CookieService + Impl
β”‚   β”‚   β”‚   β”œβ”€β”€ exception/                #   BadRequestException, ResourceNotFoundException
β”‚   β”‚   β”‚   β”œβ”€β”€ handler/                  #   GlobalExceptionHandler
β”‚   β”‚   β”‚   └── dto/                      #   ApiResponse
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ auth/                         # ── πŸ” Auth Domain ──
β”‚   β”‚   β”‚   β”œβ”€β”€ AuthController            #   /api/auth (signup, signin)
β”‚   β”‚   β”‚   β”œβ”€β”€ AuthService (interface)   #   Signup, Signin contracts
β”‚   β”‚   β”‚   β”œβ”€β”€ AuthServiceImpl           #   DRY token generation via generateAndSaveToken()
β”‚   β”‚   β”‚   └── dto/                      #   SignInRequest, SignUpRequest, AuthResponse
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ user/                         # ── πŸ‘€ User Domain ──
β”‚   β”‚   β”‚   β”œβ”€β”€ User (entity)             #   JPA entity with session token
β”‚   β”‚   β”‚   β”œβ”€β”€ UserRepository            #   Data access (package-private usage)
β”‚   β”‚   β”‚   β”œβ”€β”€ UserService (interface)   #   Centralized user access for all domains
β”‚   β”‚   β”‚   β”œβ”€β”€ UserServiceImpl           #   Implementation
β”‚   β”‚   β”‚   └── HomeController            #   / (personalized greetings API)
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ product/                      # ── πŸ“¦ Product Domain ──
β”‚   β”‚   β”‚   β”œβ”€β”€ ProductController         #   /api/products (CRUD, search, filter, featured)
β”‚   β”‚   β”‚   β”œβ”€β”€ ProductService + Impl     #   Business logic
β”‚   β”‚   β”‚   β”œβ”€β”€ ImageService + Impl       #   Product image management
β”‚   β”‚   β”‚   β”œβ”€β”€ Product, ProductImage     #   JPA entities (with composite indexes)
β”‚   β”‚   β”‚   β”œβ”€β”€ ProductRepository         #   Data access + atomic stock operations
β”‚   β”‚   β”‚   └── ProductRequest, ProductResponse
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ category/                     # ── πŸ“‚ Category Domain ──
β”‚   β”‚   β”‚   β”œβ”€β”€ CategoryController        #   /api/categories
β”‚   β”‚   β”‚   β”œβ”€β”€ CategoryService + Impl    #   CRUD with parent-child categories
β”‚   β”‚   β”‚   β”œβ”€β”€ Category                  #   JPA entity
β”‚   β”‚   β”‚   β”œβ”€β”€ CategoryRepository        #   Data access
β”‚   β”‚   β”‚   └── CategoryRequest, CategoryResponse
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ cart/                         # ── πŸ›’ Cart Domain ──
β”‚   β”‚   β”‚   β”œβ”€β”€ CartController            #   /api/cart (add, update, remove, clear)
β”‚   β”‚   β”‚   β”œβ”€β”€ CartService + Impl        #   Cascade-based item management
β”‚   β”‚   β”‚   β”œβ”€β”€ Cart, CartItem            #   JPA entities (OneToMany cascade, unique constraint)
β”‚   β”‚   β”‚   β”œβ”€β”€ CartRepository            #   JPQL fetch join for eager loading
β”‚   β”‚   β”‚   β”œβ”€β”€ CartItemRepository        #   Item-level queries
β”‚   β”‚   β”‚   └── CartItemRequest, CartResponse
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ order/                        # ── πŸ“‹ Order Domain ──
β”‚   β”‚   β”‚   β”œβ”€β”€ OrderController           #   /api/orders (create, list, cancel, status)
β”‚   β”‚   β”‚   β”œβ”€β”€ OrderService + Impl       #   Cartβ†’Order conversion, atomic stock, email triggers
β”‚   β”‚   β”‚   β”œβ”€β”€ Order, OrderItem, OrderStatus
β”‚   β”‚   β”‚   β”œβ”€β”€ OrderRepository           #   Data access (with composite indexes)
β”‚   β”‚   β”‚   └── OrderRequest, OrderResponse
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ address/                      # ── πŸ“ Address Domain ──
β”‚   β”‚   β”‚   β”œβ”€β”€ AddressController         #   /api/addresses
β”‚   β”‚   β”‚   β”œβ”€β”€ AddressService + Impl     #   CRUD + default address management
β”‚   β”‚   β”‚   β”œβ”€β”€ Address                   #   JPA entity (with user+default index)
β”‚   β”‚   β”‚   β”œβ”€β”€ AddressRepository         #   Data access
β”‚   β”‚   β”‚   └── AddressRequest, AddressResponse
β”‚   β”‚   β”‚
β”‚   β”‚   └── notification/                 # ── πŸ”” Notification Domain ──
β”‚   β”‚       β”œβ”€β”€ OtpController             #   /api/otp
β”‚   β”‚       β”œβ”€β”€ OtpService + Impl         #   OTP generate, send, verify
β”‚   β”‚       β”œβ”€β”€ OtpCleanupScheduler       #   @Scheduled cleanup of expired OTPs
β”‚   β”‚       β”œβ”€β”€ EmailService + Impl       #   Transactional order confirmation emails
β”‚   β”‚       β”œβ”€β”€ SmsService + Impl         #   Twilio SMS integration
β”‚   β”‚       β”œβ”€β”€ OrderEmailComposer        #   HTML email template builder
β”‚   β”‚       β”œβ”€β”€ Otp, OtpRepository        #   JPA entity + data access
β”‚   β”‚       └── SendEmailRequest, SendSmsRequest
β”‚   β”‚
β”‚   β”œβ”€β”€ .env.example                      # Template for environment variables
β”‚   └── pom.xml
β”‚
β”œβ”€β”€ frontend/                             # Angular 18 Application
β”‚   β”œβ”€β”€ src/app/
β”‚   β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”‚   β”œβ”€β”€ guards/                   # authGuard, adminGuard, homeRedirectGuard
β”‚   β”‚   β”‚   β”œβ”€β”€ interceptors/             # authInterceptor (JWT token attachment)
β”‚   β”‚   β”‚   β”œβ”€β”€ models/                   # TypeScript interfaces (User, Product, Cart, Order, Address, Category)
β”‚   β”‚   β”‚   └── services/                 # AuthService, ProductService, CartService, OrderService,
β”‚   β”‚   β”‚                                 # CategoryService, AddressService (barrel-exported via index.ts)
β”‚   β”‚   β”œβ”€β”€ features/
β”‚   β”‚   β”‚   β”œβ”€β”€ admin/                    # Dashboard, ProductForm (admin-only)
β”‚   β”‚   β”‚   β”œβ”€β”€ auth/                     # Login, Register (with returnUrl support)
β”‚   β”‚   β”‚   β”œβ”€β”€ cart/                     # Shopping cart page
β”‚   β”‚   β”‚   β”œβ”€β”€ checkout/                 # Checkout with address selection/creation
β”‚   β”‚   β”‚   β”œβ”€β”€ home/                     # Landing page with featured products & categories
β”‚   β”‚   β”‚   β”œβ”€β”€ orders/                   # Order history
β”‚   β”‚   β”‚   └── products/                 # ProductList (search, filter, pagination), ProductDetail
β”‚   β”‚   └── shared/
β”‚   β”‚       └── components/               # Header (nav + cart badge), Footer, ProductCard
β”‚   β”‚
β”‚   β”œβ”€β”€ src/styles.scss                   # Global theme: Material palette, snackbar styles, component overrides
β”‚   └── package.json
β”‚
β”œβ”€β”€ database_design.md                    # Full database schema documentation with ER diagram
β”œβ”€β”€ db_review.md                          # Senior architect database design review
└── ECommerce_API.postman_collection.json # Postman collection for all API endpoints

πŸ—οΈ Architecture

Domain-Driven Design (Microservice-Ready)

The backend is organized by business domain (vertical slicing), not by technical layer. Each domain package is self-contained with its own controller, service, entities, DTOs, and repositories β€” making it straightforward to extract into an independent microservice.

Domain Responsibility API Prefix
auth/ User registration & login, JWT token generation /api/auth
user/ User entity & centralized access for all domains /api/home
product/ Product catalog, search, filter, featured, images /api/products
category/ Product categories (parent-child hierarchy) /api/categories
cart/ Shopping cart with cascade-based item management /api/cart
order/ Cart→Order conversion, tracking, cancellation /api/orders
address/ Shipping address book with default management /api/addresses
notification/ Email (order confirmation), SMS (Twilio), OTP verification /api/otp

Concurrency & Data Integrity

Concern Implementation
Stock Overselling Atomic UPDATE ... WHERE stock >= :qty via JPQL @Modifying β€” returns 0 if insufficient, no race condition
Stock Restoration Automatic restoreStock() on order cancellation reverses the decrement atomically
Cart Deduplication Unique composite constraint on (cart_id, product_id) prevents duplicate cart entries at the DB level

Database Indexes

Performance-critical queries are backed by composite indexes:

Index Table Columns Query Optimized
idx_product_active products active Product listing
idx_product_category_active products category_id, active Category browsing
idx_product_featured_active products featured, active Homepage featured
idx_order_user_created orders user_id, created_at Order history
idx_order_number orders order_number Order lookup
idx_address_user_default addresses user_id, is_default Checkout
idx_cart_item_cart_product cart_items cart_id, product_id Add to cart (unique)

SOLID Principles Applied

Principle Implementation
Single Responsibility OTP cleanup in OtpCleanupScheduler; cookie logic in CookieService; email composition in OrderEmailComposer; token generation in generateAndSaveToken()
Open/Closed All services are interfaces with Impl classes β€” swap implementations without modifying consumers
Liskov Substitution EmailService.sendOrderConfirmation uses OrderResponse (typed) instead of Object
Interface Segregation Email composition separated from email sending; domain-specific concerns stay in their domain
Dependency Inversion Controllers depend on service interfaces; UserService abstracts all user data access across domains

Frontend Architecture

Pattern Implementation
Standalone Components No NgModules β€” each component declares its own imports
Lazy Loading All routes use loadComponent for code-splitting
Signals Reactive state via signal() and computed() for cart, products, and UI state
Barrel Exports index.ts files in models/ and services/ for clean imports
Functional Guards authGuard, adminGuard, homeRedirectGuard as CanActivateFn
Functional Interceptors authInterceptor as HttpInterceptorFn for JWT attachment

βš™οΈ Setup & Installation

1. Prerequisites

  • Node.js v18+
  • Java JDK 21
  • PostgreSQL (running instance)
  • Maven 3.8+

2. Backend Setup

  1. Navigate to backend/:

    cd backend
  2. Copy the example env file and fill in your values:

    cp .env.example .env
  3. Edit .env with your configuration:

    # Database
    DB_URL=jdbc:postgresql://localhost:5432/ecommerce
    DB_USERNAME=your_db_username
    DB_PASSWORD=your_db_password
    
    # JWT
    JWT_SECRET=YourSuperSecretKeyMustBeAtLeast256BitsLong
    
    # Email (Gmail App Password)
    SPRING_MAIL_USERNAME=your_email@gmail.com
    SPRING_MAIL_PASSWORD=your_app_password
    
    # Twilio SMS (optional β€” required for OTP)
    TWILIO_ACCOUNT_SID=your_twilio_account_sid
    TWILIO_AUTH_TOKEN=your_twilio_auth_token
    TWILIO_PHONE_NUMBER=+1234567890
  4. Build and run:

    mvn clean install
    mvn spring-boot:run

    The backend will start on http://localhost:8080.

3. Frontend Setup

  1. Navigate to frontend/:

    cd frontend
  2. Install dependencies:

    npm install
  3. Start the dev server:

    npm start
  4. Open your browser at http://localhost:4200.


πŸ” Security & Roles

Role Capabilities
USER Browse products, manage cart, manage addresses, place & track orders
ADMIN Create/edit/delete products & categories, view & update all orders

Note: To promote a user to admin, manually update the role column to ROLE_ADMIN in the users table for the desired user.

Authentication Flow

  1. Signup β†’ User created β†’ JWT generated β†’ token stored in DB β†’ token returned to client β†’ auto-login
  2. Signin β†’ Credentials validated β†’ new JWT generated β†’ old session token replaced β†’ token returned
  3. Every Request β†’ JwtAuthenticationFilter extracts token from Authorization header β†’ validates β†’ verifies session token in DB β†’ sets SecurityContext
  4. Logout β†’ Token removed from localStorage β†’ user redirected to login

API Access Rules

Endpoint Access
/api/auth/** Public
GET /api/products/** Public
/api/products/** Admin only (CUD operations)
GET /api/categories/** Public
/api/categories/** Admin only (CUD operations)
/api/cart/** Authenticated users (USER role)
/api/orders/** Authenticated users (USER role)
/api/addresses/** Authenticated users (USER role)
/api/otp/** Authenticated users

πŸ“ API Documentation

A complete Postman collection is provided at the project root:

ECommerce_API.postman_collection.json

Import this file into Postman to explore and test all endpoints.


πŸ“Š Database Design

Full database schema documentation is available in database_design.md, including:

  • ER Diagram β€” Mermaid-based entity relationship diagram
  • 10 Table Definitions β€” users, addresses, categories, products, product_images, carts, cart_items, orders, order_items, otps
  • Relationship Summary β€” All FK relationships with cascade behaviors
  • Key Design Decisions β€” Price snapshots, self-referential categories, soft deletes, UUID order numbers, automatic auditing

πŸ§‘β€πŸ’» Development Notes

  • Domain-Driven Structure β€” Each backend domain is a self-contained module with its own controller, service interface, implementation, entities, repositories, and DTOs. This enables clean microservice extraction when needed.
  • Service Interfaces β€” All business logic is behind interfaces (CartService, OrderService, etc.) with corresponding Impl classes, following OCP and DIP.
  • DRY Token Generation β€” AuthServiceImpl uses a private generateAndSaveToken(User) method shared by both signup() and signin().
  • UserService Abstraction β€” UserRepository is only accessed within the user/ package. All other domains use the UserService interface, reducing coupling.
  • Long userId Pattern β€” Service methods accept Long userId instead of the full User entity. Controllers extract the ID from @AuthenticationPrincipal and pass only the ID downstream.
  • Atomic Stock Operations β€” ProductRepository.decrementStock() and restoreStock() use JPQL @Modifying queries to prevent race conditions during concurrent checkout and order cancellation.
  • Cart Cascade Pattern β€” Cart items are managed via JPA's CascadeType.ALL + orphanRemoval through cart.addItem(), ensuring the in-memory entity stays in sync with the DB.
  • Standalone Components β€” The Angular frontend uses standalone components with lazy-loaded routes (no NgModules).
  • Signal-Based State β€” Cart count, authentication status, and UI state are all managed via Angular signals for fine-grained reactivity.
  • Global Error Handling β€” GlobalExceptionHandler returns structured error responses for ResourceNotFoundException, BadRequestException, and validation errors.
  • Environment Variables β€” Spring Boot loads configuration from backend/.env via spring.config.import. See .env.example for all required keys.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors