MCPcopy Index your code
hub / github.com/arifintahu/project-structure-api

github.com/arifintahu/project-structure-api @v3.0.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.0.0 ↗ · + Follow
123 symbols 251 edges 55 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

[![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Stargazers][stars-shield]][stars-url] [![Issues][issues-shield]][issues-url]

Project Structure API

A production-ready project template for building RESTful APIs with TypeScript, Express, and Sequelize






<a href="https://github.com/arifintahu/project-structure-api/issues">Report Bug</a>
·
<a href="https://github.com/arifintahu/project-structure-api/issues">Request Feature</a>

Table of Contents

  1. About The Project
  2. Architecture
  3. Getting Started
  4. Docker
  5. Usage
  6. API Reference
  7. OpenAPI Spec
  8. Testing
  9. Project Structure
  10. Contributing

About The Project

A clean, scalable Node.js API boilerplate with proper separation of concerns. Built with modern tooling (Node 22+, TypeScript 5.7, ESLint 9) and production-grade features including security hardening, structured logging, health checks, graceful shutdown, and CI/CD.

Built With

Category Technology
Runtime Node.js v22+
Language TypeScript 5.7
Framework Express.js 4.x
ORM Sequelize 6.x
Database PostgreSQL
Auth JSON Web Token + bcrypt
Security Helmet + express-rate-limit
Docs Swagger (swagger-jsdoc + swagger-ui-express)
Testing Jest + ts-jest + Supertest
Linting ESLint 9 (flat config) + Prettier
CI/CD GitHub Actions
Container Docker + Docker Compose

Features

  • Layered architecture — Routes → Controllers → Services → Repositories → Models
  • Security hardening — Helmet headers, rate limiting, body size limits, env-based CORS
  • Request tracingX-Request-Id UUID per request, included in logs and response headers
  • Structured logging — JSON format in production (for log aggregation), colorized in development
  • Health checkGET /health with database connectivity status
  • Graceful shutdown — Handles SIGTERM/SIGINT, drains connections, closes DB pool
  • DB connection pooling — Configurable Sequelize pool (min/max/acquire/idle)
  • Typed error handling — Custom AppError hierarchy with proper HTTP status codes
  • Consistent API responsesApiResponse utility for uniform success/error/paginated responses
  • Pagination — Built-in paginated list endpoints with ?page=1&limit=10
  • Password hashing — Automatic bcrypt hashing via Sequelize model hooks
  • Environment validation — Required env vars checked at startup with clear errors
  • JWT authentication — Token-based auth with role-based access control
  • OpenAPI 3.0 — Inline JSDoc specs co-located with routes + JSON spec export
  • Docker — Multi-stage build, non-root user, health check, Compose with PostgreSQL
  • CI/CD — GitHub Actions pipeline (lint → build → test)
  • Pre-commit hooks — Husky + lint-staged for ESLint and Prettier on commit

(back to top)

Architecture

Request → Route → Middleware (auth, validation) → Controller → Service → Repository → Model → DB
                                                      ↓
                                               ApiResponse (success/error)
Layer Responsibility Example
Routes HTTP method + URL mapping, middleware chaining POST /api/v1/users
Middlewares Auth, validation, rate limiting, request ID Auth.authenticate, Validate(...)
Controllers Parse request, call service, send response UserController.createUser
Services Business logic, validation rules UserService.createUser
Repositories Database queries via Sequelize UserRepository.getUsers
Models Schema definition, hooks, associations User, Role

(back to top)

Getting Started

Prerequisites

  • Node.js v22 or higher
  • PostgreSQL server running (or use Docker)
  • npm (comes with Node.js)

Installation

  1. Clone or use as template

    sh git clone https://github.com/arifintahu/project-structure-api.git cd project-structure-api

    Or click Use this template on GitHub.

  2. Install dependencies

    sh npm ci

  3. Configure environment

    sh cp .env.example .env

    Edit .env with your settings:

    ```env NODE_ENV=development APP_NAME=my-project SERVER=development PORT=3001 SECRET=your-secret-key API_VERSION=v1

    CORS

    CORS_ORIGIN=*

    Rate Limiting

    RATE_LIMIT_WINDOW_MS=900000 RATE_LIMIT_MAX=100

    Database

    DB_HOST=localhost DB_DATABASE=mydb DB_USERNAME=postgres DB_PASSWORD=postgres DB_PORT=5432 DB_DIALECT=postgres DB_TIMEZONE=Asia/Jakarta DB_LOG=true

    Database Connection Pool

    DB_POOL_MIN=2 DB_POOL_MAX=10 ```

    Required vars: DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD. The app will fail fast with a clear error if any are missing.

  4. Build the project

    sh npm run build

  5. Sync database tables

    sh npm run sync-db

  6. Start the server

    sh npm run start

    For development with auto-reload:

    sh npm run start-watch

  7. Verify

(back to top)

Docker

Run the entire stack (API + PostgreSQL) with Docker Compose:

# Start services
docker compose up --build

# Start in background
docker compose up --build -d

# Stop services
docker compose down

# Stop and remove volumes
docker compose down -v

The Compose file includes:

  • app — Node API built with multi-stage Dockerfile (non-root user, health check)
  • db — PostgreSQL 16 Alpine with persistent volume and health check

Environment variables can be overridden via .env file or inline:

DB_PASSWORD=mysecret PORT=8080 docker compose up --build

(back to top)

Usage

Adding a New Resource

Follow this pattern to add a new resource (e.g., Product):

  1. Model — Create src/api/models/Product.ts with Sequelize schema
  2. Repository interface — Create src/api/repositories/interfaces/IProductRepository.ts
  3. Repository — Create src/api/repositories/ProductRepository.ts
  4. Service interface — Create src/api/services/interfaces/IProductService.ts
  5. Service — Create src/api/services/ProductService.ts
  6. Controller — Create src/api/controllers/ProductController.ts
  7. Validation — Add rules in src/api/middlewares/validator/requirements/
  8. Routes — Create src/api/routes/v1/products.ts with inline @swagger JSDoc, register in src/api/routes/v1/index.ts
  9. Tests — Add __test__/ folders in repositories and services

Error Handling

Use typed errors in services for proper HTTP status codes:

import { NotFoundError, ConflictError } from '../../errors/AppError';

// 404 - Resource not found
throw new NotFoundError('Product not found');

// 409 - Conflict (duplicate)
throw new ConflictError('Product SKU must be unique');

// 401 - Unauthorized
throw new UnauthorizedError('Invalid credentials');

// 403 - Forbidden
throw new ForbiddenError('Insufficient permissions');

// 422 - Validation error
throw new ValidationError('Invalid input data');

API Responses

Controllers use ApiResponse for consistent response format:

import ApiResponse from '../../utils/response/ApiResponse';

// Standard response
ApiResponse.success(res, 'Product created', product, 201);

// Paginated response
ApiResponse.paginated(res, 'Products fetched', paginatedResult);

Response formats:

// Success
{ "message": "Product created", "data": { ... } }

// Paginated
{ "message": "Products fetched", "items": [...], "total": 50, "page": 1, "limit": 10, "totalPages": 5 }

// Error
{ "message": "Product not found", "statusCode": 404 }

Pagination

List endpoints accept query parameters:

GET /api/v1/users?page=2&limit=20

Default: page=1, limit=10.

Available Scripts

Script Description
npm run start Start the server
npm run start-watch Start with auto-reload (nodemon)
npm run build Compile TypeScript to dist/
npm run build-watch Compile with watch mode
npm run test Run tests with coverage
npm run test:noCoverage Run tests without coverage
npm run lint Run ESLint
npm run prettier Format code with Prettier
npm run sync-db Sync Sequelize models to database

(back to top)

API Reference

Health

Method Endpoint Description Auth
GET /health Health check with DB status No

Authentication

Method Endpoint Description Auth
POST /api/v1/login Login with email/password No
POST /api/v1/signup Register new user No

Users

Method Endpoint Description Auth
GET /api/v1/users?page=1&limit=10 List users (paginated) Admin
POST /api/v1/users Create user Admin
GET /api/v1/users/:id Get user details Admin
PUT /api/v1/users/:id Update user Admin
DELETE /api/v1/users/:id Delete user Admin

Roles

Method Endpoint Description Auth
GET /api/v1/roles List roles Admin
POST /api/v1/roles Create role Admin

Use Authorization: Bearer <token> header for authenticated endpoints.

(back to top)

OpenAPI Spec

API documentation uses OpenAPI 3.0 with inline @swagger JSDoc annotations co-located with route definitions. This means the spec stays in sync with the code automatically.

Swagger UI

Available in development at /docs/v1:

http://localhost:3001/docs/v1

JSON Spec Export

Get the raw OpenAPI JSON spec (useful for client SDK generation):

GET http://localhost:3001/docs/v1/spec.json

Use this with tools like:

  • openapi-generator — Generate client SDKs in any language
  • Postman — Import collection from OpenAPI spec
  • Redoc — Alternative API docs renderer

Adding Docs to a New Route

Add @swagger JSDoc comments directly above route definitions:

```

Extension points exported contracts — how you extend this code

IUserService (Interface)
(no doc) [4 implementers]
src/api/services/interfaces/IUserService.ts
SuccessResponse (Interface)
(no doc)
src/utils/response/ApiResponse.ts
Request (Interface)
(no doc)
src/@types/index.d.ts
IRoleService (Interface)
(no doc) [4 implementers]
src/api/services/interfaces/IRoleService.ts
PaginatedData (Interface)
(no doc)
src/utils/response/ApiResponse.ts
IAuthService (Interface)
(no doc) [3 implementers]
src/api/services/interfaces/IAuthService.ts
IUserRepository (Interface)
(no doc) [2 implementers]
src/api/repositories/interfaces/IUserRepository.ts
IRoleRepository (Interface)
(no doc) [2 implementers]
src/api/repositories/interfaces/IRoleRepository.ts

Core symbols most depended-on inside this repo

success
called by 8
src/utils/response/ApiResponse.ts
checkRoles
called by 7
src/api/middlewares/auth/index.ts
Validate
called by 7
src/api/middlewares/validator/index.ts
getUserDetail
called by 7
src/api/services/interfaces/IUserService.ts
login
called by 5
src/api/services/interfaces/IAuthService.ts
createUser
called by 5
src/api/services/interfaces/IUserService.ts
updateUser
called by 4
src/api/services/interfaces/IUserService.ts
deleteUser
called by 4
src/api/services/interfaces/IUserService.ts

Shape

Method 58
Class 40
Interface 13
Function 12

Languages

TypeScript100%

Modules by API surface

src/errors/AppError.ts21 symbols
src/api/repositories/UserRepository.ts8 symbols
src/api/services/UserService.ts7 symbols
src/api/repositories/interfaces/IUserRepository.ts7 symbols
src/api/controllers/UserController.ts7 symbols
src/utils/response/ApiResponse.ts6 symbols
src/api/services/interfaces/IUserService.ts6 symbols
src/api/repositories/RoleRepository.ts5 symbols
src/utils/jwt/index.ts4 symbols
src/api/services/RoleService.ts4 symbols
src/api/services/AuthService.ts4 symbols
src/api/repositories/interfaces/IRoleRepository.ts4 symbols

For agents

$ claude mcp add project-structure-api \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact