Implement product creation functionality with DTO and permissions

This commit is contained in:
faris Aljohari
2025-04-15 13:26:56 +03:00
parent 30dd8318e3
commit 32112930c8
6 changed files with 88 additions and 3 deletions

View File

@ -340,6 +340,9 @@ export class ControllerRoute {
static PRODUCT = class { static PRODUCT = class {
public static readonly ROUTE = 'products'; public static readonly ROUTE = 'products';
static ACTIONS = class { static ACTIONS = class {
public static readonly CREATE_PRODUCT_SUMMARY = 'Create a new product';
public static readonly CREATE_PRODUCT_DESCRIPTION =
'This endpoint allows you to create a new product in the system.';
public static readonly LIST_PRODUCT_SUMMARY = 'Retrieve all products'; public static readonly LIST_PRODUCT_SUMMARY = 'Retrieve all products';
public static readonly LIST_PRODUCT_DESCRIPTION = public static readonly LIST_PRODUCT_DESCRIPTION =
'Fetches a list of all products along with their associated device details'; 'Fetches a list of all products along with their associated device details';

View File

@ -55,6 +55,7 @@ export const RolePermissions = {
'USER_ADD', 'USER_ADD',
'SPACE_MEMBER_ADD', 'SPACE_MEMBER_ADD',
'COMMISSION_DEVICE', 'COMMISSION_DEVICE',
'PRODUCT_ADD',
], ],
[RoleType.ADMIN]: [ [RoleType.ADMIN]: [
'DEVICE_SINGLE_CONTROL', 'DEVICE_SINGLE_CONTROL',
@ -110,6 +111,7 @@ export const RolePermissions = {
'USER_ADD', 'USER_ADD',
'SPACE_MEMBER_ADD', 'SPACE_MEMBER_ADD',
'COMMISSION_DEVICE', 'COMMISSION_DEVICE',
'PRODUCT_ADD',
], ],
[RoleType.SPACE_MEMBER]: [ [RoleType.SPACE_MEMBER]: [
'DEVICE_SINGLE_CONTROL', 'DEVICE_SINGLE_CONTROL',

View File

@ -1,10 +1,13 @@
import { Controller, Get, UseGuards } from '@nestjs/common'; import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger'; import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard'; import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
import { EnableDisableStatusEnum } from '@app/common/constants/days.enum'; import { EnableDisableStatusEnum } from '@app/common/constants/days.enum';
import { BaseResponseDto } from '@app/common/dto/base.response.dto'; import { BaseResponseDto } from '@app/common/dto/base.response.dto';
import { ControllerRoute } from '@app/common/constants/controller-route'; import { ControllerRoute } from '@app/common/constants/controller-route';
import { ProductService } from '../services'; import { ProductService } from '../services';
import { Permissions } from 'src/decorators/permissions.decorator';
import { PermissionsGuard } from 'src/guards/permissions.guard';
import { AddProductDto } from '../dtos';
@ApiTags('Product Module') @ApiTags('Product Module')
@Controller({ @Controller({
@ -13,7 +16,19 @@ import { ProductService } from '../services';
}) })
export class ProductController { export class ProductController {
constructor(private readonly productService: ProductService) {} constructor(private readonly productService: ProductService) {}
@ApiBearerAuth()
@UseGuards(PermissionsGuard)
@Permissions('PRODUCT_ADD')
@Post()
@ApiOperation({
summary: ControllerRoute.PRODUCT.ACTIONS.CREATE_PRODUCT_SUMMARY,
description: ControllerRoute.PRODUCT.ACTIONS.CREATE_PRODUCT_DESCRIPTION,
})
async addNewProductType(
@Body() addProductDto: AddProductDto,
): Promise<BaseResponseDto> {
return await this.productService.addNewProductType(addProductDto);
}
@ApiBearerAuth() @ApiBearerAuth()
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get() @Get()

View File

@ -0,0 +1,36 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString } from 'class-validator';
export class AddProductDto {
@ApiProperty({
description: 'tuyaCategoryName',
required: true,
})
@IsString()
@IsNotEmpty()
public tuyaCategoryName: string;
@ApiProperty({
description: 'tuyaProductId',
required: true,
})
@IsString()
@IsNotEmpty()
public tuyaProductId: string;
@ApiProperty({
description: 'syncrowProductType',
required: true,
})
@IsString()
@IsNotEmpty()
public syncrowProductType: string;
@ApiProperty({
description: 'syncrowProductName',
required: true,
})
@IsString()
@IsNotEmpty()
public syncrowProductName: string;
}

View File

@ -0,0 +1 @@
export * from './add.product.dto';

View File

@ -2,11 +2,39 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto';
import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
import { ProductRepository } from '@app/common/modules/product/repositories'; import { ProductRepository } from '@app/common/modules/product/repositories';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { AddProductDto } from '../dtos';
@Injectable() @Injectable()
export class ProductService { export class ProductService {
constructor(private readonly productRepository: ProductRepository) {} constructor(private readonly productRepository: ProductRepository) {}
async addNewProductType(
addProductDto: AddProductDto,
): Promise<BaseResponseDto> {
try {
const {
tuyaCategoryName,
tuyaProductId,
syncrowProductType,
syncrowProductName,
} = addProductDto;
const product = await this.productRepository.save({
catName: tuyaCategoryName,
prodId: tuyaProductId,
prodType: syncrowProductType,
name: syncrowProductName,
});
return new SuccessResponseDto({
data: product,
message: 'Successfully added new product type',
});
} catch (error) {
throw new HttpException(
`Error adding new product type: ${error.message}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async list(): Promise<BaseResponseDto> { async list(): Promise<BaseResponseDto> {
const products = await this.productRepository.find(); const products = await this.productRepository.find();
@ -37,7 +65,7 @@ export class ProductService {
return new SuccessResponseDto({ return new SuccessResponseDto({
data: product, data: product,
message: 'Succefully retrieved product', message: 'Successfully retrieved product',
}); });
} }
} }