Robust Node.js REST API built with TypeScript, Express.js, and MongoDB.
It powers the Shoishob platform, handling authentication, payments, and data access with production-grade security and code quality tooling.
| Area | What You Get | Packages / Techniques |
|---|---|---|
| Typed Code | End-to-end TypeScript, strict tsconfig |
typescript, ts-node-dev |
| Scalable API | Layered architecture (Routes β Controllers β Services β Models) | express, mongoose |
| Authentication | Stateless JWT auth (access + refresh tokens) | jsonwebtoken, HTTP-only cookies |
| Payments | Fully-integrated SSL Commerz flow (initiate β redirect β IPN) | sslcommerz-lts |
| Validation | Runtime payload validation & type inference | zod |
| Error Handling | Centralized error classes + global handler | Custom ApiError, catchAsync |
| Security | Helmet, rate-limiting, CORS, .env isolation |
helmet, express-rate-limit, cors, dotenv |
| Dev Ex | Lint, format, pre-commit hooks, VS Code launch | eslint, prettier, husky, lint-staged |
| CI-ready | Dockerfile & GitHub Actions workflow (optional) | see Deployment |
Shoihob-backend follows a modular architecture with distinct components that handle specific business domains. The system is built using Node.js with Express framework and TypeScript, connecting to a MongoDB database for data persistence and integrating with SSLCommerz for payment processing.
The system follows a layered architecture pattern that promotes separation of concerns and maintainability.
This layer is responsible for handling HTTP requests and routing them to appropriate business logic.
- Routes: Define API endpoints and connect them to corresponding controllers.
- Controllers: Manage the request/response lifecycle and delegate core operations to services.
- Middleware: Intercepts and processes requests before they reach the controller (e.g., authentication, input validation, error handling).
The API is organized as a RESTful service with versioned endpoints. All routes are prefixed with /api/v1 and are organized by functionality. The Express router maps incoming requests to the appropriate controller functions.
This layer contains Service Classes that encapsulate the core logic of the application. It:
- Implements domain-specific rules and use cases.
- Coordinates actions involving multiple models or external services.
- Keeps controllers lean and focused on the request flow.
Responsible for communicating with the database using Mongoose. It includes:
- Schemas & Models: Define data structures and constraints for MongoDB collections.
- CRUD Operations: Abstracts direct database operations and enforces a consistent access pattern.
The Shoihob-backend is structured into several key modules, each responsible for a distinct business function. This modular approach ensures better scalability, maintainability, and separation of concerns.
| Module | Path | Description |
|---|---|---|
| User | /user |
Handles user registration, profile management, and role-based access control. |
| Auth | /jwt |
Manages authentication using JWT tokens. |
| Turf | /turf |
Manages sports field listings, details, and maintenance. |
| Booking | /bookings |
Handles turf reservation, scheduling, and payment processing. |
| Payment History | /history |
Stores and manages transaction records and payment history. |
| Tournament | /tournament-details |
Enables creation and management of tournaments. |
| Tournament Registration | /tournamentRegistration |
Facilitates user registration and participation in tournaments. |
| Admin Stats | /stats |
Provides analytics and system insights for administrators. |
| Owner Stats | /ownerStats |
Delivers usage analytics specifically for turf owners. |
| Module | Description |
|---|---|
| User Module | Manages user accounts, profiles, and role-based access control (user, admin, superAdmin). |
| Authentication Module | Implements secure JWT-based authentication and authorization. |
| Turf Details Module | Handles sports venue data including availability, pricing, and location. |
| Turf Booking Module | Manages turf reservations, slot selection, payment processing, and confirmation. |
| Payment History Module | Tracks all transaction records, including bookings and tournament registrations. |
| Tournament Module | Manages tournament creation, scheduling, and turf associations. |
| Tournament Registration Module | Handles user registration for tournaments, with integrated payment processing. |
| Statistics Module | Provides analytical dashboards and metrics for admins and turf owners. |
π Source Root:
src/app/routes/index.ts
Each module adheres to a standardized internal structure, which improves code readability, collaboration, and scalability:
src/
βββ app/
βββ [module-name]/
βββ controllers/ # Handles HTTP request/response logic
βββ services/ # Contains core business logic
βββ models/ # Mongoose schemas and data access definitions
βββ routes/ # Defines REST API endpoints
βββ validators/ # Joi or Zod schemas for request validation (if any)
The following diagram illustrates how a typical request flows through the system:
The system implements JWT (JSON Web Token) based authentication and role-based authorization.
The system uses MongoDB as its database and Mongoose for object data modeling. The following diagram illustrates the key data models and their relationships:
The system implements a global error handling mechanism to ensure consistent error responses across all API endpoints.
The system integrates with external services, particularly for payment processing:
src/
βββ app/
β βββ module/
β β βββ User/
β β β βββ User.controller.ts
β β β βββ User.service.ts
β β β βββ User.model.ts
β β β βββ User.interface.ts
β β β βββ User.constant.ts
β β β βββ User.validation.ts
β β βββ Payment/ (etc.)
β βββ common/ # shared middlewares & utils
βββ config/ # mongo, sslcommerz, etc.
βββ constance/ # enumerations & magic numbers
βββ errors/ # ApiError, global handler
βββ shared/ # helpers (catchAsync, sendResponse, pick)
βββ app.ts # Express app
βββ server.ts # entry point (env, DB connect, graceful shutdown)
- Node.js 20.4+ (LTS recommended)
- Yarn 4.9+ or npm 10+
- MongoDB (Atlas or local)
- SSL Commerz merchant account
# 1. Clone
git clone https://github.com/tareksabbir/shoishob-backend.git
cd shoishob-backend
# 2. Install
yarn install # or: npm ci
# 3. Configure
cp .env.example .env # fill real secrets
# 4. Run dev server (auto-restart, TS support)
yarn startVisit [http://localhost:5000 /health](http://localhost:5000 /health) β should return {status:"OK"}.
| Name | Example | Required | Description |
|---|---|---|---|
NODE_ENV |
development |
β | development / production |
PORT |
5000 |
β | API port |
DATABASE_URL |
mongodb+srv://... |
β | Mongo connection string |
JWT_SECRET |
s3cr3t |
β | HS256 signing secret |
JWT_EXPIRES_IN |
1d |
β | Token TTL |
STORE_ID |
shoishob_live |
β | SSL Commerz store id |
STORE_PASSWORD |
abcd1234 |
β | SSL Commerz key |
CLIENT_URL |
https://shoishob.app |
β | CORS allow-list |
RATE_LIMIT_WINDOW |
15 |
β | minutes |
RATE_LIMIT_MAX |
100 |
β | reqs per window |
| Command | What it does |
|---|---|
yarn start |
Start dev server with ts-node-dev |
yarn build |
Compile TypeScript to dist |
yarn start:prod |
Run compiled JS with node |
yarn lint:check |
ESLint analysis |
yarn lint:fix |
ESLint auto-fix |
yarn prettier:check |
Format check |
yarn prettier:fix |
Auto-format |
yarn test |
(add Jest tests soon) |
yarn lint-prettier |
Lint + format in one go |
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN yarn install --prod
COPY . .
RUN yarn build
CMD ["node", "dist/server.js"]docker build -t shoishob-api .
docker run -p 5000:5000 --env-file .env shoishob-api# .github/workflows/deploy.yml
name: Deploy
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: yarn install --immutable
- run: yarn test # add tests!
- run: yarn build
# TODO: docker push / ssh deploy / render.com deployβ¦- Unit tests: pure functions, services (
jest,ts-jest) - Integration tests: Express routes with in-memory Mongo (
supertest,mongodb-memory-server) - E2E: Postman/Newman or Playwright against staging
Add a
__tests__/folder mirroringsrc/. Aim for 80%+ coverage on business logic.
- Install:
yarn add swagger-ui-express swagger-jsdoc - Define specs in
docs/openapi.yaml(see sample below). - Mount swagger UI in
app.ts:
import swaggerUi from 'swagger-ui-express'
import specs from './docs'
app.use('/docs', swaggerUi.serve, swaggerUi.setup(specs))Now GET /docs shows live API reference.
-
helmet()HTTP headers -
express-rate-limit100 req/15 min per IP -
.envnever committed (git ignored) - Mongo connection retries, graceful shutdown
- Mongoose ObjectId sanitization (
mongoose-unique-validator) - Unit tests for auth & permissions
- TODO: Enable CSRF protection for cookie-based auth
- TODO: Turn on log redaction for sensitive fields
import { ApiError } from './errors'
import httpStatus from 'http-status'
throw new ApiError(httpStatus.BAD_REQUEST, 'Email already exists')All thrown ApiErrors propagate to the global handler β client gets a consistent JSON error envelope:
- Client hits
POST /api/v1/payments/initwith cart & customer info. - Server creates transaction, gets
GatewayPageURL, returns to client. - Client redirects user β SSL Commerz hosted checkout.
- After payment, SSL Commerz calls
IPNβPOST /api/v1/payments/ipn. - We verify signature, update order status, trigger webhooks or emails.
- User redirected back to our success or cancel page.
- main β always deployable
- dev β integration branch
feature/xyz,bugfix/123β short-lived topic branches
Commit messages follow Conventional Commits:
feat(user): add password reset
fix(payment): correct amount rounding
- Fork & create a topic branch:
git checkout -b feat/cool-stuff - Run
yarn lint-prettierand add tests. - Commit & push, then open a Pull Request.
All PRs trigger CI: lint, tests, type-check.
- β Refresh-token rotation & logout-all
- β 2-FA (TOTP)
- β Soft-delete + audit logs
- β GraphQL gateway (stretch goal)
Mongo fails to connect on first start
Check that the DATABASE_URL in .env points to an SRV Atlas URL or your local instance, and your IP is whitelisted in Atlas.
How do I seed initial data?
Run yarn ts-node scripts/seed.ts (script coming soon).
Md. Tarek Rahman Sabbir β https://github.com/tareksabbir
{ "success": false, "message": "Email already exists", "statusCode": 400, "stack": "..." // only in dev }