Skip to content

Commit 819a6e5

Browse files
committed
feat: add req body validation & swagger docs to users routes
1 parent 7058145 commit 819a6e5

File tree

7 files changed

+117
-41
lines changed

7 files changed

+117
-41
lines changed

package-lock.json

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
"@nestjs/swagger": "^7.3.1",
3535
"@prisma/client": "^5.13.0",
3636
"bcrypt": "^5.1.1",
37+
"class-transformer": "^0.5.1",
38+
"class-validator": "^0.14.1",
3739
"date-fns": "^3.6.0",
3840
"passport-jwt": "^4.0.1",
3941
"reflect-metadata": "^0.2.0",

src/users/dtos/CreateUserDTO.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsNotEmpty, IsString } from 'class-validator';
3+
4+
export class CreateUserDTO {
5+
@ApiProperty({ type: 'string', example: 'John' })
6+
@IsNotEmpty()
7+
@IsString()
8+
readonly name = '';
9+
10+
@ApiProperty({ type: 'string', example: 'Doe' })
11+
@IsNotEmpty()
12+
@IsString()
13+
readonly lastName = '';
14+
15+
@ApiProperty({ type: 'string', example: '(55) 99671-6164' })
16+
@IsNotEmpty()
17+
@IsString()
18+
readonly phone = '';
19+
}

src/users/dtos/UpdateUserDTO.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsOptional, IsString } from 'class-validator';
3+
4+
export class UpdateUserDTO {
5+
@ApiProperty({ type: 'string', example: 'John' })
6+
@IsOptional()
7+
@IsString()
8+
readonly name?: string;
9+
10+
@ApiProperty({ type: 'string', example: 'Doe' })
11+
@IsOptional()
12+
@IsString()
13+
readonly lastName?: string;
14+
15+
@ApiProperty({ type: 'string', example: 'John' })
16+
@IsOptional()
17+
@IsString()
18+
readonly login?: string;
19+
20+
@ApiProperty({ type: 'string', example: 'john123' })
21+
@IsOptional()
22+
@IsString()
23+
readonly password?: string;
24+
25+
@ApiProperty({ type: 'string', example: '(55) 99671-6164' })
26+
@IsOptional()
27+
@IsString()
28+
readonly phone?: string;
29+
}

src/users/types.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/users/users.controller.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,21 @@ import {
99
Req,
1010
UseGuards,
1111
} from '@nestjs/common';
12-
import { ApiTags } from '@nestjs/swagger';
12+
import {
13+
ApiBadRequestResponse,
14+
ApiBearerAuth,
15+
ApiCreatedResponse,
16+
ApiInternalServerErrorResponse,
17+
ApiTags,
18+
ApiUnauthorizedResponse,
19+
} from '@nestjs/swagger';
1320

1421
import { UserGuard } from '@/guards/user.guard';
1522
import { ServerResponse } from '../utils';
1623
import { UsersService } from './users.service';
1724
import { AdminGuard } from '@/guards/admin.guard';
25+
import { CreateUserDTO } from './dtos/CreateUserDTO';
26+
import { UpdateUserDTO } from './dtos/UpdateUserDTO';
1827

1928
@ApiTags('Usuários')
2029
@Controller('users')
@@ -23,9 +32,13 @@ export class UsersController {
2332

2433
constructor(private readonly userServices: UsersService) {}
2534

35+
@ApiUnauthorizedResponse()
36+
@ApiBadRequestResponse()
37+
@ApiInternalServerErrorResponse()
38+
@ApiCreatedResponse()
2639
@Post('')
2740
@UseGuards(AdminGuard)
28-
async store(@Body() body) {
41+
async store(@Body() body: CreateUserDTO) {
2942
try {
3043
await this.userServices.store(body);
3144
return new ServerResponse(201, 'Successfully created user');
@@ -35,9 +48,14 @@ export class UsersController {
3548
}
3649
}
3750

51+
@ApiBearerAuth()
52+
@ApiUnauthorizedResponse()
53+
@ApiBadRequestResponse()
54+
@ApiInternalServerErrorResponse()
55+
@ApiCreatedResponse()
3856
@Put(':id')
3957
@UseGuards(AdminGuard)
40-
async update(@Body() body, @Param('id') id: string) {
58+
async update(@Body() body: UpdateUserDTO, @Param('id') id: string) {
4159
try {
4260
await this.userServices.update(id, body);
4361
return new ServerResponse(201, 'Successfully updated user');
@@ -47,9 +65,14 @@ export class UsersController {
4765
}
4866
}
4967

68+
@ApiBearerAuth()
69+
@ApiUnauthorizedResponse()
70+
@ApiBadRequestResponse()
71+
@ApiInternalServerErrorResponse()
72+
@ApiCreatedResponse()
5073
@Put('')
5174
@UseGuards(UserGuard)
52-
async selfUpdate(@Body() body, @Req() req) {
75+
async selfUpdate(@Body() body: UpdateUserDTO, @Req() req) {
5376
try {
5477
const { userId } = req.user;
5578
await this.userServices.update(userId, body);

src/users/users.service.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Injectable } from '@nestjs/common';
22

33
import { PrismaService } from '../prisma/prisma.service';
4-
import { CreateUserSchema, UpdateUserSchema } from './types';
4+
import { CreateUserDTO } from './dtos/CreateUserDTO';
5+
import { UpdateUserDTO } from './dtos/UpdateUserDTO';
56

67
@Injectable()
78
export class UsersService {
89
constructor(private readonly prismaService: PrismaService) {}
910

10-
async store(body: any) {
11-
const { name, lastName, phone } = CreateUserSchema.parse(body);
11+
async store({ name, lastName, phone }: CreateUserDTO) {
1212
await this.prismaService.user.create({
1313
data: {
1414
name,
@@ -21,14 +21,13 @@ export class UsersService {
2121
});
2222
}
2323

24-
async update(id: string, body: any) {
25-
const payload = UpdateUserSchema.parse(body);
24+
async update(id: string, body: UpdateUserDTO) {
2625
await this.prismaService.user.update({
2726
where: {
2827
id,
2928
},
3029
data: {
31-
...payload,
30+
...body,
3231
updatedAt: new Date().toISOString(),
3332
},
3433
});

0 commit comments

Comments
 (0)