Loading repository data…
Loading repository data…
Samin1362 / repository
NexCart Backend is a TypeScript-based e-commerce API built with Express and MongoDB, featuring JWT auth, role-based access, AI-powered tools via Google Gemini, and a clean MVC structure for scalable and maintainable backend development.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
A full-featured e-commerce REST API built with Express 5, TypeScript, and Mongoose 9. Features JWT authentication, role-based access control, AI-powered features via Google Gemini, comprehensive admin dashboard analytics, and a fully automated CI/CD pipeline.
Server/
├── src/
│ ├── __tests__/
│ │ └── setup.ts # Vitest global setup (MongoDB Memory Server)
│ ├── config/
│ │ ├── index.ts # Environment config loader
│ │ └── firebase-admin.ts # Firebase Admin SDK init
│ ├── controllers/
│ │ ├── auth.controller.ts # Register, login, refresh, logout
│ │ ├── user.controller.ts # Profile & admin user management
│ │ ├── category.controller.ts
│ │ ├── product.controller.ts
│ │ ├── review.controller.ts
│ │ ├── cart.controller.ts
│ │ ├── order.controller.ts
│ │ ├── dashboard.controller.ts
│ │ ├── ai.controller.ts # Gemini AI features
│ │ └── __tests__/ # Route integration tests
│ ├── middlewares/
│ │ ├── auth.middleware.ts # JWT verification
│ │ ├── role.middleware.ts # Role-based authorization
│ │ ├── validate.middleware.ts
│ │ └── __tests__/ # Middleware unit/integration tests
│ ├── models/
│ │ ├── user.model.ts
│ │ ├── category.model.ts
│ │ ├── product.model.ts
│ │ ├── review.model.ts
│ │ ├── cart.model.ts
│ │ └── order.model.ts
│ ├── routes/
│ │ ├── auth.routes.ts
│ │ ├── user.routes.ts
│ │ ├── category.routes.ts
│ │ ├── product.routes.ts
│ │ ├── review.routes.ts
│ │ ├── cart.routes.ts
│ │ ├── order.routes.ts
│ │ ├── dashboard.routes.ts
│ │ └── ai.routes.ts
│ ├── types/
│ │ └── index.ts # All TypeScript interfaces
│ ├── utils/
│ │ ├── errors.ts # Custom error classes
│ │ ├── helpers.ts # Slug generator
│ │ ├── response.ts # Standardized API responses
│ │ └── __tests__/ # Utility unit tests
│ ├── app.ts # Express app configuration
│ ├── server.ts # MongoDB connection & server start
│ └── seed.ts # Database seeder with demo data
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI/CD pipeline
├── .env
├── eslint.config.mjs # ESLint flat config
├── vitest.config.ts # Vitest configuration
├── package.json
└── tsconfig.json
cd Server
npm install
Create a .env file in the Server directory:
PORT=5001
MONGODB_URI=mongodb+srv://<username>:<password>@cluster0.mongodb.net/nexcart
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
GEMINI_API_KEY=your_gemini_api_key
npm run dev
Populates the database with demo users, categories, products, reviews, and orders:
npm run seed
npm run build
npm start
| Role | Password | |
|---|---|---|
| Admin | admin@nexcart.com | 123456 |
| Admin | manager@nexcart.com | 123456 |
| User | john@nexcart.com | 123456 |
| User | jane@nexcart.com | 123456 |
| User | bob@nexcart.com | 123456 |
The project uses GitHub Actions for continuous integration and Render for continuous deployment. Every push to main or master automatically runs the full pipeline.
Push to main/master
│
▼
┌─────────────────────┐
│ Lint & Build Job │
│ ───────────────── │
│ 1. ESLint check │
│ 2. TypeScript check│
│ 3. Build (tsc) │
└────────┬────────────┘
│ (passes)
▼
┌─────────────────────┐
│ Test Job │
│ ───────────────── │
│ 133 tests via │
│ Vitest + Supertest │
│ (in-memory MongoDB)│
└────────┬────────────┘
│ (passes)
▼
┌─────────────────────┐
│ Render Auto-Deploy │
│ (main branch only) │
└─────────────────────┘
The workflow file is at .github/workflows/ci.yml. It runs two sequential jobs:
Job 1 — Lint & Build (lint-and-build):
npm ci --ignore-scripts)npm run lint)npm run typecheck)npm run build)Job 2 — Test (test, runs after lint-and-build):
npm test) with CI-safe environment variablesThe test job only runs if the lint-and-build job passes, preventing unnecessary test runs on broken code.
Tests use Vitest for the test runner, Supertest for HTTP integration testing, and mongodb-memory-server to spin up a real in-memory MongoDB instance — no external database needed in CI.
src/
├── __tests__/setup.ts # Global setup: starts MongoDB, sets env vars, wipes collections between tests
├── utils/__tests__/helpers.test.ts # generateSlug — 11 tests
├── utils/__tests__/errors.test.ts # Custom error classes — 18 tests
├── utils/__tests__/response.test.ts # sendSuccess / sendError — 9 tests
├── middlewares/__tests__/
│ ├── validate.test.ts # Zod validation middleware — 17 tests
│ ├── role.test.ts # authorize() RBAC middleware — 5 tests
│ └── auth.test.ts # authenticate() JWT middleware — 7 integration tests
└── controllers/__tests__/
├── auth.test.ts # /api/auth routes — 16 tests
├── category.test.ts # /api/categories routes — 12 tests
├── product.test.ts # /api/products routes — 15 tests
├── cart.test.ts # /api/cart routes — 10 tests
└── order.test.ts # /api/orders routes — 13 tests
Total: 133 tests
# Run all tests once
npm test
# Run in watch mode (re-runs on file changes)
npm run test:watch
# Run with coverage report
npm run test:coverage
Coverage reports are generated in coverage/ (text output + lcov for CI tools).
| Command | Description |
|---|---|
npm run dev | Start dev server with hot reload |
npm run build | Compile TypeScript to JavaScript |
npm start | Run compiled production build |
npm run seed | Seed database with demo data |
npm run lint | Run ESLint on all source files |
npm run lint:fix | Run ESLint and auto-fix fixable issues |
npm run typecheck | TypeScript type-check without emitting files |
npm test | Run full test suite (133 tests) |
npm run test:watch | Run tests in watch mode |
npm run test:coverage | Run tests with coverage report |
The backend is deployed on Render at the production URL. Render is connected to the main branch and auto-deploys whenever a push reaches main — which only happens after the full CI pipeline passes on GitHub Actions.
Deployment flow:
master → CI runsmaster is merged into main → Render detects the pushnpm run build, then npm startAll endpoints return a standardized response:
{
"success": true,
"message": "Description of the result",
"data": {},
"meta": {
"page": 1,
"limit": 10,
"total": 50,
"totalPages": 5
}
}
Error responses:
{
"success": false,
"message": "Error description",
"errorDetails": "Technical details (dev only)"
}
The API uses JWT-based authentication with access and refresh tokens.
Authorization: Bearer <token> header| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/health | No | API health status |
/api/auth)| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /register | No | Register new user |
| POST | /login | No | Login and get access + refresh tokens |
| POST | /refresh-token | No | Get new access token using refresh |
| POST | /logout | Yes | Logout and invalidate refresh token |
POST /register
{
"name": "John Doe",
"email": "john@example.com",
"password": "123456"
}
POST /login
{
"email": "john@example.com",
"password": "123456"
}
Returns: { accessToken, refreshToken, user }
POST /refresh-token
{
"refreshToken": "your_refresh_token"
}
Returns: { accessToken, refreshToken }
/api/users)| Method | Endpoint | Auth | Role | Description |
|---|---|---|---|---|
| GET | /me | Yes | Any | Get current user profile |
| PATCH | /me | Yes | Any | Update own profile |
| GET | / | Yes | Admin | List all users (paginated) |
| GET | /:id | Yes | Admin | Get user by ID |
| PATCH | /:id | Yes | Admin | Update user (role, block status) |
| DELETE | /:id | Yes | Admin | Delete user (cannot self-delete) |
PATCH /me (allowed fields: name, phone, avatar, address)
{
"name": "Updated Name",
"phone": "+8801711000000",
"address": {
"street": "123 Main St",
"city": "Dhaka",
"state": "Dhaka",
"zipCode": "1200",
"country": "Bangladesh"
}
}
GET / (query params: page, limit, search)
/api/categories)| Method | Endpoint | Auth | Role | Description |
|---|---|---|---|---|
| GET | / | No | - | List all categories |
| GET | /:slug | No | - | Get category by slug |
| POST | / | Yes | Admin | Create category |
| PATCH | /:id | Yes | Admin | Update category |
| DELETE | /:id | Yes | Admin | Delete category (blocked if has products) |
POST /
{
"name": "Electronics",
"description":