import { Controller, Get, Post, Put, Delete, Body, Param, Query, HttpCode, HttpStatus, NotFoundException } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiBody } from '@nestjs/swagger'; import { PrismaService } from '../services/prisma.service'; import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; import { CreateProductDto, UpdateProductDto, FindManyProductDto, FlatQueryProductDto, ProductResponseDto, ProductIdDto, } from '../dto/product'; @ApiTags('Product') @Controller('product') export class ProductController { constructor(private readonly prisma: PrismaService) {} @Post() @ApiOperation({ summary: 'Create a new Product record', operationId: 'createProduct' }) @ApiBody({ type: CreateProductDto }) @ApiResponse({ status: 201, description: 'Created Product record', type: ProductResponseDto }) async createProduct(@Body() data: CreateProductDto): Promise { return this.prisma.product.create({ data }); } @Put(':id') @ApiOperation({ summary: 'Update a Product record', operationId: 'updateProduct' }) @ApiBody({ type: UpdateProductDto }) @ApiResponse({ status: 200, description: 'Updated Product record', type: ProductResponseDto }) @ApiResponse({ status: 404, description: 'Product record not found' }) async updateProduct(@Param() params: ProductIdDto, @Body() data: UpdateProductDto): Promise { try { return await this.prisma.product.update({ where: params, data }); } catch (error) { if (error instanceof PrismaClientKnownRequestError && error.code === 'P2025') { throw new NotFoundException('Product record not found'); } throw error; } } @Get(':id') @ApiOperation({ summary: 'Get a Product record by ID', operationId: 'getProduct' }) @ApiResponse({ status: 200, description: 'Product record', type: ProductResponseDto }) @ApiResponse({ status: 404, description: 'Product record not found' }) async getProduct(@Param() params: ProductIdDto): Promise { try { return await this.prisma.product.findUniqueOrThrow({ where: params }); } catch (error) { if (error instanceof PrismaClientKnownRequestError && error.code === 'P2025') { throw new NotFoundException('Product record not found'); } throw error; } } @Get() @ApiOperation({ summary: 'Get a list of Product records', operationId: 'getProductList' }) @ApiResponse({ status: 200, description: 'List of Product records', type: [ProductResponseDto] }) async getProductList(@Query() query: FlatQueryProductDto): Promise { return this.prisma.product.findMany(query.toPrismaQuery()); } @Post('search') @ApiOperation({ summary: 'Search Product records', operationId: 'searchProduct' }) @ApiBody({ type: FindManyProductDto }) @ApiResponse({ status: 200, description: 'List of Product records', type: [ProductResponseDto] }) async searchProduct(@Body() query: FindManyProductDto): Promise { const { where, orderBy, take, skip } = query; return this.prisma.product.findMany({ where, orderBy, take, skip, }); } @Delete(':id') @ApiOperation({ summary: 'Delete a Product record', operationId: 'deleteProduct' }) @HttpCode(HttpStatus.NO_CONTENT) @ApiResponse({ status: 204, description: 'Product record deleted' }) @ApiResponse({ status: 404, description: 'Product record not found' }) async deleteProduct(@Param() params: ProductIdDto): Promise { try { await this.prisma.product.delete({ where: params }); } catch (error) { if (error instanceof PrismaClientKnownRequestError && error.code === 'P2025') { throw new NotFoundException('Product record not found'); } throw error; } } }