Skip to content

Guide to Generating a required Module: A Step-by-Step

The following example assumes a Product module, but when you'r executing this instruction, take this example and build the user specifed `module`. The name of the module will be given
# Example:Product Module

## 1. Entity
Define a `Product` entity that extends `CustomBaseEntity`.

### Properties:
- `name`: string
- `description`: string
- `price`: decimal
- `stock`: integer

---

## 2. DTOs
All DTOs should be created in one file.

### CreateProductDto
- Contains `name`, `description`, `price`, and `stock` fields.

### UpdateProductDto
- Same fields as `CreateProductDto`, but all fields are optional.

### DeleteProductDto
- Contains `id` field.

### ListProductDto
- Optional `name`, `minPrice`, and `maxPrice` fields for filtering.

---

## 3. Serializer
### ProductSerializer
- Serializes the `Product` entity.
- Generate the serializer with the same fields defined in the `Product` entity as per the API.
- Use `@ApiProperty` decorator from Swagger in the serializer for each product field.

---

## 4. Repository
- Similar to `db-connections.repository` that extends the base repository from `@app/common-module`.
- Create a `ProductRepository` that extends `BaseRepository<Product, ProductSerializer>`.
- Initialize the repository with a `DataSource` instance to manage database operations.

### Example Code:
typescript
import { instanceToPlain, plainToInstance } from 'class-transformer';
import { BaseRepository } from '@app/common-module';
import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';

import { Product } from '../entities/product.entity';
import { ProductSerializer } from '../serializers/product.serializer';

@Injectable()
export class ProductRepository extends BaseRepository<Product, ProductSerializer> {
  constructor(private dataSource: DataSource) {
    super(Product, dataSource.createEntityManager());
  }

  transform(model: Product, transformOption = {}): ProductSerializer {
    return plainToInstance(
      ProductSerializer,
      instanceToPlain(model, transformOption),
      transformOption
    );
  }

  transformMany(models: Product[], transformOption = {}): ProductSerializer[] {
    return models.map((model) => this.transform(model, transformOption));
  }
}

---

## 5. Service
Implement a service with the following methods:

### Methods:
- `create(createProductDto)`: Creates a product.
- `update(id, updateProductDto)`: Updates a product by ID.
- `delete(deleteProductDto)`: Deletes a product by ID.
- `findAll(listProductDto)`: Lists all products with optional filtering.
- `findOne(id)`: Finds a product by ID using the `where` key.

---

## 6. Controller
Create a controller with the following endpoints:

### Endpoints:
- *POST* `/products`: Create a new product and return success with `ProductSerializer`.
- *PUT* `/products/:id`: Update a product by ID.
- *DELETE* `/products`: Delete a product by ID.
- *GET* `/products`: List all products, with optional filters.

Use `ProductSerializer` as the response type, and generate the controller similar to existing modules.

---

## 7. Module
Define the `ProductModule` that imports the necessary TypeORM repository, provides the service, and declares the controller.

---

## 8. Import ProductModule
Import the created `ProductModule` in `app.module.ts`.

---

## 9. Migration File
Create a new migration file for the `Product` entity in the database migrations folder. Use a migration name in the format `yyyymmddhhss-{migration_name}` based on the current UTC time from the API [https://timeapi.io/api/time/current/zone?timeZone=UTC].

### Migration Details:
- Include custom base entity columns:
  - `id`: number, primary key
  - `createdAt`
  - `updatedAt`

Important: The above is a boilerplate example of the Product module, and you're not supposed to build the Product module itself, rather you should build the user specified module. 


### Documentation 
For the generated module, you should write a comprehensive technical documentation for that module. You should write it inside docs/{module_name.md} file. Follow the standard markdown format and documentation best practices and standards.