diff --git a/src/app.module.ts b/src/app.module.ts index 536d2ea..911b0d5 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -6,6 +6,7 @@ import { SequelizeModule } from "@nestjs/sequelize"; import { databaseConfig } from "../config/database.config"; import { UsersModule } from './users/users.module'; import { ShopModule } from './shop/shop.module'; +import { ProductsModule } from './products/products.module'; @Module({ @@ -14,6 +15,7 @@ import { ShopModule } from './shop/shop.module'; isGlobal: true, }), SequelizeModule.forRoot(databaseConfig), + ProductsModule, UsersModule, ShopModule, diff --git a/src/products/dto/create-product.dto.ts b/src/products/dto/create-product.dto.ts new file mode 100644 index 0000000..cc96c47 --- /dev/null +++ b/src/products/dto/create-product.dto.ts @@ -0,0 +1,16 @@ +import { IsNotEmpty, IsNumber, IsString, Min } from 'class-validator'; + +export class CreateProductDto { + @IsNotEmpty() + @IsString() + name: string; + + @IsNotEmpty() + @IsString() + description: string; + + @IsNotEmpty() + @IsNumber() + @Min(0) + price: number; +} diff --git a/src/products/dto/update-product.dto.ts b/src/products/dto/update-product.dto.ts new file mode 100644 index 0000000..e2d43fc --- /dev/null +++ b/src/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/products/entities/product.entity.ts b/src/products/entities/product.entity.ts new file mode 100644 index 0000000..13077cb --- /dev/null +++ b/src/products/entities/product.entity.ts @@ -0,0 +1,30 @@ +import { Table, Column, Model, DataType, PrimaryKey, AutoIncrement, Default } from 'sequelize-typescript'; + +@Table({ tableName: 'products', timestamps: true }) +export class Product extends Model { + @PrimaryKey + @AutoIncrement + @Column(DataType.INTEGER) + id: number; + + @Column(DataType.STRING) + name: string; + + @Column(DataType.STRING) + description: string; + + @Column(DataType.DECIMAL(10, 2)) + price: number; + + @Default(true) + @Column(DataType.BOOLEAN) + isActive: boolean; + + @Default(DataType.NOW) + @Column({ type: DataType.DATE }) + createdAt: Date; + + @Default(DataType.NOW) + @Column({ type: DataType.DATE }) + updatedAt: Date; +} diff --git a/src/products/products.controller.ts b/src/products/products.controller.ts new file mode 100644 index 0000000..21a74cf --- /dev/null +++ b/src/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 } from './dto/create-product.dto'; +import { UpdateProductDto } from './dto/update-product.dto'; + +@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/products/products.module.ts b/src/products/products.module.ts new file mode 100644 index 0000000..fe865cd --- /dev/null +++ b/src/products/products.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { SequelizeModule } from '@nestjs/sequelize'; +import { ProductsService } from './products.service'; +import { ProductsController } from './products.controller'; +import { Product } from '../shop/entities/product.entity'; + +@Module({ + imports: [SequelizeModule.forFeature([Product])], + controllers: [ProductsController], + providers: [ProductsService], +}) +export class ProductsModule {} diff --git a/src/products/products.service.ts b/src/products/products.service.ts new file mode 100644 index 0000000..1b7823f --- /dev/null +++ b/src/products/products.service.ts @@ -0,0 +1,41 @@ +import { Injectable, NotFoundException } from '@nestjs/common'; +import { InjectModel } from '@nestjs/sequelize'; +import { Product } from '../shop/entities/product.entity'; +import { CreateProductDto } from './dto/create-product.dto'; +import { UpdateProductDto } from './dto/update-product.dto'; + +@Injectable() +export class ProductsService { + constructor( + @InjectModel(Product) + private readonly productModel: typeof Product, + ) {} + + async create(createProductDto: CreateProductDto) { + return this.productModel.create(createProductDto); + } + + async findAll() { + return this.productModel.findAll(); + } + + async findOne(id: number) { + const product = await this.productModel.findByPk(id); + if (!product) { + throw new NotFoundException(`Product with ID ${id} not found`); + } + return product; + } + + async update(id: number, updateProductDto: UpdateProductDto) { + const product = await this.findOne(id); + await product.update(updateProductDto); + return product; + } + + async remove(id: number) { + const product = await this.findOne(id); + await product.destroy(); + return { message: 'Product deleted successfully' }; + } +} \ No newline at end of file