speedrun-cli 2.6.9 → 2.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +1 -1
  3. package/src/generator.js +4 -0
  4. package/src/moduleGenerator.js +2 -1
  5. package/templates/base-crud/src/modules/products/dto/create-product.dto.ts +34 -0
  6. package/templates/base-crud/src/modules/products/dto/product.dto.ts +36 -0
  7. package/templates/base-crud/src/modules/products/dto/update-product.dto.ts +4 -0
  8. package/templates/base-crud/src/modules/products/products.controller.ts +78 -0
  9. package/templates/base-crud-drizzle/src/modules/products/dto/create-product.dto.ts +34 -0
  10. package/templates/base-crud-drizzle/src/modules/products/dto/product.dto.ts +36 -0
  11. package/templates/base-crud-drizzle/src/modules/products/dto/update-product.dto.ts +4 -0
  12. package/templates/base-crud-drizzle/src/modules/products/products.controller.ts +0 -1
  13. package/templates/base-crud-mongoose/src/modules/products/dto/create-product.dto.ts +34 -0
  14. package/templates/base-crud-mongoose/src/modules/products/dto/product.dto.ts +36 -0
  15. package/templates/base-crud-mongoose/src/modules/products/dto/update-product.dto.ts +4 -0
  16. package/templates/base-crud-mongoose/src/modules/products/products.controller.ts +0 -1
  17. package/templates/base-crud-prisma/src/modules/products/dto/create-product.dto.ts +34 -0
  18. package/templates/base-crud-prisma/src/modules/products/dto/product.dto.ts +36 -0
  19. package/templates/base-crud-prisma/src/modules/products/dto/update-product.dto.ts +4 -0
  20. package/templates/base-crud-prisma/src/modules/products/products.controller.ts +78 -0
  21. package/templates/base-crud-typeorm/src/modules/products/dto/create-product.dto.ts +34 -0
  22. package/templates/base-crud-typeorm/src/modules/products/dto/product.dto.ts +36 -0
  23. package/templates/base-crud-typeorm/src/modules/products/dto/update-product.dto.ts +4 -0
  24. package/templates/base-crud-typeorm/src/modules/products/products.controller.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@ All notable changes to create-nestjs-auth will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.6.10] - 2026-08-21
9
+
10
+ ### Fixed
11
+ - **Restored Products controller and DTO files** — Restored `products.controller.ts`, `create-product.dto.ts`, `update-product.dto.ts`, and `product.dto.ts` into the `base-crud` and `base-crud-*` templates to eliminate TypeScript compilation errors (`TS2307: Cannot find module './products.controller'` / `Cannot find module './dto/create-product.dto'`).
12
+ - **Automated `app.module.ts` registration** — `ProductsModule` (and any module generated via `speedrun-cli generate`) is now automatically imported and registered inside `src/app.module.ts`'s `imports` array upon generation.
13
+
14
+ ---
15
+
8
16
  ## [2.6.9] - 2026-08-21
9
17
 
10
18
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speedrun-cli",
3
- "version": "2.6.9",
3
+ "version": "2.6.10",
4
4
  "description": "CLI tool to scaffold a production-ready NestJS authentication system with JWT, refresh tokens, and RBAC",
5
5
  "keywords": [
6
6
  "nestjs",
package/src/generator.js CHANGED
@@ -121,6 +121,10 @@ async function generateFromModularTemplates(targetDir, { baseDir, ormDir, dbDir,
121
121
  filter: createCopyFilter(baseCrudOrmDir),
122
122
  });
123
123
  }
124
+
125
+ // 6c. Automatically register ProductsModule in src/app.module.ts
126
+ const { registerInAppModule } = require('./moduleGenerator');
127
+ await registerInAppModule(targetDir, 'Products', 'products');
124
128
  }
125
129
  }
126
130
 
@@ -624,5 +624,6 @@ export class AppModule {}
624
624
  module.exports = {
625
625
  generateModule,
626
626
  promptForModuleOptions,
627
- detectOrm
627
+ detectOrm,
628
+ registerInAppModule,
628
629
  };
@@ -0,0 +1,34 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { IsString, IsNotEmpty, IsNumber, IsOptional, Min } from 'class-validator';
3
+
4
+ export class CreateProductDto {
5
+ @ApiProperty({ example: 'Wireless Mouse' })
6
+ @IsString()
7
+ @IsNotEmpty()
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ @IsString()
12
+ @IsOptional()
13
+ description?: string;
14
+
15
+ @ApiProperty({ example: 'PROD-001' })
16
+ @IsString()
17
+ @IsNotEmpty()
18
+ sku: string;
19
+
20
+ @ApiProperty({ example: 29.99 })
21
+ @IsNumber()
22
+ @Min(0)
23
+ price: number;
24
+
25
+ @ApiProperty({ example: 100 })
26
+ @IsNumber()
27
+ @Min(0)
28
+ stock: number;
29
+
30
+ @ApiPropertyOptional({ example: 'Electronics' })
31
+ @IsString()
32
+ @IsOptional()
33
+ category?: string;
34
+ }
@@ -0,0 +1,36 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+
3
+ export class ProductDto {
4
+ @ApiProperty({ example: '123e4567-e89b-12d3-a456-426614174000', format: 'uuid' })
5
+ id: string;
6
+
7
+ @ApiProperty({ example: 'Wireless Mouse' })
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ description?: string;
12
+
13
+ @ApiProperty({ example: 'PROD-001' })
14
+ sku: string;
15
+
16
+ @ApiProperty({ example: 29.99 })
17
+ price: number;
18
+
19
+ @ApiProperty({ example: 100 })
20
+ stock: number;
21
+
22
+ @ApiPropertyOptional({ example: 'Electronics' })
23
+ category?: string;
24
+
25
+ @ApiProperty({ example: 'ACTIVE' })
26
+ status: string;
27
+
28
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
29
+ createdAt: Date;
30
+
31
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
32
+ updatedAt: Date;
33
+
34
+ @ApiPropertyOptional({ nullable: true, example: null })
35
+ deletedAt?: Date | null;
36
+ }
@@ -0,0 +1,4 @@
1
+ import { PartialType } from '@nestjs/swagger';
2
+ import { CreateProductDto } from './create-product.dto';
3
+
4
+ export class UpdateProductDto extends PartialType(CreateProductDto) {}
@@ -0,0 +1,78 @@
1
+ import {
2
+ Controller,
3
+ Get,
4
+ Param,
5
+ Query,
6
+ ParseUUIDPipe,
7
+ HttpStatus,
8
+ Type,
9
+ } from '@nestjs/common';
10
+ import {
11
+ ApiTags,
12
+ ApiOperation,
13
+ ApiResponse,
14
+ ApiBearerAuth,
15
+ ApiExtraModels,
16
+ ApiParam,
17
+ } from '@nestjs/swagger';
18
+ import { BaseController } from '../../common/base/base.controller';
19
+ import {
20
+ ApiResponseDto,
21
+ ApiResponseSchema,
22
+ PaginatedResponseDto,
23
+ PaginatedResponseSchema,
24
+ PaginationQueryDto,
25
+ } from '../../common/base';
26
+ import { ProductsService, ProductEntity } from './products.service';
27
+ import { CreateProductDto } from './dto/create-product.dto';
28
+ import { UpdateProductDto } from './dto/update-product.dto';
29
+ import { ProductDto } from './dto/product.dto';
30
+
31
+ @ApiTags('Products')
32
+ @ApiBearerAuth('bearer')
33
+ @ApiExtraModels(ApiResponseDto, PaginatedResponseDto, ProductDto)
34
+ @Controller('products')
35
+ export class ProductsController extends BaseController<
36
+ ProductEntity,
37
+ CreateProductDto,
38
+ UpdateProductDto
39
+ > {
40
+ constructor(private readonly productsService: ProductsService) {
41
+ super(productsService);
42
+ }
43
+
44
+ protected getDtoClass(): Type<ProductEntity> {
45
+ return ProductDto as unknown as Type<ProductEntity>;
46
+ }
47
+
48
+ @Get()
49
+ @ApiOperation({ summary: 'Get all products (paginated)' })
50
+ @ApiResponse({ status: HttpStatus.OK, schema: PaginatedResponseSchema(ProductDto) })
51
+ @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
52
+ override async findAll(@Query() pagination: PaginationQueryDto): Promise<PaginatedResponseDto<ProductEntity>> {
53
+ return super.findAll(pagination);
54
+ }
55
+
56
+ @Get('by-sku/:sku')
57
+ @ApiOperation({ summary: 'Get a product by SKU' })
58
+ @ApiParam({ name: 'sku', example: 'KB-WL-MEC-001' })
59
+ @ApiResponse({ status: HttpStatus.OK, schema: ApiResponseSchema(ProductDto) })
60
+ @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Product not found' })
61
+ async findBySku(@Param('sku') sku: string): Promise<ApiResponseDto<ProductEntity>> {
62
+ const data = await this.productsService.findBySku(sku);
63
+ return { success: true, data, meta: { correlationId: '', timestamp: new Date().toISOString() } };
64
+ }
65
+
66
+ @Get(':id')
67
+ @ApiOperation({ summary: 'Get a product by ID' })
68
+ @ApiParam({ name: 'id', format: 'uuid', example: '123e4567-e89b-12d3-a456-426614174000' })
69
+ @ApiResponse({ status: HttpStatus.OK, schema: ApiResponseSchema(ProductDto) })
70
+ @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Product not found' })
71
+ @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Invalid UUID' })
72
+ override async findOne(
73
+ @Param('id', new ParseUUIDPipe({ version: '4', errorHttpStatusCode: HttpStatus.BAD_REQUEST }))
74
+ id: string,
75
+ ): Promise<ApiResponseDto<ProductEntity>> {
76
+ return super.findOne(id);
77
+ }
78
+ }
@@ -0,0 +1,34 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { IsString, IsNotEmpty, IsNumber, IsOptional, Min } from 'class-validator';
3
+
4
+ export class CreateProductDto {
5
+ @ApiProperty({ example: 'Wireless Mouse' })
6
+ @IsString()
7
+ @IsNotEmpty()
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ @IsString()
12
+ @IsOptional()
13
+ description?: string;
14
+
15
+ @ApiProperty({ example: 'PROD-001' })
16
+ @IsString()
17
+ @IsNotEmpty()
18
+ sku: string;
19
+
20
+ @ApiProperty({ example: 29.99 })
21
+ @IsNumber()
22
+ @Min(0)
23
+ price: number;
24
+
25
+ @ApiProperty({ example: 100 })
26
+ @IsNumber()
27
+ @Min(0)
28
+ stock: number;
29
+
30
+ @ApiPropertyOptional({ example: 'Electronics' })
31
+ @IsString()
32
+ @IsOptional()
33
+ category?: string;
34
+ }
@@ -0,0 +1,36 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+
3
+ export class ProductDto {
4
+ @ApiProperty({ example: '123e4567-e89b-12d3-a456-426614174000', format: 'uuid' })
5
+ id: string;
6
+
7
+ @ApiProperty({ example: 'Wireless Mouse' })
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ description?: string;
12
+
13
+ @ApiProperty({ example: 'PROD-001' })
14
+ sku: string;
15
+
16
+ @ApiProperty({ example: 29.99 })
17
+ price: number;
18
+
19
+ @ApiProperty({ example: 100 })
20
+ stock: number;
21
+
22
+ @ApiPropertyOptional({ example: 'Electronics' })
23
+ category?: string;
24
+
25
+ @ApiProperty({ example: 'ACTIVE' })
26
+ status: string;
27
+
28
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
29
+ createdAt: Date;
30
+
31
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
32
+ updatedAt: Date;
33
+
34
+ @ApiPropertyOptional({ nullable: true, example: null })
35
+ deletedAt?: Date | null;
36
+ }
@@ -0,0 +1,4 @@
1
+ import { PartialType } from '@nestjs/swagger';
2
+ import { CreateProductDto } from './create-product.dto';
3
+
4
+ export class UpdateProductDto extends PartialType(CreateProductDto) {}
@@ -76,4 +76,3 @@ export class ProductsController extends BaseController<
76
76
  return super.findOne(id);
77
77
  }
78
78
  }
79
-
@@ -0,0 +1,34 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { IsString, IsNotEmpty, IsNumber, IsOptional, Min } from 'class-validator';
3
+
4
+ export class CreateProductDto {
5
+ @ApiProperty({ example: 'Wireless Mouse' })
6
+ @IsString()
7
+ @IsNotEmpty()
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ @IsString()
12
+ @IsOptional()
13
+ description?: string;
14
+
15
+ @ApiProperty({ example: 'PROD-001' })
16
+ @IsString()
17
+ @IsNotEmpty()
18
+ sku: string;
19
+
20
+ @ApiProperty({ example: 29.99 })
21
+ @IsNumber()
22
+ @Min(0)
23
+ price: number;
24
+
25
+ @ApiProperty({ example: 100 })
26
+ @IsNumber()
27
+ @Min(0)
28
+ stock: number;
29
+
30
+ @ApiPropertyOptional({ example: 'Electronics' })
31
+ @IsString()
32
+ @IsOptional()
33
+ category?: string;
34
+ }
@@ -0,0 +1,36 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+
3
+ export class ProductDto {
4
+ @ApiProperty({ example: '123e4567-e89b-12d3-a456-426614174000', format: 'uuid' })
5
+ id: string;
6
+
7
+ @ApiProperty({ example: 'Wireless Mouse' })
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ description?: string;
12
+
13
+ @ApiProperty({ example: 'PROD-001' })
14
+ sku: string;
15
+
16
+ @ApiProperty({ example: 29.99 })
17
+ price: number;
18
+
19
+ @ApiProperty({ example: 100 })
20
+ stock: number;
21
+
22
+ @ApiPropertyOptional({ example: 'Electronics' })
23
+ category?: string;
24
+
25
+ @ApiProperty({ example: 'ACTIVE' })
26
+ status: string;
27
+
28
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
29
+ createdAt: Date;
30
+
31
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
32
+ updatedAt: Date;
33
+
34
+ @ApiPropertyOptional({ nullable: true, example: null })
35
+ deletedAt?: Date | null;
36
+ }
@@ -0,0 +1,4 @@
1
+ import { PartialType } from '@nestjs/swagger';
2
+ import { CreateProductDto } from './create-product.dto';
3
+
4
+ export class UpdateProductDto extends PartialType(CreateProductDto) {}
@@ -76,4 +76,3 @@ export class ProductsController extends BaseController<
76
76
  return super.findOne(id);
77
77
  }
78
78
  }
79
-
@@ -0,0 +1,34 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { IsString, IsNotEmpty, IsNumber, IsOptional, Min } from 'class-validator';
3
+
4
+ export class CreateProductDto {
5
+ @ApiProperty({ example: 'Wireless Mouse' })
6
+ @IsString()
7
+ @IsNotEmpty()
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ @IsString()
12
+ @IsOptional()
13
+ description?: string;
14
+
15
+ @ApiProperty({ example: 'PROD-001' })
16
+ @IsString()
17
+ @IsNotEmpty()
18
+ sku: string;
19
+
20
+ @ApiProperty({ example: 29.99 })
21
+ @IsNumber()
22
+ @Min(0)
23
+ price: number;
24
+
25
+ @ApiProperty({ example: 100 })
26
+ @IsNumber()
27
+ @Min(0)
28
+ stock: number;
29
+
30
+ @ApiPropertyOptional({ example: 'Electronics' })
31
+ @IsString()
32
+ @IsOptional()
33
+ category?: string;
34
+ }
@@ -0,0 +1,36 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+
3
+ export class ProductDto {
4
+ @ApiProperty({ example: '123e4567-e89b-12d3-a456-426614174000', format: 'uuid' })
5
+ id: string;
6
+
7
+ @ApiProperty({ example: 'Wireless Mouse' })
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ description?: string;
12
+
13
+ @ApiProperty({ example: 'PROD-001' })
14
+ sku: string;
15
+
16
+ @ApiProperty({ example: 29.99 })
17
+ price: number;
18
+
19
+ @ApiProperty({ example: 100 })
20
+ stock: number;
21
+
22
+ @ApiPropertyOptional({ example: 'Electronics' })
23
+ category?: string;
24
+
25
+ @ApiProperty({ example: 'ACTIVE' })
26
+ status: string;
27
+
28
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
29
+ createdAt: Date;
30
+
31
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
32
+ updatedAt: Date;
33
+
34
+ @ApiPropertyOptional({ nullable: true, example: null })
35
+ deletedAt?: Date | null;
36
+ }
@@ -0,0 +1,4 @@
1
+ import { PartialType } from '@nestjs/swagger';
2
+ import { CreateProductDto } from './create-product.dto';
3
+
4
+ export class UpdateProductDto extends PartialType(CreateProductDto) {}
@@ -0,0 +1,78 @@
1
+ import {
2
+ Controller,
3
+ Get,
4
+ Param,
5
+ Query,
6
+ ParseUUIDPipe,
7
+ HttpStatus,
8
+ Type,
9
+ } from '@nestjs/common';
10
+ import {
11
+ ApiTags,
12
+ ApiOperation,
13
+ ApiResponse,
14
+ ApiBearerAuth,
15
+ ApiExtraModels,
16
+ ApiParam,
17
+ } from '@nestjs/swagger';
18
+ import { BaseController } from '../../common/base/base.controller';
19
+ import {
20
+ ApiResponseDto,
21
+ ApiResponseSchema,
22
+ PaginatedResponseDto,
23
+ PaginatedResponseSchema,
24
+ PaginationQueryDto,
25
+ } from '../../common/base';
26
+ import { ProductsService, ProductEntity } from './products.service';
27
+ import { CreateProductDto } from './dto/create-product.dto';
28
+ import { UpdateProductDto } from './dto/update-product.dto';
29
+ import { ProductDto } from './dto/product.dto';
30
+
31
+ @ApiTags('Products')
32
+ @ApiBearerAuth('bearer')
33
+ @ApiExtraModels(ApiResponseDto, PaginatedResponseDto, ProductDto)
34
+ @Controller('products')
35
+ export class ProductsController extends BaseController<
36
+ ProductEntity,
37
+ CreateProductDto,
38
+ UpdateProductDto
39
+ > {
40
+ constructor(private readonly productsService: ProductsService) {
41
+ super(productsService);
42
+ }
43
+
44
+ protected getDtoClass(): Type<ProductEntity> {
45
+ return ProductDto as unknown as Type<ProductEntity>;
46
+ }
47
+
48
+ @Get()
49
+ @ApiOperation({ summary: 'Get all products (paginated)' })
50
+ @ApiResponse({ status: HttpStatus.OK, schema: PaginatedResponseSchema(ProductDto) })
51
+ @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized' })
52
+ override async findAll(@Query() pagination: PaginationQueryDto): Promise<PaginatedResponseDto<ProductEntity>> {
53
+ return super.findAll(pagination);
54
+ }
55
+
56
+ @Get('by-sku/:sku')
57
+ @ApiOperation({ summary: 'Get a product by SKU' })
58
+ @ApiParam({ name: 'sku', example: 'KB-WL-MEC-001' })
59
+ @ApiResponse({ status: HttpStatus.OK, schema: ApiResponseSchema(ProductDto) })
60
+ @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Product not found' })
61
+ async findBySku(@Param('sku') sku: string): Promise<ApiResponseDto<ProductEntity>> {
62
+ const data = await this.productsService.findBySku(sku);
63
+ return { success: true, data, meta: { correlationId: '', timestamp: new Date().toISOString() } };
64
+ }
65
+
66
+ @Get(':id')
67
+ @ApiOperation({ summary: 'Get a product by ID' })
68
+ @ApiParam({ name: 'id', format: 'uuid', example: '123e4567-e89b-12d3-a456-426614174000' })
69
+ @ApiResponse({ status: HttpStatus.OK, schema: ApiResponseSchema(ProductDto) })
70
+ @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Product not found' })
71
+ @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Invalid UUID' })
72
+ override async findOne(
73
+ @Param('id', new ParseUUIDPipe({ version: '4', errorHttpStatusCode: HttpStatus.BAD_REQUEST }))
74
+ id: string,
75
+ ): Promise<ApiResponseDto<ProductEntity>> {
76
+ return super.findOne(id);
77
+ }
78
+ }
@@ -0,0 +1,34 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+ import { IsString, IsNotEmpty, IsNumber, IsOptional, Min } from 'class-validator';
3
+
4
+ export class CreateProductDto {
5
+ @ApiProperty({ example: 'Wireless Mouse' })
6
+ @IsString()
7
+ @IsNotEmpty()
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ @IsString()
12
+ @IsOptional()
13
+ description?: string;
14
+
15
+ @ApiProperty({ example: 'PROD-001' })
16
+ @IsString()
17
+ @IsNotEmpty()
18
+ sku: string;
19
+
20
+ @ApiProperty({ example: 29.99 })
21
+ @IsNumber()
22
+ @Min(0)
23
+ price: number;
24
+
25
+ @ApiProperty({ example: 100 })
26
+ @IsNumber()
27
+ @Min(0)
28
+ stock: number;
29
+
30
+ @ApiPropertyOptional({ example: 'Electronics' })
31
+ @IsString()
32
+ @IsOptional()
33
+ category?: string;
34
+ }
@@ -0,0 +1,36 @@
1
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2
+
3
+ export class ProductDto {
4
+ @ApiProperty({ example: '123e4567-e89b-12d3-a456-426614174000', format: 'uuid' })
5
+ id: string;
6
+
7
+ @ApiProperty({ example: 'Wireless Mouse' })
8
+ name: string;
9
+
10
+ @ApiPropertyOptional({ example: 'Ergonomic wireless mouse' })
11
+ description?: string;
12
+
13
+ @ApiProperty({ example: 'PROD-001' })
14
+ sku: string;
15
+
16
+ @ApiProperty({ example: 29.99 })
17
+ price: number;
18
+
19
+ @ApiProperty({ example: 100 })
20
+ stock: number;
21
+
22
+ @ApiPropertyOptional({ example: 'Electronics' })
23
+ category?: string;
24
+
25
+ @ApiProperty({ example: 'ACTIVE' })
26
+ status: string;
27
+
28
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
29
+ createdAt: Date;
30
+
31
+ @ApiProperty({ example: '2025-01-01T00:00:00.000Z' })
32
+ updatedAt: Date;
33
+
34
+ @ApiPropertyOptional({ nullable: true, example: null })
35
+ deletedAt?: Date | null;
36
+ }
@@ -0,0 +1,4 @@
1
+ import { PartialType } from '@nestjs/swagger';
2
+ import { CreateProductDto } from './create-product.dto';
3
+
4
+ export class UpdateProductDto extends PartialType(CreateProductDto) {}
@@ -76,4 +76,3 @@ export class ProductsController extends BaseController<
76
76
  return super.findOne(id);
77
77
  }
78
78
  }
79
-