Skip to content

ShivamKarna/Merchant-Hub-API

Repository files navigation

πŸͺ Merchant Hub API

TypeScript Node.js Express PostgreSQL Redis Docker License: ISC

A production-ready, scalable RESTful API for merchant and e-commerce management

Getting Started β€’ API Documentation β€’ Features β€’ Architecture β€’ Contributing


Table of Contents


Features

Core Features

  • ** Product Management** - Full CRUD operations with advanced filtering, sorting, and pagination
  • Order Management - Complete order lifecycle with status tracking
  • Authentication - JWT-based secure authentication
  • Authorization - Role-Based (RBAC) and Attribute-Based (ABAC) access control
  • High Performance - Redis caching for optimized response times
  • API Documentation - Interactive Swagger/OpenAPI documentation

Technical Features

  • Containerized - Docker and Docker Compose ready for any environment
  • Type-Safe ORM - Drizzle ORM with full TypeScript support
  • Input Validation - Zod schema validation for all endpoints
  • Error Handling - Centralized error handling with structured responses
  • Health Checks - Built-in health monitoring endpoints
  • Graceful Shutdown - Proper cleanup of connections on termination

Tech Stack

Category Technology
Runtime Node.js 20+
Language TypeScript 5.9
Framework Express 5.x
Database PostgreSQL 16
ORM Drizzle ORM
Cache Redis 7
Validation Zod
Documentation Swagger/OpenAPI
Containerization Docker & Docker Compose
Package Manager pnpm

Getting Started

Prerequisites

Ensure you have the following installed:

Installation

  1. Clone the repository ```bash git clone https://github.com/shivamkarn1/Merchant-Hub-API.git cd Merchant-Hub-API ```

  2. Install dependencies ```bash pnpm install ```

Environment Setup

  1. Create environment file ```bash cp .env.example .env ```

  2. Configure environment variables ```env

    Server

    NODE_ENV=development PORT=6767

    Database

    DATABASE_URL=postgresql://postgres:postgres@localhost:5432/merchant_hub

    Redis

    REDIS_URL=redis://localhost:6379

    JWT

    JWT_SECRET=your-super-secret-key-change-in-production ```

Database Setup

  1. Create the database ```bash createdb merchant_hub ```

  2. Run migrations ```bash pnpm db:migrate ```

  3. Generate migrations (for schema changes) ```bash pnpm db:generate ```

  4. View database with Drizzle Studio ```bash pnpm db:studio ```

Running the Application

Development mode (with hot-reload): ```bash pnpm dev ```

Production mode: ```bash pnpm build pnpm start ```

The API will be available at `http://localhost:6767\`


🐳 Docker Deployment

Development with Docker

Start all services with hot-reload enabled:

```bash

Start development environment

docker-compose -f docker-compose.dev.yml up -d

View logs

docker-compose -f docker-compose.dev.yml logs -f api

Stop services

docker-compose -f docker-compose.dev.yml down ```

Optional: Enable Redis Commander for GUI access: ```bash docker-compose -f docker-compose.dev.yml --profile tools up -d

```

Production Deployment

  1. Build and start production services ```bash

    Build the image

    docker-compose build

    Start services

    docker-compose up -d

    Check status

    docker-compose ps ```

  2. Run migrations in container ```bash docker-compose exec api pnpm db:migrate ```

  3. View logs ```bash docker-compose logs -f api ```

  4. Stop and remove containers ```bash docker-compose down

    Remove volumes (WARNING: deletes data)

    docker-compose down -v ```

Docker Services:

Service Port Description
`api` 6767 Main API application
`postgres` 5432 PostgreSQL database
`redis` 6379 Redis cache server

API Documentation

Interactive Documentation

Swagger UI is available at: ``` http://localhost:6767/api-docs ```

OpenAPI specification (JSON): ``` http://localhost:6767/api-docs.json ```

Authentication

All protected endpoints require JWT authentication:

```http Authorization: Bearer <your_jwt_token> ```

User Roles:

Role Description Permissions
`super_admin` Full system access All operations
`admin` Administrative access Manage all resources
`merchant` Merchant-level access Own resources only
`customer` Customer-level access Own data only
`viewer` Read-only access View resources

Products API

Method Endpoint Description Auth
`GET` `/api/v1/products/allProducts` Get all products with filtering ❌
`GET` `/api/v1/products/allProducts/search` Search products ❌
`GET` `/api/v1/products/:id` Get product by ID βœ…
`POST` `/api/v1/products/create` Create new product βœ…
`PUT` `/api/v1/products/update/:id` Update product βœ…
`DELETE` `/api/v1/products/delete/:id` Delete product (soft) βœ…

Query Parameters for GET /products/allProducts:

Parameter Type Description
`q` string Search in name/description
`sku` string Filter by SKU
`minPrice` number Minimum price filter
`maxPrice` number Maximum price filter
`inStock` boolean Filter by stock availability
`sortBy` string Sort field (`price`, `name`, `created_at`)
`sortOrder` string Sort direction (`asc`, `desc`)
`limit` number Items per page (max: 100)
`offset` number Pagination offset

Orders API

Method Endpoint Description Auth Permission
`GET` `/api/v1/orders` Get all orders (filtered by role) βœ… `orders.read`
`GET` `/api/v1/orders/:id` Get order by ID βœ… `orders.read`
`POST` `/api/v1/orders/create` Create new order βœ… `orders.create`
`PUT` `/api/v1/orders/:id/status` Update order status βœ… `orders.update`
`PUT` `/api/v1/orders/:id/cancel` Cancel order βœ… `orders.cancel`

Health Check

```http GET /health ```

Response: ```json { "status": "healthy", "timestamp": "2025-11-26T10:30:00.000Z", "uptime": 3600, "version": "1.0.0" } ```


πŸ—οΈ Architecture

Project Structure

``` merchant-api/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ app.ts # Express app configuration β”‚ β”œβ”€β”€ index.ts # Application entry point β”‚ β”œβ”€β”€ config/ β”‚ β”‚ └── swagger.ts # Swagger/OpenAPI configuration β”‚ β”œβ”€β”€ controllers/ # Request handlers β”‚ β”‚ β”œβ”€β”€ orders/ β”‚ β”‚ β”‚ └── orders.controller.ts β”‚ β”‚ └── products/ β”‚ β”‚ β”œβ”€β”€ product.validation.ts β”‚ β”‚ └── products.controller.ts β”‚ β”œβ”€β”€ db/ # Database layer β”‚ β”‚ β”œβ”€β”€ db.ts # Database connection β”‚ β”‚ β”œβ”€β”€ schema.ts # Combined schema exports β”‚ β”‚ β”œβ”€β”€ orders.schema.ts # Orders table schema β”‚ β”‚ β”œβ”€β”€ products.schema.ts # Products table schema β”‚ β”‚ └── users.schema.ts # Users table schema β”‚ β”œβ”€β”€ middlewares/ # Express middlewares β”‚ β”‚ β”œβ”€β”€ abac.middleware.ts # Attribute-based access control β”‚ β”‚ β”œβ”€β”€ auth.middleware.ts # JWT authentication β”‚ β”‚ β”œβ”€β”€ errorHandler.ts # Global error handler β”‚ β”‚ └── rbac.middleware.ts # Role-based access control β”‚ β”œβ”€β”€ routes/ # Route definitions β”‚ β”‚ β”œβ”€β”€ orders/ β”‚ β”‚ β”‚ └── orders.routes.ts β”‚ β”‚ └── products/ β”‚ β”‚ └── products.routes.ts β”‚ β”œβ”€β”€ services/ # Business logic β”‚ β”‚ β”œβ”€β”€ orders/ β”‚ β”‚ β”‚ └── orders.service.ts β”‚ β”‚ └── products/ β”‚ β”‚ └── products.service.ts β”‚ β”œβ”€β”€ types/ # TypeScript type definitions β”‚ β”‚ β”œβ”€β”€ auth.types.ts β”‚ β”‚ └── express.d.ts β”‚ └── utils/ # Utility functions β”‚ β”œβ”€β”€ ApiError.ts β”‚ β”œβ”€β”€ ApiResponse.ts β”‚ β”œβ”€β”€ asyncHandler.ts β”‚ β”œβ”€β”€ handleZodError.ts β”‚ β”œβ”€β”€ HttpStatusCodes.ts β”‚ └── redis.ts # Redis client & caching β”œβ”€β”€ drizzle/ # Database migrations β”œβ”€β”€ docker-compose.yml # Production Docker setup β”œβ”€β”€ docker-compose.dev.yml # Development Docker setup β”œβ”€β”€ Dockerfile # Production Dockerfile β”œβ”€β”€ Dockerfile.dev # Development Dockerfile β”œβ”€β”€ drizzle.config.ts # Drizzle ORM configuration β”œβ”€β”€ package.json β”œβ”€β”€ tsconfig.json └── README.md ```

Database Schema

``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ users β”‚ β”‚ products β”‚ β”‚ orders β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ id β”‚ β”‚ id β”‚ β”‚ id β”‚ β”‚ email β”‚ β”‚ name β”‚ β”‚ order_number β”‚ β”‚ name β”‚ β”‚ description β”‚ β”‚ customer_id β”‚ β”‚ password_hash β”‚ β”‚ sku β”‚ β”‚ merchant_id β”‚ β”‚ role β”‚ β”‚ price β”‚ β”‚ status β”‚ β”‚ merchant_id β”‚ β”‚ stock β”‚ β”‚ total_amount β”‚ β”‚ parent_user_id β”‚ β”‚ merchant_id β”‚ β”‚ currency β”‚ β”‚ is_active β”‚ β”‚ created_by β”‚ β”‚ shipping_addr β”‚ β”‚ created_at β”‚ β”‚ created_at β”‚ β”‚ billing_addr β”‚ β”‚ updated_at β”‚ β”‚ updated_at β”‚ β”‚ created_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ deleted_at β”‚ β”‚ updated_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ order_items β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ id β”‚ β”‚ order_id β”‚ β”‚ product_id β”‚ β”‚ quantity β”‚ β”‚ unit_price β”‚ β”‚ subtotal β”‚ β”‚ created_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ```

Caching Strategy

Redis caching is implemented with the following TTLs:

Cache Type TTL Description
Product List 2 min Paginated product queries
Single Product 5 min Individual product details
Order List 1 min User-specific order lists
Single Order 2 min Individual order details

Cache Invalidation:

  • Product cache invalidated on create/update/delete
  • Order cache invalidated on create/status update/cancel

Security

  • JWT Authentication - Stateless token-based authentication
  • RBAC - Role-based permission system
  • ABAC - Attribute-based resource access control
  • Input Validation - Zod schema validation on all inputs
  • SQL Injection Prevention - Parameterized queries via Drizzle ORM
  • Security Headers - X-Content-Type-Options, X-Frame-Options, X-XSS-Protection
  • Non-root Docker User - Container runs as unprivileged user

βš™οΈ Configuration

Environment Variables

Variable Required Default Description
`NODE_ENV` No `development` Environment mode
`PORT` No `6767` Server port
`DATABASE_URL` Yes - PostgreSQL connection string
`REDIS_URL` No `redis://localhost:6379` Redis connection string
`JWT_SECRET` Yes - JWT signing secret
`PGSSLMODE` No - PostgreSQL SSL mode

NPM Scripts

Script Description
`pnpm dev` Start development server with hot-reload
`pnpm build` Build TypeScript to JavaScript
`pnpm start` Start production server
`pnpm db:generate` Generate database migrations
`pnpm db:migrate` Run database migrations
`pnpm db:studio` Open Drizzle Studio GUI

πŸ§ͺ Testing

```bash

Run tests (coming soon)

pnpm test ```


🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch ```bash git checkout -b feature/amazing-feature ```
  3. Commit your changes ```bash git commit -m 'feat: add amazing feature' ```
  4. Push to the branch ```bash git push origin feature/amazing-feature ```
  5. Open a Pull Request

Commit Convention

This project follows Conventional Commits:

  • `feat:` - New features
  • `fix:` - Bug fixes
  • `docs:` - Documentation changes
  • `style:` - Code style changes
  • `refactor:` - Code refactoring
  • `test:` - Test additions/changes
  • `chore:` - Build process/auxiliary tools

πŸ“„ License

This project is licensed under the ISC License - see the LICENSE file for details.


Made with ❀️ by Shivam Karn

⭐ Star this repository if you find it helpful!

About

A Scalable Backend service for managing merchants, products, orders, and role-based operations using TypeScript, Drizzle ORM, Redis and PostgreSQL.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors