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.
- 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
- 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
- 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
- Atomic Stock Management β Race-condition-free inventory via JPQL
@Modifyingqueries (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
GlobalExceptionHandlerforResourceNotFoundException,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
BehaviorSubjectboilerplate)
| 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 |
| 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 |
| 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 |
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
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 |
| 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 |
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) |
| 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 |
| 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 |
- Node.js v18+
- Java JDK 21
- PostgreSQL (running instance)
- Maven 3.8+
-
Navigate to
backend/:cd backend -
Copy the example env file and fill in your values:
cp .env.example .env
-
Edit
.envwith 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
-
Build and run:
mvn clean install mvn spring-boot:run
The backend will start on
http://localhost:8080.
-
Navigate to
frontend/:cd frontend -
Install dependencies:
npm install
-
Start the dev server:
npm start
-
Open your browser at
http://localhost:4200.
| 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
rolecolumn toROLE_ADMINin theuserstable for the desired user.
- Signup β User created β JWT generated β token stored in DB β token returned to client β auto-login
- Signin β Credentials validated β new JWT generated β old session token replaced β token returned
- Every Request β
JwtAuthenticationFilterextracts token fromAuthorizationheader β validates β verifies session token in DB β setsSecurityContext - Logout β Token removed from localStorage β user redirected to login
| 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 |
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.
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
- 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 correspondingImplclasses, following OCP and DIP. - DRY Token Generation β
AuthServiceImpluses a privategenerateAndSaveToken(User)method shared by bothsignup()andsignin(). - UserService Abstraction β
UserRepositoryis only accessed within theuser/package. All other domains use theUserServiceinterface, reducing coupling. - Long userId Pattern β Service methods accept
Long userIdinstead of the fullUserentity. Controllers extract the ID from@AuthenticationPrincipaland pass only the ID downstream. - Atomic Stock Operations β
ProductRepository.decrementStock()andrestoreStock()use JPQL@Modifyingqueries to prevent race conditions during concurrent checkout and order cancellation. - Cart Cascade Pattern β Cart items are managed via JPA's
CascadeType.ALL+orphanRemovalthroughcart.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 β
GlobalExceptionHandlerreturns structured error responses forResourceNotFoundException,BadRequestException, and validation errors. - Environment Variables β Spring Boot loads configuration from
backend/.envviaspring.config.import. See.env.examplefor all required keys.