Repository: Sync-FATEC/API-4-BACK
Pull request #6: feat: Creating CRUD for user functions
Author: login: joaogabgr
Created: 2025-03-15T19:12:01Z | Merged: 2025-03-16T01:38:05Z

# Crud para dados do usuario

## Branch
- feat/Creating-update-delete-list-users-functions

## Changelog:
- Criei rota para deletar
- Crie rota para editar
- Crie rota de listar usuarios

## Como Testar:
- Rota de deletar é localhost:5000/api/auth/delete/{ID}
- Rota de editar é localhost:5000/api/auth/update/{ID*, nome, email, cpf, password} apenas o ID é obrigatorio
- rota de listar é localhost:5000/api/auth/list

## Dependências:
- npm i


Diff:
diff --git a/package-lock.json b/package-lock.json
index 959c933..bd19f50 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "bcryptjs": "^2.4.3",
+        "class-transformer": "^0.5.1",
         "cors": "^2.8.5",
         "dotenv": "^16.0.3",
         "express": "^4.18.2",
@@ -681,6 +682,12 @@
         "fsevents": "~2.3.2"
       }
     },
+    "node_modules/class-transformer": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
+      "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==",
+      "license": "MIT"
+    },
     "node_modules/cli-highlight": {
       "version": "2.1.11",
       "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz",
diff --git a/package.json b/package.json
index f78e8de..0a9486c 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
   "description": "",
   "dependencies": {
     "bcryptjs": "^2.4.3",
+    "class-transformer": "^0.5.1",
     "cors": "^2.8.5",
     "dotenv": "^16.0.3",
     "express": "^4.18.2",
diff --git a/src/application/use-cases/auth/AuthUseCase.ts b/src/application/use-cases/auth/AuthUseCase.ts
index 90324f9..fdac147 100644
--- a/src/application/use-cases/auth/AuthUseCase.ts
+++ b/src/application/use-cases/auth/AuthUseCase.ts
@@ -10,13 +10,13 @@ export class AuthUseCase {
         const user = await this.userRepository.findByEmail(email);
 
         if (!user) {
-            throw new Error('User not found');
+            throw new Error('Usuario não encontrado');
         }
 
         const passwordMatch = await compare(password, user.password);
 
         if (!passwordMatch) {
-            throw new Error('Invalid password');
+            throw new Error('Senha incorreta');
         }
 
         const token = sign(
diff --git a/src/application/use-cases/auth/DeleteUserUseCase.ts b/src/application/use-cases/auth/DeleteUserUseCase.ts
new file mode 100644
index 0000000..5903ec0
--- /dev/null
+++ b/src/application/use-cases/auth/DeleteUserUseCase.ts
@@ -0,0 +1,12 @@
+import { IUserRepository } from "../../../domain/entities/User";
+
+export class DeleteUserUseCase {
+    constructor(private userRepository: IUserRepository) {}
+
+    async execute(id: string): Promise<boolean> {
+        if (this.userRepository.findById(id) === null) {
+            throw new Error('Usuário não encontrado ou inexistente');
+        }
+        return await this.userRepository.delete(id);
+    }
+}
\ No newline at end of file
diff --git a/src/application/use-cases/auth/ListUserUseCase.ts b/src/application/use-cases/auth/ListUserUseCase.ts
new file mode 100644
index 0000000..96862bd
--- /dev/null
+++ b/src/application/use-cases/auth/ListUserUseCase.ts
@@ -0,0 +1,9 @@
+import { IUserRepository, User } from "../../../domain/entities/User";
+
+export class ListUserUseCase {
+    constructor(private userRepository: IUserRepository) {}
+
+    async execute(): Promise<User[]> {
+        return await this.userRepository.list();
+    }
+}
\ No newline at end of file
diff --git a/src/application/use-cases/auth/RegisterUseCase.ts b/src/application/use-cases/auth/RegisterUseCase.ts
index 8916914..2bd3d76 100644
--- a/src/application/use-cases/auth/RegisterUseCase.ts
+++ b/src/application/use-cases/auth/RegisterUseCase.ts
@@ -3,27 +3,20 @@ import { User, IUserRepository } from '../../../domain/entities/User';
 import { hash } from 'bcryptjs';
 import { sign } from 'jsonwebtoken';
 import { isValidCPF } from '../../operations/isValidCPF';
-
-interface RegisterUserRequest {
-    name: string;
-    email: string;
-    password: string;
-    cpf: string;
-    role?: string;
-}
+import RegisterUserDTO from '../../../web/dtos/auth/RegisterUserDTO';
 
 export class RegisterUseCase {
     constructor(private userRepository: IUserRepository) {}
 
-    async execute({ name, email, password, cpf, role }: RegisterUserRequest): Promise<{ user: Partial<User>; token: string }> {
-        const userExists = await this.userRepository.findByEmail(email);
-        const cpfExists = await this.userRepository.findByCpf(cpf);
+    async execute(userData: RegisterUserDTO): Promise<{ user: Partial<User>; token: string }> {
+        const userExists = await this.userRepository.findByEmail(userData.getEmail());
+        const cpfExists = await this.userRepository.findByCpf(userData.getCpf());
 
         if (userExists) {
             throw new Error('Usuário já existe');
         }
 
-        if (isValidCPF(cpf) === false) {
+        if (isValidCPF(userData.getCpf()) === false) {
             throw new Error('CPF inválido');
         }
 
@@ -31,14 +24,14 @@ export class RegisterUseCase {
             throw new Error('CPF já cadastrado');
         }
 
-        const hashedPassword = await hash(password, 8);
+        const hashedPassword = await hash(userData.getPassword(), 8);
 
         const user = await this.userRepository.create({
-            name,
-            email,
+            name: userData.getName(),
+            email: userData.getEmail(),
             password: hashedPassword,
-            cpf,
-            role
+            cpf: userData.getCpf(),
+            role: 'user'
         });
 
         const token = sign(
diff --git a/src/application/use-cases/auth/UpdateUserUseCase.ts b/src/application/use-cases/auth/UpdateUserUseCase.ts
new file mode 100644
index 0000000..604645e
--- /dev/null
+++ b/src/application/use-cases/auth/UpdateUserUseCase.ts
@@ -0,0 +1,45 @@
+import { hash } from "bcryptjs";
+import { IUserRepository, User } from "../../../domain/entities/User";
+import { UpdateUserDTO } from "../../../web/dtos/auth/UpdateUserDTO";
+import { isValidCPF } from "../../operations/isValidCPF";
+
+export class UpdateUserUseCase {
+    constructor(private userRepository: IUserRepository) { }
+
+    async execute(userData: UpdateUserDTO): Promise<User | null> {
+        const User = await this.userRepository.findById(userData.getId());
+        if (!User) throw new Error('Usuário não encontrado');
+
+        if (userData.getName() != '') {
+            User.name = userData.getName();
+        }
+
+        if (userData.getEmail() != User.email && userData.getEmail() != '') {
+            const emailExists = await this.userRepository.findByEmail(userData.getEmail());
+            if (emailExists) throw new Error('Email já cadastrado');
+        }
+
+        User.email = userData.getEmail();
+
+        if (userData.getCpf() != User.cpf && userData.getCpf() != '') {
+            const cpfExists = await this.userRepository.findByCpf(userData.getCpf());
+            if (cpfExists) throw new Error('CPF já cadastrado');
+        }
+
+        if (isValidCPF(userData.getCpf()) === false && userData.getCpf() != '') {
+            throw new Error('CPF inválido');
+        }
+
+        if (userData.getCpf() != '') {
+            User.cpf = userData.getCpf();
+        }
+        
+
+        if (userData.getPassword() != '' && userData.getPassword() != null) {
+            const hashedPassword = await hash(userData.getPassword(), 8);
+            User.password = hashedPassword;
+        }
+
+        return await this.userRepository.update(userData.getId(), User);
+    }
+}
\ No newline at end of file
diff --git a/src/domain/entities/User.ts b/src/domain/entities/User.ts
index b993d05..102097a 100644
--- a/src/domain/entities/User.ts
+++ b/src/domain/entities/User.ts
@@ -1,3 +1,4 @@
+import { Exclude } from 'class-transformer';
 import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
 
 @Entity()
@@ -12,6 +13,7 @@ export class User {
     email!: string;
 
     @Column()
+    @Exclude()
     password!: string;
 
     @Column({ nullable: true, default: 'user' })
@@ -26,6 +28,9 @@ export class User {
 
 export interface IUserRepository {
     create(user: Partial<User>): Promise<User>;
+    delete(id: string): Promise<boolean>;
+    update(id: string, user: Partial<User>): Promise<User | null>;
+    list(): Promise<User[]>;
     findByEmail(email: string): Promise<User | null>;
     findById(id: string): Promise<User | null>;
     findByCpf(cpf: string): Promise<User | null>;
diff --git a/src/infrastructure/middlewares/ensureAuthenticated.ts b/src/infrastructure/middlewares/ensureAuthenticated.ts
index ae3b041..e70a853 100644
--- a/src/infrastructure/middlewares/ensureAuthenticated.ts
+++ b/src/infrastructure/middlewares/ensureAuthenticated.ts
@@ -20,13 +20,13 @@ interface TokenPayload {
 
 export function ensureAuthenticated(
     request: Request,
-    response: Response,
+    response,
     next: NextFunction
 ): Response | void {
     const authHeader = request.headers.authorization;
 
     if (!authHeader) {
-        return response.sendError('JWT token is missing', 401);
+        return response.sendError('Token JWT não esta sendo enviado', 401);
     }
 
     const [, token] = authHeader.split(' ');
@@ -36,6 +36,6 @@ export function ensureAuthenticated(
         request.user = { name: decoded.name, role: decoded.role };
         return next();
     } catch (error) {
-        return response.sendError('Invalid JWT token', 401);
+        return response.sendError('Token JWT é invalido ou esta expirado!', 401);
     }
 }
\ No newline at end of file
diff --git a/src/infrastructure/middlewares/responseHandler.ts b/src/infrastructure/middlewares/responseHandler.ts
index fd4b58b..daf160a 100644
--- a/src/infrastructure/middlewares/responseHandler.ts
+++ b/src/infrastructure/middlewares/responseHandler.ts
@@ -1,5 +1,5 @@
 import { Request, Response, NextFunction } from 'express';
-import { ResponseModelDTO } from '../../domain/dtos/ResponseModelDTO';
+import { ResponseModelDTO } from '../../web/dtos/ResponseModelDTO';
 
 /**
  * Estende o objeto Response do Express para incluir métodos de resposta padronizados
diff --git a/src/infrastructure/repositories/UserRepository.ts b/src/infrastructure/repositories/UserRepository.ts
index 4544d04..213f3a5 100644
--- a/src/infrastructure/repositories/UserRepository.ts
+++ b/src/infrastructure/repositories/UserRepository.ts
@@ -1,7 +1,6 @@
 import { Repository } from 'typeorm';
 import { AppDataSource } from '../database/data-source';
 import { User, IUserRepository } from '../../domain/entities/User';
-
 export class UserRepository implements IUserRepository {
     private repository: Repository<User>;
 
@@ -14,6 +13,23 @@ export class UserRepository implements IUserRepository {
         return await this.repository.save(user);
     }
 
+    async delete(id: string): Promise<boolean> {
+        const result = await this.repository.delete(id);
+        return result.affected === 1;
+    }
+
+    async update(id: string, userData: Partial<User>): Promise<User | null> {
+        const user = await this.repository.findOne({ where: { id } });
+        if (!user) return null;
+
+        await this.repository.update(id, userData);
+        return await this.repository.findOne({ where: { id } });
+    }
+
+    async list(): Promise<User[]> {
+        return await this.repository.find();
+    }
+
     async findByEmail(email: string): Promise<User | null> {
         return await this.repository.findOne({ where: { email } });
     }
diff --git a/src/web/controllers/auth/DeleteUserController.ts b/src/web/controllers/auth/DeleteUserController.ts
new file mode 100644
index 0000000..7af1d5c
--- /dev/null
+++ b/src/web/controllers/auth/DeleteUserController.ts
@@ -0,0 +1,25 @@
+import { DeleteUserUseCase } from "../../../application/use-cases/auth/DeleteUserUseCase";
+import { Request, Response } from "express";
+
+export class DeleteUserController {
+    constructor(private deleteUserUseCase: DeleteUserUseCase) {}
+
+    async handle(request: Request, response): Promise<Response> {
+        try {
+            const { id } = request.params;
+
+            if (!id) {
+                return response.sendError('Usuário não encontrado ou inexistente', 400);
+            }
+
+            await this.deleteUserUseCase.execute(id);
+
+            return response.sendSuccess('Usuário deletado com sucesso', 200);
+        } catch (error) {
+            return response.sendError(
+                error instanceof Error ? error.message : 'Erro inesperado',
+                400
+            );
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/web/controllers/auth/ListUserController.ts b/src/web/controllers/auth/ListUserController.ts
new file mode 100644
index 0000000..3fb8dcb
--- /dev/null
+++ b/src/web/controllers/auth/ListUserController.ts
@@ -0,0 +1,22 @@
+import { ListUserUseCase } from "../../../application/use-cases/auth/ListUserUseCase";
+import { Request, Response } from 'express';
+import { instanceToPlain } from 'class-transformer';
+
+export class ListUserController {
+    constructor(private listUserUseCase: ListUserUseCase) {}
+
+    async handle(request: Request, response): Promise<Response> {
+        try {
+            const users = await this.listUserUseCase.execute();
+            
+            const usersWithoutPassword = instanceToPlain(users);
+
+            return response.sendSuccess(usersWithoutPassword, 200);
+        } catch (error) {
+            return response.sendError(
+                error instanceof Error ? error.message : 'Erro inesperado',
+                400
+            );
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/web/controllers/auth/RegisterController.ts b/src/web/controllers/auth/RegisterController.ts
index d1af9a5..d90dd38 100644
--- a/src/web/controllers/auth/RegisterController.ts
+++ b/src/web/controllers/auth/RegisterController.ts
@@ -1,26 +1,23 @@
 import { Request, Response } from 'express';
 import { RegisterUseCase } from '../../../application/use-cases/auth/RegisterUseCase';
+import RegisterUserDTO from '../../dtos/auth/RegisterUserDTO';
 
 export class RegisterController {
     constructor(private registerUseCase: RegisterUseCase) {}
 
     async handle(request: Request, response): Promise<Response> {
         try {
-            const { name, email, password, cpf, role } = request.body;
+            const { name, email, password, cpf } = request.body;
 
-            if (!name || !email || !password || !cpf || !role) {
+            if (!name || !email || !password || !cpf) {
                 return response.sendError('Nome, email, senha e CPF são obrigatórios', 400);
             }
 
-            const { user, token } = await this.registerUseCase.execute({
-                name,
-                email,
-                password,
-                cpf,
-                role
-            });
+            const userData: RegisterUserDTO = new RegisterUserDTO(name, email, password, cpf);
 
-            return response.sendSuccess({ user, token }, 201);
+            const { user, token } = await this.registerUseCase.execute(userData);
+
+            return response.sendSuccess({ user, token }, 200);
         } catch (error) {
             return response.sendError(
                 error instanceof Error ? error.message : 'Erro inesperado',
diff --git a/src/web/controllers/auth/UpdateUserController.ts b/src/web/controllers/auth/UpdateUserController.ts
new file mode 100644
index 0000000..0d5ab0a
--- /dev/null
+++ b/src/web/controllers/auth/UpdateUserController.ts
@@ -0,0 +1,29 @@
+import { UpdateUserUseCase } from "../../../application/use-cases/auth/UpdateUserUseCase";
+import { Request, Response } from 'express';
+import { UpdateUserDTO } from "../../dtos/auth/UpdateUserDTO";
+import { instanceToPlain } from "class-transformer";
+
+export class UpdateUserController {
+    constructor(private updateUserUseCase: UpdateUserUseCase) {}
+
+    async handle(request: Request, response): Promise<Response> {
+        try {
+            const { id, name, email, password, cpf } = request.body;
+
+            if (!id) {
+                return response.sendError('Usuário não encontrado ou inexistente', 400);
+            }
+
+            const userData: UpdateUserDTO = new UpdateUserDTO(id, name, email, cpf, password);
+
+            const user = await this.updateUserUseCase.execute(userData);
+
+            return response.sendSuccess(instanceToPlain(user), 200);
+        } catch (error) {
+            return response.sendError(
+                error instanceof Error ? error.message : 'Erro inesperado',
+                400
+            );
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/domain/dtos/ResponseModelDTO.ts b/src/web/dtos/ResponseModelDTO.ts
similarity index 100%
rename from src/domain/dtos/ResponseModelDTO.ts
rename to src/web/dtos/ResponseModelDTO.ts
diff --git a/src/web/dtos/auth/RegisterUserDTO.ts b/src/web/dtos/auth/RegisterUserDTO.ts
new file mode 100644
index 0000000..8996c48
--- /dev/null
+++ b/src/web/dtos/auth/RegisterUserDTO.ts
@@ -0,0 +1,29 @@
+export default class RegisterUserDTO {
+    protected name: string;
+    private email: string;
+    private cpf: string;
+    private password: string;
+
+    constructor(name: string, email: string, password: string, cpf: string) {
+        this.name = name;
+        this.email = email;
+        this.password = password;
+        this.cpf = cpf;
+    }
+
+    public getName(): string {
+        return this.name;
+    }
+
+    public getEmail(): string {
+        return this.email;
+    }
+
+    public getCpf(): string {
+        return this.cpf;
+    }
+
+    public getPassword(): string {
+        return this.password;
+    }
+}
\ No newline at end of file
diff --git a/src/web/dtos/auth/UpdateUserDTO.ts b/src/web/dtos/auth/UpdateUserDTO.ts
new file mode 100644
index 0000000..e7875d6
--- /dev/null
+++ b/src/web/dtos/auth/UpdateUserDTO.ts
@@ -0,0 +1,35 @@
+export class UpdateUserDTO {
+    private id: string;
+    private name: string;
+    private email: string;
+    private cpf: string;
+    private password: string;
+
+    constructor(id: string, name: string, email: string, cpf: string, password: string) {
+        this.id = id;
+        this.name = name;
+        this.email = email;
+        this.cpf = cpf;
+        this.password = password;
+    }
+
+    public getId(): string {
+        return this.id;
+    }
+
+    public getName(): string {
+        return this.name;
+    }
+
+    public getEmail(): string {
+        return this.email;
+    }
+
+    public getCpf(): string {
+        return this.cpf;
+    }
+
+    public getPassword(): string {
+        return this.password;
+    }
+}
\ No newline at end of file
diff --git a/src/web/routes/auth.routes.ts b/src/web/routes/auth.routes.ts
index 03ccd3f..c136d86 100644
--- a/src/web/routes/auth.routes.ts
+++ b/src/web/routes/auth.routes.ts
@@ -4,6 +4,12 @@ import { RegisterUseCase } from '../../application/use-cases/auth/RegisterUseCas
 import { UserRepository } from '../../infrastructure/repositories/UserRepository';
 import { AuthController } from '../controllers/auth/AuthController';
 import { RegisterController } from '../controllers/auth/RegisterController';
+import { UpdateUserUseCase } from '../../application/use-cases/auth/UpdateUserUseCase';
+import { UpdateUserController } from '../controllers/auth/UpdateUserController';
+import { DeleteUserUseCase } from '../../application/use-cases/auth/DeleteUserUseCase';
+import { DeleteUserController } from '../controllers/auth/DeleteUserController';
+import { ListUserUseCase } from '../../application/use-cases/auth/ListUserUseCase';
+import { ListUserController } from '../controllers/auth/ListUserController';
 
 const authRoutes = Router();
 const userRepository = new UserRepository();
@@ -16,8 +22,27 @@ const authController = new AuthController(authUseCase);
 const registerUseCase = new RegisterUseCase(userRepository);
 const registerController = new RegisterController(registerUseCase);
 
+// Update
+const updateUserUseCase = new UpdateUserUseCase(userRepository);
+const updateController = new UpdateUserController(updateUserUseCase);
+
+
+// Delete 
+const deleteUserUseCase = new DeleteUserUseCase(userRepository);
+const deleteController = new DeleteUserController(deleteUserUseCase);
+
+// List
+const listUserUseCase = new ListUserUseCase(userRepository);
+const listController = new ListUserController(listUserUseCase);
 
 authRoutes.post('/login', (req, res) => authController.login(req, res));
+
 authRoutes.post('/register', (req, res) => registerController.handle(req, res));
 
+authRoutes.put('/update', (req, res) => updateController.handle(req, res));
+
+authRoutes.delete('/delete/:id', (req, res) => deleteController.handle(req, res));
+
+authRoutes.get('/list', (req, res) => listController.handle(req, res));
+
 export { authRoutes }; 
\ No newline at end of file


Reviews:
user: login: collafilipe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-15T19:22:37Z
user: login: collafilipe
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-15T19:24:45Z
user: login: joaogabgr
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-15T23:56:51Z
user: login: collafilipe
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-16T01:37:44Z

Review comments:
diff_hunk: @@ -19,7 +19,7 @@ async function bootstrap() {
     await initializeDatabase();
 
     // Rotas
-    app.use('/auth', authRoutes);
+    app.use('/api/auth', authRoutes);
path: src/server.ts
user: login: collafilipe
body: o /api tem ser no front, pois é la q nginx.conf vai olhar qual rota é pro back ou não
created_at: 2025-03-15T19:18:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+import { DeleteUserUseCase } from "../../../application/use-cases/auth/DeleteUserUseCase";
+import { Request, Response } from "express";
+
+export class DeleteUserController {
+    constructor(private deleteUserUseCase: DeleteUserUseCase) {}
+
+    async handle(request: Request, response): Promise<Response> {
+        try {
+            const { id } = request.params;
+
+            if (!id) {
+                return response.sendError('ID é obrigatório', 400);
path: src/web/controllers/auth/DeleteUserController.ts
user: login: collafilipe
body: Acho q seria melhor deixar 'Usuário não encontrado ou inexistente'
created_at: 2025-03-15T19:19:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,28 @@
+import { UpdateUserUseCase } from "../../../application/use-cases/auth/UpdateUserUseCase";
+import { Request, Response } from 'express';
+import { UpdateUserDTO } from "../../dtos/auth/UpdateUserDTO";
+
+export class UpdateUserController {
+    constructor(private updateUserUseCase: UpdateUserUseCase) {}
+
+    async handle(request: Request, response): Promise<Response> {
+        try {
+            const { id, name, email, password, cpf } = request.body;
+
+            if (!id) {
path: src/web/controllers/auth/UpdateUserController.ts
user: login: collafilipe
body: Seria melhor colocar todos como você fez no de registrar
created_at: 2025-03-15T19:21:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,28 @@
+import { UpdateUserUseCase } from "../../../application/use-cases/auth/UpdateUserUseCase";
+import { Request, Response } from 'express';
+import { UpdateUserDTO } from "../../dtos/auth/UpdateUserDTO";
+
+export class UpdateUserController {
+    constructor(private updateUserUseCase: UpdateUserUseCase) {}
+
+    async handle(request: Request, response): Promise<Response> {
+        try {
+            const { id, name, email, password, cpf } = request.body;
+
+            if (!id) {
path: src/web/controllers/auth/UpdateUserController.ts
user: login: collafilipe
body: tipo if (!id !name !email e etc
created_at: 2025-03-15T19:24:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,28 @@
+import { UpdateUserUseCase } from "../../../application/use-cases/auth/UpdateUserUseCase";
+import { Request, Response } from 'express';
+import { UpdateUserDTO } from "../../dtos/auth/UpdateUserDTO";
+
+export class UpdateUserController {
+    constructor(private updateUserUseCase: UpdateUserUseCase) {}
+
+    async handle(request: Request, response): Promise<Response> {
+        try {
+            const { id, name, email, password, cpf } = request.body;
+
+            if (!id) {
path: src/web/controllers/auth/UpdateUserController.ts
user: login: joaogabgr
body: ta assim pq nao sao dados obrigatorios, se vc nao mandar nada ele nao atualiza o campo, no register todos eles são obrigatorios


created_at: 2025-03-15T23:56:51Z
author_association: MEMBER

PR comments:
user: login: collafilipe
created_at: 2025-03-15T19:27:49Z
body: ta very good nice, só arrumar esses trem ai q fica melhor ainda
author_association: CONTRIBUTOR
user: login: Kaue-Francisco
created_at: 2025-03-15T22:14:01Z
body: Tem umas log que ta em português, tem outros em inglês. Tem que definir isso ai master

Também acho bom caso for colocar algum log, a gente armazenar num arquivo de log mesmo ao invés do terminal.
author_association: MEMBER