# NestJS Boilerplate

A production-ready NestJS boilerplate with authentication, PostgreSQL, Sequelize ORM, and Redis integration.

## Features

- **Authentication**: JWT-based authentication with refresh tokens
- **Database**: PostgreSQL with Sequelize ORM
- **Caching**: Redis integration
- **Validation**: Class-validator for request validation
- **API Documentation**: Swagger/OpenAPI documentation
- **Email**: Mailgun integration for sending emails
- **File Upload**: Built-in file upload support
- **Security**: Helmet, CORS, rate limiting
- **Code Quality**: ESLint, Prettier

## Requirements

- Node.js 16.17.0+
- npm 8.15.0+
- PostgreSQL 12+
- Redis (optional, for caching)
- Git

## Installation

### 1. Clone the repository
```bash
git clone <your-repo-url>
cd nest-boiler-plate
npm install
```

### 2. Environment Setup
Copy the example environment file and update the configuration:
```bash
cp .env.example .env
```

Update the following variables in `.env`:
- **Database**: `DATABASE_DIALECT`, `DATABASE_HOST`, `DATABASE_PORT`, `DATABASE_USERNAME`, `DATABASE_PASSWORD`, `DATABASE_NAME`
- **Redis**: `REDIS_HOST`, `REDIS_PORT`
- **JWT**: Keys are already generated, but you can replace them
- **Mail**: `MAIL_API_KEY`, `MAIL_DOMAIN` (if using Mailgun)

### 3. Database Setup
Create the database:
```bash
npm run db:create
```

Run migrations:
```bash
npm run db:migrate
```

(Optional) Seed the database:
```bash
npm run db:seed
```

## Development

Start the development server with hot-reload:
```bash
npm run start:dev
```

The API will be available at `http://localhost:3000`

## Production

Build the application:
```bash
npm run build
```

Start the production server:
```bash
npm run start:prod
```

## Database Commands

### Migrations

Create a new migration:
```bash
npx sequelize migration:generate --name create-your-table-name
```

Run all pending migrations:
```bash
npm run db:migrate
```

Check migration status:
```bash
npm run db:migrate:status
```

Undo the last migration:
```bash
npm run db:migrate:undo
```

Reset database (undo all migrations and re-run them):
```bash
npm run db:reset
```

### Seeds

Create a new seed file:
```bash
npx sequelize seed:generate --name seed-name
```

Run all seeds:
```bash
npm run db:seed
```

## API Documentation

Once the application is running, access the Swagger documentation at:
```
http://localhost:3000/api-documentation
```

## Available Scripts

- `npm run start:dev` - Start development server with hot-reload
- `npm run start:prod` - Start production server
- `npm run build` - Build the application
- `npm run lint` - Run ESLint
- `npm run format` - Format code with Prettier
- `npm run test` - Run unit tests
- `npm run test:watch` - Run tests in watch mode
- `npm run test:cov` - Run tests with coverage
- `npm run db:create` - Create database
- `npm run db:migrate` - Run migrations
- `npm run db:migrate:status` - Check migration status
- `npm run db:migrate:undo` - Undo last migration
- `npm run db:reset` - Reset database (undo all and re-run)
- `npm run db:seed` - Run seeders

## Project Structure

```
src/
├── common/             # Shared utilities, constants, decorators
├── database/           # Database models, migrations, seeders
│   ├── migrations/     # Sequelize migrations
│   ├── models/         # Sequelize models
│   └── seeders/        # Database seeders
├── interceptors/       # Global interceptors
├── middleware/         # Custom middleware
├── modules/            # Feature modules
│   ├── auth/           # Authentication module
│   └── users/          # Users module
├── share/              # Shared services and guards
├── app.module.ts       # Root module
└── main.ts             # Application entry point
```

## Creating New Migrations

### Example: Create a products table

1. Generate migration file:
```bash
npx sequelize migration:generate --name create-products-table
```

2. Edit the generated file in `src/database/migrations/`:
```javascript
'use strict';

module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('products', {
      id: {
        type: Sequelize.BIGINT,
        autoIncrement: true,
        primaryKey: true,
        allowNull: false
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false
      },
      description: {
        type: Sequelize.TEXT,
        allowNull: true
      },
      price: {
        type: Sequelize.DECIMAL(10, 2),
        allowNull: false
      },
      createdAt: {
        type: Sequelize.DATE,
        field: 'created_at',
        allowNull: false,
        defaultValue: Sequelize.fn('NOW')
      },
      updatedAt: {
        type: Sequelize.DATE,
        field: 'updated_at',
        allowNull: false,
        defaultValue: Sequelize.fn('NOW')
      }
    });

    await queryInterface.addIndex('products', ['name']);
  },

  async down(queryInterface) {
    await queryInterface.dropTable('products');
  }
};
```

3. Run the migration:
```bash
npm run db:migrate
```

## Creating New Modules

NestJS CLI provides a powerful generator to create new modules with all necessary files.

### Generate a complete CRUD resource:
```bash
nest g resource products
```

This will prompt you to:
- Choose transport layer (REST API, GraphQL, Microservice, WebSockets) - Select **REST API**
- Generate CRUD entry points? - Select **Yes**

This command creates:
```
src/modules/products/
├── dto/
│   ├── create-product.dto.ts
│   └── update-product.dto.ts
├── entities/
│   └── product.entity.ts
├── products.controller.ts
├── products.module.ts
├── products.service.ts
└── products.controller.spec.ts
```

### Other useful generators:

Generate a module only:
```bash
nest g module products
```

Generate a controller:
```bash
nest g controller products
```

Generate a service:
```bash
nest g service products
```

Generate a guard:
```bash
nest g guard auth/guards/custom
```

Generate a decorator:
```bash
nest g decorator common/decorators/custom
```

Generate a middleware:
```bash
nest g middleware common/middleware/custom
```

After generating a new module, remember to:
1. Create the corresponding Sequelize model in `src/database/models/`
2. Create a migration for the database table
3. Add the model to `SequelizeModule.forFeature([])` in your module
4. Update DTOs with proper validation decorators

## Contributors

- Daffa Praramadhana - [daffa.praramadhana@mdd.co.id](mailto:daffa.praramadhana@mdd.co.id)

## License

Copyright © 2025 Multidaya Dinamika. All rights reserved.
