Skip to content

anasFaleh/E-commerce-API

Repository files navigation

E-Commerce API

A production-ready RESTful e-commerce backend built with NestJS, Prisma, and PostgreSQL. Supports full e-commerce workflows with JWT authentication, role-based access control, and Swagger documentation.


Table of Contents


Overview

This project is a fully-featured e-commerce REST API designed for real-world use. It covers the complete shopping flow — from user registration and product browsing, to cart management, checkout, and order tracking.

Built on a modular NestJS architecture, it emphasizes security, maintainability, and developer experience, making it a solid foundation for any e-commerce product.


Features

  • Authentication — JWT access tokens (15 min) + HTTP-only refresh token cookies (7 days) with rotation and reuse detection
  • Role-Based Access ControlUSER and ADMIN roles enforced via guards and decorators
  • Product Catalog — Full CRUD with category filtering, price range filtering, and full-text search
  • Shopping Cart — Persistent per-user cart with add/update/remove operations
  • Checkout & Orders — Atomic checkout with stock decrement; order history and cancellation
  • Product Reviews — One review per user per product; filterable by rating, product, and user
  • Image Uploads — Secure file uploads (JPEG, PNG, WebP, GIF; max 5 MB) with static serving
  • Global ValidationValidationPipe with whitelist stripping and type transformation
  • Centralized Error Handling — Global exception filter with Prisma error code mapping
  • Request Logging — Winston logger with per-request timing via an interceptor
  • Rate Limiting — Global throttle (100 req/60s) + stricter limits on auth endpoints (5 req/60s)
  • API Documentation — Interactive Swagger UI at /api/docs

Tech Stack

Category Technology
Framework NestJS v11, Node.js
Language TypeScript v5
Database PostgreSQL
ORM Prisma v6
Auth Passport.js, JWT, bcrypt
Validation class-validator, class-transformer, Joi
Logging Winston, nest-winston
Documentation Swagger / OpenAPI
File Uploads Multer
Security Helmet, CORS, express-rate-limit
Caching @nestjs/cache-manager

Project Structure

src/
├── auth/               # Authentication (signup, login, logout, token refresh)
│   ├── dto/
│   ├── guards/
│   └── strategies/
├── product/            # Product catalog (CRUD, search, filtering)
│   └── dto/
├── category/           # Product categories (CRUD)
│   └── dto/
├── cart/               # Shopping cart (add, update, remove items)
│   └── dto/
├── order/              # Checkout and order management
│   └── dto/
├── review/             # Product reviews and ratings
│   └── dto/
├── user/               # User profile management
│   └── dto/
├── uploads/            # Product image uploads
├── prisma/             # Prisma service and module
├── common/             # Shared utilities
│   ├── decorators/     # @Public, @Roles, @GetUser, @GetRefreshToken
│   ├── guards/         # RolesGuard
│   ├── filters/        # AllExceptionsFilter
│   └── logger/         # LoggerInterceptor, Winston config
├── config/             # App and auth configuration factories
├── app.module.ts
└── main.ts
prisma/
├── schema.prisma       # Database schema
└── migrations/
uploads/
└── images/             # Stored product images (static served)

Getting Started

Prerequisites

Installation

# Clone the repository
git clone https://github.com/anasFaleh/Simple-E-commerce-App.git
cd Simple-E-commerce-App

# Install dependencies (also auto-generates Prisma client via postinstall)
npm install

Environment Variables

Create a .env file in the project root:

# Database
DATABASE_URL=postgresql://username:password@localhost:5432/ecommerce_db

# JWT Secrets — use long, random strings (minimum 32 characters)
JWT_SECRET=your-super-secret-jwt-access-key-here
JWT_REFRESH_SECRET=your-super-secret-jwt-refresh-key-here

# Application
NODE_ENV=development
PORT=3000

# CORS — comma-separated list of allowed origins
ALLOWED_ORIGINS=http://localhost:4200,http://localhost:3000

Security Note: Never commit your .env file. Use strong, unique secrets for JWT_SECRET and JWT_REFRESH_SECRET in production.

Database Setup

# Apply all migrations to your database
npx prisma migrate deploy

# (Optional) Open Prisma Studio to browse data
npx prisma studio

Running the App

# Development (watch mode)
npm run start:dev

# Production
npm run build
npm run start:prod

The API will be available at http://localhost:3000/api/v1/.


API Documentation

Interactive Swagger UI is available at:

http://localhost:3000/api/docs

All endpoints, request bodies, and response schemas are documented there.


API Endpoints

Auth

Method Endpoint Auth Description
POST /api/v1/auth/signup Public Register a new user account
POST /api/v1/auth/login Public Login and receive tokens
POST /api/v1/auth/Refresh Refresh Cookie Rotate access + refresh tokens
POST /api/v1/auth/Logout Bearer JWT Revoke session and clear cookie

Auth endpoints (signup/login) are throttled to 5 requests per minute.

Products

Method Endpoint Auth Role Description
GET /api/v1/products Public List products (filter by category, price range, pagination)
GET /api/v1/products/search Public Full-text search by name/description (?q=, ?page=, ?limit=)
GET /api/v1/products/:id Public Get a single product by ID
POST /api/v1/products JWT ADMIN Create a new product
PUT /api/v1/products/:id JWT ADMIN Update a product
DELETE /api/v1/products/:id JWT ADMIN Delete a product

Categories

Method Endpoint Auth Role Description
GET /api/v1/categories Public List all categories
GET /api/v1/categories/:id Public Get a single category
POST /api/v1/categories JWT ADMIN Create a category
PATCH /api/v1/categories/:id JWT ADMIN Update a category
DELETE /api/v1/categories/:id JWT ADMIN Delete a category

Cart

Method Endpoint Auth Description
GET /api/v1/carts JWT Get the current user's cart with totals
POST /api/v1/carts/add JWT Add a product to the cart
PUT /api/v1/carts/item/:itemId JWT Update cart item quantity
DELETE /api/v1/carts/item/:itemId JWT Remove an item from the cart

Orders

Method Endpoint Auth Role Description
POST /api/v1/orders/checkout JWT Checkout: convert cart to order (atomic)
GET /api/v1/orders JWT List the current user's orders
GET /api/v1/orders/:id JWT Get a single order
PATCH /api/v1/orders/:id/cancel JWT Cancel a PENDING order (restores stock)
PATCH /api/v1/orders/:id/status JWT ADMIN Update order status

Order status flow: PENDINGCONFIRMEDSHIPPEDDELIVERED

Reviews

Method Endpoint Auth Description
GET /api/v1/reviews Public List reviews (filter by productId, userId, rating, pagination)
GET /api/v1/reviews/:id Public Get a single review
POST /api/v1/reviews JWT Create a review (one per user per product)
PUT /api/v1/reviews/:id JWT Update your own review
DELETE /api/v1/reviews/:id JWT Delete your own review

Users

Method Endpoint Auth Description
GET /api/v1/users/:id JWT Get a user's profile
PATCH /api/v1/users/:id JWT Update your own profile
DELETE /api/v1/users/:id JWT Delete your own account

Uploads

Method Endpoint Auth Role Description
POST /api/v1/uploads/products/:productId JWT ADMIN Upload a product image (multipart/form-data)
GET /api/v1/uploads/products/:productId Public Get a product's image URL
DELETE /api/v1/uploads/products/:productId JWT ADMIN Delete a product's image

Uploaded images are served statically at:

http://localhost:3000/static/images/:filename

Authentication & Authorization

This API uses a dual-token authentication strategy:

Token Type TTL Location
Access Token JWT 15 minutes Authorization: Bearer <token>
Refresh Token JWT 7 days HTTP-only cookie (refresh_token)

How it works:

  1. On login, the server returns an access token in the response body and sets a refresh token as an HTTP-only cookie.
  2. When the access token expires, call POST /auth/Refresh — the server validates the refresh token cookie, checks the stored jti, and issues a new token pair.
  3. If a refresh token is reused after it has already been rotated, the session is fully revoked (reuse detection).
  4. On logout, the server clears the refresh token from the database and expires the cookie.

Role-based access is enforced using the @Roles() decorator and RolesGuard. Public routes are marked with the @Public() decorator, which bypasses the global JwtGuard.


Database Schema

User         — id, email, name, role, hash, RT (refresh token jti)
Product      — id, name, description, price, stock, imageUrl, categoryId, userId
Category     — id, name
Cart         — id, userId (1-to-1 with User)
CartItem     — id, cartId, productId, quantity
Order        — id, userId, status, totalAmount
OrderItem    — id, orderId, productId, quantity, unitPrice (price snapshot at checkout)
Review       — id, userId, productId, rating, comment

Each user has exactly one persistent cart. OrderItem stores a price snapshot at checkout time so historical order totals remain accurate even if product prices change later.


Scripts

npm run start:dev     # Start in watch mode (development)
npm run start:prod    # Start compiled app (production)
npm run build         # Compile TypeScript and generate Prisma client
npm run lint          # Run ESLint with auto-fix
npm run format        # Format code with Prettier
npm test              # Run unit tests
npm run test:cov      # Run tests with coverage report
npm run test:e2e      # Run end-to-end tests

License

This project is licensed under the MIT License.

About

E-commece backend API with authentication, caching, product management

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors