diff --git a/src/app.module.ts b/src/app.module.ts index 2b7c62a..92956ea 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -5,12 +5,14 @@ import { DatabaseModule } from './core/database/database.module'; import { ConfigModule } from '@nestjs/config'; import { UsersModule } from './modules/users/users.module'; import { UsersController } from './modules/users/users.controller'; +import { ProductsModule } from './modules/products/products.module'; @Module({ imports: [ DatabaseModule, ConfigModule.forRoot({ isGlobal: true }), UsersModule, + ProductsModule, ], controllers: [AppController, UsersController], providers: [AppService], diff --git a/src/core/constants/index.ts b/src/core/constants/index.ts index e28382c..0af31e8 100644 --- a/src/core/constants/index.ts +++ b/src/core/constants/index.ts @@ -3,3 +3,4 @@ export const DEVELOPMENT = 'development'; export const TEST = 'test'; export const PRODUCTION = 'production'; export const USER_REPOSITORY = 'USER_REPOSITORY'; +export const PRODUCT_REPOSITORY = 'PRODUCT_REPOSITORY'; diff --git a/src/core/database/database.providers.ts b/src/core/database/database.providers.ts index b2b6bbf..7b1c4f9 100644 --- a/src/core/database/database.providers.ts +++ b/src/core/database/database.providers.ts @@ -1,7 +1,8 @@ import { Sequelize } from 'sequelize-typescript'; import { SEQUELIZE, DEVELOPMENT, TEST, PRODUCTION } from '../constants'; import { databaseConfig } from './database.config'; -import { User } from 'src/modules/users/user.entity'; +import { User } from 'src/modules/users/entities/user.entity'; +import { Product } from 'src/modules/products/entities/product.entity'; export const databaseProviders = [ { @@ -22,7 +23,7 @@ export const databaseProviders = [ config = databaseConfig.development; } const sequelize = new Sequelize(config); - sequelize.addModels([User]); + sequelize.addModels([User, Product]); await sequelize.sync(); return sequelize; }, diff --git a/src/modules/products/dto/create-product.dto.ts b/src/modules/products/dto/create-product.dto.ts new file mode 100644 index 0000000..842dcec --- /dev/null +++ b/src/modules/products/dto/create-product.dto.ts @@ -0,0 +1,5 @@ +export class CreateProductDto { + productName: string; + quantityInStock: number; + pricePerUnit: number; +} diff --git a/src/modules/products/dto/index.ts b/src/modules/products/dto/index.ts new file mode 100644 index 0000000..eee3849 --- /dev/null +++ b/src/modules/products/dto/index.ts @@ -0,0 +1,2 @@ +export * from './create-product.dto'; +export * from './update-product.dto'; diff --git a/src/modules/products/dto/update-product.dto.ts b/src/modules/products/dto/update-product.dto.ts new file mode 100644 index 0000000..e2d43fc --- /dev/null +++ b/src/modules/products/dto/update-product.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateProductDto } from './create-product.dto'; + +export class UpdateProductDto extends PartialType(CreateProductDto) {} diff --git a/src/modules/products/entities/product.entity.ts b/src/modules/products/entities/product.entity.ts new file mode 100644 index 0000000..b4cbc30 --- /dev/null +++ b/src/modules/products/entities/product.entity.ts @@ -0,0 +1,24 @@ +import { Table, Column, Model, DataType } from 'sequelize-typescript'; + +@Table({ tableName: 'products' }) +export class Product extends Model { + @Column({ + type: DataType.STRING, + allowNull: false, + }) + productName: string; + + @Column({ + type: DataType.INTEGER, + allowNull: false, + defaultValue: 0, + }) + quantityInStock: number; + + @Column({ + type: DataType.FLOAT, + allowNull: false, + defaultValue: 0, + }) + pricePerUnit: number; +} diff --git a/src/modules/products/products.controller.ts b/src/modules/products/products.controller.ts new file mode 100644 index 0000000..6456a06 --- /dev/null +++ b/src/modules/products/products.controller.ts @@ -0,0 +1,42 @@ +import { + Controller, + Get, + Post, + Body, + Patch, + Param, + Delete, +} from '@nestjs/common'; +import { ProductsService } from './products.service'; +import { CreateProductDto, UpdateProductDto } from './dto'; +import { UUID } from 'crypto'; + +@Controller('products') +export class ProductsController { + constructor(private readonly productsService: ProductsService) {} + + @Post() + create(@Body() createProductDto: CreateProductDto) { + return this.productsService.create(createProductDto); + } + + @Get() + findAll() { + return this.productsService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.productsService.findOne(+id); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updateProductDto: UpdateProductDto) { + return this.productsService.update(+id, updateProductDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.productsService.remove(+id); + } +} diff --git a/src/modules/products/products.module.ts b/src/modules/products/products.module.ts new file mode 100644 index 0000000..32ab474 --- /dev/null +++ b/src/modules/products/products.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { ProductsService } from './products.service'; +import { ProductsController } from './products.controller'; +import { productsProviders } from './products.providers'; + +@Module({ + controllers: [ProductsController], + exports: [ProductsService], + providers: [ProductsService, ...productsProviders], +}) +export class ProductsModule {} diff --git a/src/modules/products/products.providers.ts b/src/modules/products/products.providers.ts new file mode 100644 index 0000000..543544d --- /dev/null +++ b/src/modules/products/products.providers.ts @@ -0,0 +1,9 @@ +import { Product } from './entities/product.entity'; +import { PRODUCT_REPOSITORY } from '../../core/constants'; + +export const productsProviders = [ + { + provide: PRODUCT_REPOSITORY, + useValue: Product, + }, +]; diff --git a/src/modules/products/products.service.ts b/src/modules/products/products.service.ts new file mode 100644 index 0000000..fb8af1e --- /dev/null +++ b/src/modules/products/products.service.ts @@ -0,0 +1,41 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { CreateProductDto, UpdateProductDto } from './dto'; +import { PRODUCT_REPOSITORY } from 'src/core/constants'; +import { Product } from './entities/product.entity'; + +@Injectable() +export class ProductsService { + constructor( + @Inject(PRODUCT_REPOSITORY) + private readonly productRepository: typeof Product, + ) {} + + async create(createProductDto: CreateProductDto) { + return await this.productRepository.create(createProductDto); + } + + async findAll() { + return await this.productRepository.findAll(); + } + + async findOne(id: number) { + return await this.productRepository.findAll({ where: { id } }); + } + + async update(id: number, updateProductDto: UpdateProductDto) { + const [numberOfAffectedRows, [updatedProduct]] = + await this.productRepository.update( + { ...updateProductDto }, + { where: { id }, returning: true }, + ); + return { numberOfAffectedRows, updatedProduct }; + } + + async remove(id: number) { + const deletedProduct = await this.findOne(id); + + await this.productRepository.destroy({ where: { id } }); + + return deletedProduct; + } +} diff --git a/src/modules/users/user.entity.ts b/src/modules/users/entities/user.entity.ts similarity index 100% rename from src/modules/users/user.entity.ts rename to src/modules/users/entities/user.entity.ts diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts index a3252d9..8ce59a8 100644 --- a/src/modules/users/users.controller.ts +++ b/src/modules/users/users.controller.ts @@ -26,13 +26,13 @@ export class UsersController { } @Post() - create(@Body() user: CreateUserDto) { - return this.usersService.create(user); + create(@Body() createUserDto: CreateUserDto) { + return this.usersService.create(createUserDto); } - @Patch() - update(@Param('id') id: UUID, @Body() user: UpdateUserDto) { - return this.usersService.update(id, user); + @Patch(':id') + update(@Param('id') id: UUID, @Body() updateUserDto: UpdateUserDto) { + return this.usersService.update(id, updateUserDto); } @Delete(':id') diff --git a/src/modules/users/users.providers.ts b/src/modules/users/users.providers.ts index 2b9e27f..b88c334 100644 --- a/src/modules/users/users.providers.ts +++ b/src/modules/users/users.providers.ts @@ -1,4 +1,4 @@ -import { User } from './user.entity'; +import { User } from './entities/user.entity'; import { USER_REPOSITORY } from '../../core/constants'; export const usersProviders = [ diff --git a/src/modules/users/users.service.ts b/src/modules/users/users.service.ts index aa4cca4..2f5a124 100644 --- a/src/modules/users/users.service.ts +++ b/src/modules/users/users.service.ts @@ -1,5 +1,5 @@ import { Injectable, Inject } from '@nestjs/common'; -import { User } from './user.entity'; +import { User } from './entities/user.entity'; import { CreateUserDto, UpdateUserDto } from './dto'; import { USER_REPOSITORY } from '../../core/constants'; import * as argon from 'argon2'; @@ -20,11 +20,11 @@ export class UsersService { return await this.userRepository.findAll({ where: { uuid: id } }); } - async create(user: CreateUserDto) { - const hashedPassword = await argon.hash(user.password); - user.password = hashedPassword; + async create(createUserDto: CreateUserDto) { + const hashedPassword = await argon.hash(createUserDto.password); + createUserDto.password = hashedPassword; - const newUser = await this.userRepository.create(user); + const newUser = await this.userRepository.create(createUserDto); return _.pick(newUser, [ 'firstName', @@ -36,10 +36,19 @@ export class UsersService { ]); } - async update(id: UUID, user: UpdateUserDto) { + // async update(id: UUID, updateUserDto: UpdateUserDto) { + // const [numberOfAffectedRows, [updatedUser]] = + // await this.userRepository.update( + // { ...updateUserDto }, + // { where: { uuid: id }, returning: true }, + // ); + // return { numberOfAffectedRows, updatedUser }; + // } + + async update(id: UUID, updateUserDto: UpdateUserDto) { const [numberOfAffectedRows, [updatedUser]] = await this.userRepository.update( - { ...user }, + { ...updateUserDto }, { where: { uuid: id }, returning: true }, ); return { numberOfAffectedRows, updatedUser };