Entrega teste Pablo oliveira ferreira#85
Conversation
WalkthroughReplaces an AdonisJS app with an Express + Prisma + MongoDB stack. Removes Adonis configs, providers, and tests; adds Express server, routers, controllers for users/tasks/typeNotes/login, Prisma schema and client, and Jest unit tests. Updates tooling: ESLint, Prettier, Babel, Jest, tsconfig, and package.json. Simplifies various dotfiles and documentation. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant C as Client
participant API as Express Router
participant LC as LoginController
participant DB as Prisma (MongoDB)
U->>C: Submit email/password
C->>API: POST /api/login
API->>LC: handle(request, response)
LC->>DB: user.findFirst({ email, password, include: userImages })
alt match found
DB-->>LC: user
LC-->>API: 200 { msg, login }
API-->>C: 200 OK
else no match
DB-->>LC: null
LC-->>API: 401 { msg }
API-->>C: 401 Unauthorized
end
opt unexpected error
DB-->>LC: throw
LC-->>API: 500 { msg }
API-->>C: 500 Error
end
sequenceDiagram
autonumber
actor U as User
participant C as Client
participant API as Express Router
participant CT as CreateTaskController
participant DB as Prisma (MongoDB)
U->>C: Create Task (titulo, task, userId)
C->>API: POST /api/createTask
API->>CT: handle(req,res)
CT->>CT: validate fields + format createdAt
CT->>DB: task.create({ data: { titulo, task, createdAt, users.connect:{id} } })
alt success
DB-->>CT: newTask
CT-->>API: 201 { msg, newTask }
API-->>C: 201 Created
else error
DB-->>CT: throw
CT-->>API: 500 { msg }
API-->>C: 500 Error
end
sequenceDiagram
autonumber
actor U as User
participant C as Client
participant API as Express Router
participant UT as UpdateTaskController
participant DB as Prisma (MongoDB)
U->>C: Update Task (id, userId, titulo, task)
C->>API: PATCH /api/updateTask
API->>UT: handle(req,res)
UT->>UT: compute updatedAt
UT->>DB: task.update({ where:{ id, userId }, data:{ titulo, task, updatedAt } })
alt success
DB-->>UT: updateTask
UT-->>API: 200 { msg, updateTask }
API-->>C: 200 OK
else failure
DB-->>UT: throw
UT-->>API: 500 { msg }
API-->>C: 500 Error
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 62
🧹 Nitpick comments (60)
.prettierrc.json (1)
1-6: Prefer trailing commas to reduce diff noiseConsider using trailingComma "es5" for cleaner PRs and easier re-ordering.
{ - "trailingComma": "none", + "trailingComma": "es5", "tabWidth": 4, "semi": true, "singleQuote": true }jest.unit.json (1)
1-7: Set Node environment and avoid config duplication with jest.config.js
- Explicitly set testEnvironment: "node" for backend tests.
- If jest.config.js also exists, ensure scripts choose one config to avoid divergence.
{ "preset": "ts-jest", "coverageDirectory": "./coverage", "testMatch": ["**/?(*.)+(spec).ts"], "resetMocks": true, - "clearMocks": true + "clearMocks": true, + "testEnvironment": "node" }Can you confirm which config your npm scripts use (jest.config.js vs jest.unit.json)?
.eslintignore (1)
1-3: Reassess ignoring all root .js files; add common noisy folders
- Pattern /*.js will skip linting of root configs (e.g., jest.config.js, babel.config.js). Confirm intent.
- Add common outputs (coverage, build) to cut lint time/noise.
-/*.js node_modules dist +coverage +build.gitignore (1)
1-3: .gitignore is too minimal — risk of committing artifacts and secretsReintroduce standard Node/TS ignores (logs, coverage, caches, build outputs, TS build info, Prisma migrations). Keep lockfiles committed.
node_modules # Keep environment variables out of version control .env + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +pnpm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage +coverage +.nyc_output + +# Caches +.cache +.eslintcache +.stylelintcache + +# Build outputs +dist +build +out +tmp +temp + +# TypeScript +*.tsbuildinfo + +# Prisma +prisma/migrations/jest.config.js (1)
2-5: Harden Jest config and map "@/*" to src.Prevents scanning dist, resets mocks, and resolves TS path alias during tests.
module.exports = { - preset: 'ts-jest', - testEnvironment: 'node' + preset: 'ts-jest', + testEnvironment: 'node', + moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1' }, + testPathIgnorePatterns: ['/dist/'], + clearMocks: true };package.json (3)
6-19: Move dev-only packages and type packages out of production deps.
@types/*,nodemon, andts-node-devshouldn’t ship to prod."dependencies": { - "@types/cors": "^2.8.17", - "@types/multer": "^1.4.11", "axios": "^1.2.2", "cors": "^2.8.5", "date-fns": "^2.30.0", "express": "^4.18.2", "mongodb": "^6.3.0", "mongoose": "^6.8.2", "multer": "^1.4.5-lts.1", - "nodemon": "^3.0.3", - "ts-node-dev": "^2.0.0" + "nodemon": undefined, + "ts-node-dev": undefined }, "devDependencies": { + "@types/cors": "^2.8.17", + "@types/multer": "^1.4.11", + "nodemon": "^3.0.3", + "ts-node-dev": "^2.0.0",Note: Remove the temporary “undefined” keys above when applying; they illustrate removals.
Also applies to: 33-51
20-29: Add type checking and (optionally) tsconfig-paths in dev.Ensures CI type-checks and local runs honor TS path aliases.
"scripts": { - "test": "jest --no-cache", - "dev": "ts-node-dev --transpile-only --respawn --ignore-watch node_modules ./src/server.ts", + "test": "jest --no-cache", + "typecheck": "tsc -p tsconfig.json --noEmit", + "dev": "ts-node-dev --transpile-only --respawn -r tsconfig-paths/register --ignore-watch node_modules ./src/server.ts", "build": "npx babel src --extensions \".js,.ts\" --out-dir dist --copy-files --no-copy-ignored ", "start": "node dist/server.js", "format:check": "prettier --check .", "format:write": "prettier --write .", "lint:check": "eslint .", "lint:fix": "eslint --fix ." },If you adopt this, add
tsconfig-pathsto devDependencies.
1-53: Pick one data access layer to reduce complexity.You depend on Prisma+MongoDB and Mongoose concurrently. Maintaining both ORMs increases cognitive load and risk of divergent models. Prefer standardizing on one unless there’s a clear boundary/use-case.
tsconfig.json (1)
2-23: Align lib/target and tighten compiler checks.
- lib "es6" is below target ES2020; align to avoid missing typings.
- Add strict and moduleResolution for predictable behavior.
- Keep decorators options only if actually used (build uses Babel).
"compilerOptions": { - "target": "ES2020", - "module": "commonjs", - "lib": ["es6"], + "target": "ES2020", + "module": "commonjs", + "lib": ["ES2020"], "allowJs": true, "outDir": "./dist", "rootDir": "./src", "removeComments": true, "typeRoots": ["./node_modules/@types", "./src/types"], + "moduleResolution": "node", + "strict": true, "esModuleInterop": true, "resolveJsonModule": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, + "experimentalDecorators": false, + "emitDecoratorMetadata": false, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "baseUrl": ".", "paths": { "@/*": ["./src/*"] } },If you do use decorators, keep them enabled here and add the Babel plugins noted in babel.config.js review.
PULL_REQUEST.md (4)
21-25: Fix empty/invalid nav link and bracket lint warning.Linking to
#violates MD042 and creates “unpaired bracket” noise. Point to an existing section or remove it.[**Desafio**](#desafio) **•** [**Tecnologias**](#tecnologias) **•** -[**Backend-Api**](#) **•** +[**Rotas**](#rotas) **•**
47-48: Corrija instruções do Prisma.
npx prisma generateapenas gera o client; não “sobe” o banco.-- Ao instalar o projeto/ iniciar do zero deve adicionar um novo .env e configurar a string de conexão do bd mongo `DATABASE_URL` e por fim executar o cmg `npx prisma generate` e irá subir o banco de dados . +- Ao instalar o projeto, crie um `.env`, configure `DATABASE_URL` (MongoDB) e execute `npx prisma generate` para gerar o Prisma Client. (Se usar migrações, aplique-as conforme necessário.)
50-51: Ajuste de linguagem/clareza.Frase ambígua; melhore a explicação.
-- Foi criada uma tabela onde o tipo de nota e criado e others === null se mais tarde for necessario acrescentar novos tipos e so adicionar ! +- Foi criada uma coleção para tipos de notas. Campos não utilizados permanecem `null`. Novos tipos podem ser adicionados futuramente sem impacto nas rotas existentes.
82-85: Especifique linguagem no bloco de código (MD040).-``` +```text Base url da rota BaseUrl https://apicorelab-iqxx.onrender.com</blockquote></details> <details> <summary>src/database/prismaClient.ts (2)</summary><blockquote> `3-5`: **Avoid multiple PrismaClient instances in dev/tests** Cache the client on globalThis to prevent excessive connections during Jest runs or hot-reload. Also export the cached instance. ```diff -import { PrismaClient } from '@prisma/client'; - -const prismaClient = new PrismaClient(); - -export { prismaClient }; +import { PrismaClient } from '@prisma/client'; + +const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient }; +const prismaClient = globalForPrisma.prisma ?? new PrismaClient({ + // Uncomment locally if you want more visibility: + // log: ['warn', 'error'], +}); +if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prismaClient; + +export { prismaClient };
1-5: Graceful shutdown hookEnsure prismaClient.$disconnect() is called on SIGINT/SIGTERM in server bootstrap to avoid hanging processes on exit.
src/tests/user/findAllUsers.spec.ts (2)
9-15: Use jest.spyOn and restore mocks between testsDirectly overwriting prismaClient.user.findMany can leak across tests. Spy instead and restore.
- prismaClient.user.findMany = jest.fn().mockResolvedValue([]); + jest.spyOn(prismaClient.user, 'findMany').mockResolvedValue([]); @@ - prismaClient.user.findMany = jest - .fn() - .mockRejectedValueOnce(new Error('Unexpected error')); + jest + .spyOn(prismaClient.user, 'findMany') + .mockRejectedValueOnce(new Error('Unexpected error'));Add afterEach once in this file:
afterEach(() => { jest.restoreAllMocks(); });Also applies to: 28-31
18-20: Stronger assertion on payloadAssert the exact array returned to catch shape regressions.
- expect(mockResponse.json).toHaveBeenCalledWith(expect.any(Array)); + expect(mockResponse.json).toHaveBeenCalledWith([]);src/controllers/users/FindAllUsersController.ts (1)
7-13: Remove unreachable null/undefined branchprisma.user.findMany() returns an array (empty when no rows). The null/undefined check is dead code.
src/server.ts (1)
7-13: Consider basic hardening (helmet, JSON size, CORS origins).Add helmet, set JSON/body limits, and restrict CORS origins as needed.
+import helmet from 'helmet'; ... app.use(cors()); +app.use(helmet()); -app.use( - express.urlencoded({ - extended: true - }) -); -app.use(express.json()); +app.use(express.urlencoded({ extended: true, limit: '100kb' })); +app.use(express.json({ limit: '100kb' }));src/tests/user/updateUser.spec.ts (2)
59-63: Use spyOn instead of reassigning prisma methods; restore after test.Prevents cross-test leakage and preserves original method.
- prismaClient.user.update = jest - .fn() - .mockRejectedValue(new Error('Unexpected error')); + const updateMock = jest + .spyOn(prismaClient.user, 'update') + .mockRejectedValue(new Error('Unexpected error')); await controller.handle(mockRequest, mockResponse); + updateMock.mockRestore();
4-4: Remove unused import.
errorfrom 'console' is unused.-import { error } from 'console';src/controllers/tasks/UpdateCompletedTaskController.ts (2)
26-26: Fix response message grammar.“Task has been updated!” reads better.
- .json({ msg: 'Task as updated!', updateTask }); + .json({ msg: 'Task has been updated!', updateTask });
12-12: Prefer storing timestamps as Date/DateTime in DB, not preformatted strings.Store a Date and format at the edge when needed.
- const completedAt = Date.now(); + const completedAt = new Date(); ... - completedAt: format(completedAt, 'dd/MM/yyyy HH:mm:ss') + completedAt: completedAtAlso applies to: 19-22
src/controllers/users/FindUserByIdController.ts (1)
7-8: Consider reading id from route params for GET semantics.E.g., GET /users/:id with
request.params.id. Update router accordingly.src/tests/task/updatedCompletedTask.spec.ts (2)
41-41: Fix test description to match expected status (500).Currently title says 400 but assertions expect 500.
- it('should return a 400 status code and an error message if the update fails', async () => { + it('should return a 500 status code and an error message if the update fails', async () => {
31-39: Optionally decouple from exact timestamp string.If controller switches to Date or different format, assert shape not exact value.
- expect(mockResponse.json).toHaveBeenCalledWith({ - msg: 'Task as updated!', - updateTask: { - id: 'validTaskId', - titulo: 'New Title', - task: 'New Task', - completedAt: '01/01/2022 12:00:00' - } - }); + expect(mockResponse.json).toHaveBeenCalledWith({ + msg: 'Task has been updated!', + updateTask: expect.objectContaining({ + id: 'validTaskId', + titulo: 'New Title', + task: 'New Task', + completedAt: expect.anything() + }) + });src/controllers/users/DeleteUserByIdController.ts (2)
7-7: Type the request body using Express generics.Improves type-safety at the boundary.
- async handle(request: Request, response: Response) { + async handle(request: Request<{}, {}, DeleteByIdBody>, response: Response) {
1-26: Guard destructive ops with auth/authorization.A delete-by-id endpoint should require authentication and enforce ownership/admin checks.
src/controllers/typeNotes/deleteTypeController.ts (1)
6-6: Use PascalCase for class names.-export class deleteTypeController { +export class DeleteTypeController {src/controllers/typeNotes/CreateTypeNotesController.ts (1)
3-5: Interface and naming nits.Prefer PascalCase for interfaces and avoid shadowing route names in variables.
-interface createTypeNotesBody { +interface CreateTypeNotesBody { name: string; }src/controllers/tasks/FindAllTasksByUserIdController.ts (2)
29-29: Status code/message for invalid id.Use 400 with a precise message; current 404 “Person is not found!” is misleading and grammatically off.
- return response.status(404).json({ msg: 'Person is not found!' }); + return response.status(400).json({ msg: 'Invalid or missing user id.' });
22-27: Avoid console.log in handlers.Use a structured logger and avoid leaking internals in responses.
src/tests/task/updateTask.spec.ts (3)
30-30: Test name vs expectation mismatch.The test asserts 500 but says “return a 400”. Align the description.
- it('should handle and return a 400 status code with an error message for invalid input data', async () => { + it('should handle and return a 500 status code with an error message for invalid input data', async () => {
5-7: Reset mocks between tests to avoid cross-test leakage.const controller = new UpdateTaskController(); +beforeEach(() => { + jest.resetAllMocks(); +});
21-22: Prefer jest.spyOn over direct reassignment for stronger typing.- prismaClient.task.update = jest.fn().mockResolvedValue({}); + jest.spyOn(prismaClient.task, 'update').mockResolvedValue({} as any); ... -prismaClient.task.update=jest.fn().mockRejectedValue(new Error('Invalid input')); + jest.spyOn(prismaClient.task, 'update').mockRejectedValue(new Error('Invalid input'));Also applies to: 43-44
src/tests/task/createTask.spec.ts (1)
13-15: Remove unused createdAt from request bodiesController ignores request.body.createdAt and computes its own timestamp. Dropping it reduces confusion.
- createdAt: '2022-01-01T00:00:00.000Z',Also applies to: 37-39, 60-62
src/tests/user/deleteUser.spec.ts (2)
20-35: Remove duplicated expectationSame assertion appears twice.
expect(prismaClient.user.delete).toHaveBeenCalledWith({ where: { id: 'validId' } }); - - expect(prismaClient.user.delete).toHaveBeenCalledWith({ - where: { - id: 'validId' - } - });
37-53: Consider covering undefined id and error pathAdd tests for id: undefined and prisma throwing to exercise 500 branch.
src/routers/router.ts (2)
71-73: DELETE /deleteUser should take id as a route paramPrefer
DELETE /users/:idinstead of reading from body for better REST semantics and to avoid GET/DELETE bodies.-router.delete('/deleteUser', deleteUser.handle); +router.delete('/users/:id', deleteUser.handle);Then change controller to read
request.params.id.
39-41: Return 201 when creating a resourceCreateTypeNotesController returns 200 on creation; consider 201 Created for consistency (controller change).
src/tests/user/findUserById.spec.ts (2)
50-71: Fix test name: expects 500, not 404The description contradicts the assertion.
- it('should return a 404 status code and an error message when an unexpected error occurs', async () => { + it('should return a 500 status code when an unexpected error occurs', async () => {
108-129: Remove duplicate error-handling testThis duplicates the previous 500-path coverage.
- it('should handle errors thrown by prismaClient', async () => { - const mockRequest = { - body: { - id: 'validId' - } - } as Request; - const mockResponse = { - status: jest.fn().mockReturnThis(), - json: jest.fn() - } as unknown as Response; - - prismaClient.user.findFirst = jest - .fn() - .mockRejectedValue(new Error('Prisma error')); - - await controller.handle(mockRequest, mockResponse); - - expect(mockResponse.status).toHaveBeenCalledWith(500); - expect(mockResponse.json).toHaveBeenCalledWith({ - msg: 'Internal server error!' - }); - });src/controllers/users/UpdateUserController.ts (5)
25-33: Handle missing image row gracefully.
userImages.updatewill throw ifimgIddoesn’t exist. Preferupsertwhen appropriate.- userImages: { - update: { - where: { id: imgId }, - data: { image: imgBuffer } - } - } + userImages: imgId && hasFile ? { + upsert: { + where: { id: imgId }, + update: { image: imgBuffer! }, + create: { id: imgId, image: imgBuffer! } + } + } : undefined
12-12: Type safety forrequest.file.Avoid
any. Use Express.Multer types or narrow with a type guard.- const imgBuffer: any = request.file?.buffer.toString('base64'); + const file = request.file as Express.Multer.File | undefined; + const imgBuffer = file ? file.buffer.toString('base64') : undefined;
13-14: Validate input.Add schema validation (e.g., zod) for
userName,password, andimgId.
21-22: Avoid redundant key repetition.Use shorthand properties for readability.
- userName: userName, - email: email, + userName, + email,
12-12: Store images outside the DB.Base64 in DB increases size and memory. Prefer object storage (e.g., S3/GCS) and only persist URLs/metadata.
src/controllers/typeNotes/FindTaskByTypeController.ts (1)
12-14: Simplify redundantAND.
ANDis unnecessary here.- AND:{ - typeId: '68b30e2856e18c21c1298cce', - } + typeId: '68b30e2856e18c21c1298cce'src/controllers/typeNotes/UpdateTypeNotesController.ts (1)
26-29: Response messages and statuses.
- “Task as updated!” → “Task has been updated!”
- 404 message says “Person”; should be “Task or type”.
- .json({ msg: 'Task as updated!', updateTask }); + .json({ msg: 'Task has been updated!', updateTask }); ... - .json({ msg: 'Person or type is not found!' }); + .json({ msg: 'Task or type not found!' });Also applies to: 37-38
src/controllers/tasks/UpdateTaskController.ts (3)
31-34: Status codes and messages.Use 400 for bad input; fix typos; keep responses consistent.
- return response - .status(500) - .json({ msg: 'Internal server error!' }); + return response.status(500).json({ msg: 'Internal server error!' }); ... - return response.status(500).json({ msg: 'Erro on server!' }); + return response.status(400).json({ msg: 'Missing id or userId' });Also applies to: 41-41
14-14: Validate and type request body.Use
Request<Params, ResBody, updateTaskBody>and a validator (zod/yup) to ensureid,userId,titulo, andtask.
26-27: Use property shorthand.Minor readability improvement.
- titulo: titulo, - task: task, + titulo, + task,src/tests/task/findTaskById.spec.ts (1)
4-4: Remove unused import.The
errorimport from 'console' is not used anywhere in the test file.-import { error } from 'console';src/controllers/login/LoginController.ts (1)
18-32: Consider implementing rate limiting for login attempts.To prevent brute force attacks, consider implementing rate limiting on login attempts, especially given the current lack of password hashing.
You could implement this using libraries like
express-rate-limitorexpress-slow-downto limit login attempts per IP address or email.src/tests/user/createUser.spec.ts (1)
33-34: Fix empty line in test data.There's an empty line in the request body object that should contain the password field or be removed for clarity.
body: { userName: 'JohnDoe', email: 'johndoe@example.com', - }src/controllers/tasks/CreateTaskController.ts (3)
1-3: Map Prisma errors to HTTP status (e.g., 404 on missing user).Return 404 when connect fails (P2025) instead of generic 500.
+import { Prisma } from '@prisma/client'; @@ - } catch (error) { - console.log(error); - return response.status(500).json({ msg: 'Internal server error!' }); - } + } catch (error) { + console.log(error); + if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2025') { + return response.status(404).json({ msg: 'User not found for the provided userId.' }); + } + return response.status(500).json({ msg: 'Internal server error!' }); + }Also applies to: 40-43
4-9: Tighten types: removecreatedAtfrom body and type Request body.The client doesn’t supply
createdAt; drop it from the interface and type the Request.interface TasksBody { titulo: string; task: string; - createdAt: string; userId: string; } export class CreateTaskController { - async handle(request: Request, response: Response) { + async handle(request: Request<unknown, unknown, TasksBody>, response: Response) {Also applies to: 11-11
37-39: Nit: success message grammar.- .json({ msg: 'Task as created!', newTask }); + .json({ msg: 'Task has been created!', newTask });src/controllers/users/CreateUsersController.ts (1)
30-40: CreateuserImagesonly when an image was uploaded.Avoid creating an empty child document.
const users = await prismaClient.user.create({ data: { - userName: userName, - email: email, - password: password, + userName: userNameStr, + email: emailStr, + password: hashedPassword, createdAt: format(createdAt, 'dd/MM/yyyy HH:mm:ss'), - userImages: { - create: { - image: imgBuffer - } - } + ...(imgBuffer ? { + userImages: { create: { image: imgBuffer } } + } : {}) }, include: { userImages: true } });prisma/schema.prisma (1)
34-45: Optional: rename singular relations for clarity (users->user,typeNotes->typeNote).No behavioral change; improves readability.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (32)
dist/controllers/login/LoginController.jsis excluded by!**/dist/**dist/controllers/tasks/CreateTaskController.jsis excluded by!**/dist/**dist/controllers/tasks/DeleteTaskController.jsis excluded by!**/dist/**dist/controllers/tasks/FindAllTasksByUserIdController.jsis excluded by!**/dist/**dist/controllers/tasks/FindTaskByIdController.jsis excluded by!**/dist/**dist/controllers/tasks/UpdateCompletedTaskController.jsis excluded by!**/dist/**dist/controllers/tasks/UpdateTaskController.jsis excluded by!**/dist/**dist/controllers/typeNotes/CreateTypeNotesController.jsis excluded by!**/dist/**dist/controllers/typeNotes/FindTaskByTypeController.jsis excluded by!**/dist/**dist/controllers/typeNotes/UpdateTypeNotesController.jsis excluded by!**/dist/**dist/controllers/typeNotes/deleteTypeController.jsis excluded by!**/dist/**dist/controllers/users/CreateUsersController.jsis excluded by!**/dist/**dist/controllers/users/DeleteUserByIdController.jsis excluded by!**/dist/**dist/controllers/users/FindAllUsersController.jsis excluded by!**/dist/**dist/controllers/users/FindUserByIdController.jsis excluded by!**/dist/**dist/controllers/users/updateUserController.jsis excluded by!**/dist/**dist/database/prismaClient.jsis excluded by!**/dist/**dist/routers/router.jsis excluded by!**/dist/**dist/server.jsis excluded by!**/dist/**dist/tests/login/login.spec.jsis excluded by!**/dist/**dist/tests/task/createTask.spec.jsis excluded by!**/dist/**dist/tests/task/deleteTask.spec.jsis excluded by!**/dist/**dist/tests/task/findAllTaskByUserId.spec.jsis excluded by!**/dist/**dist/tests/task/findTaskById.spec.jsis excluded by!**/dist/**dist/tests/task/updateTask.spec.jsis excluded by!**/dist/**dist/tests/task/updatedCompletedTask.spec.jsis excluded by!**/dist/**dist/tests/user/createUser.spec.jsis excluded by!**/dist/**dist/tests/user/deleteUser.spec.jsis excluded by!**/dist/**dist/tests/user/findAllUsers.spec.jsis excluded by!**/dist/**dist/tests/user/findUserById.spec.jsis excluded by!**/dist/**dist/tests/user/updateUser.spec.jsis excluded by!**/dist/**package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (73)
.adonisrc.json(0 hunks).editorconfig(0 hunks).env.example(0 hunks).eslintignore(1 hunks).eslintrc.json(1 hunks).gitignore(1 hunks).gitignore copy(0 hunks).prettierignore(0 hunks).prettierrc.json(1 hunks)Leiame.md(0 hunks)PULL_REQUEST.md(1 hunks)README.md(0 hunks)ace(0 hunks)ace-manifest.json(0 hunks)app/Controllers/VehiclesController.ts(0 hunks)app/Exceptions/Handler.ts(0 hunks)app/Types/Vehicle.ts(0 hunks)babel.config.js(1 hunks)commands/index.ts(0 hunks)config/app.ts(0 hunks)config/bodyparser.ts(0 hunks)config/cors.ts(0 hunks)config/drive.ts(0 hunks)config/hash.ts(0 hunks)contracts/drive.ts(0 hunks)contracts/env.ts(0 hunks)contracts/events.ts(0 hunks)contracts/hash.ts(0 hunks)contracts/tests.ts(0 hunks)env.ts(0 hunks)jest.config.js(1 hunks)jest.unit.json(1 hunks)package.json(1 hunks)prisma/schema.prisma(1 hunks)providers/AppProvider.ts(0 hunks)server.ts(0 hunks)src/controllers/login/LoginController.ts(1 hunks)src/controllers/tasks/CreateTaskController.ts(1 hunks)src/controllers/tasks/DeleteTaskController.ts(1 hunks)src/controllers/tasks/FindAllTasksByUserIdController.ts(1 hunks)src/controllers/tasks/FindTaskByIdController.ts(1 hunks)src/controllers/tasks/UpdateCompletedTaskController.ts(1 hunks)src/controllers/tasks/UpdateTaskController.ts(1 hunks)src/controllers/typeNotes/CreateTypeNotesController.ts(1 hunks)src/controllers/typeNotes/FindTaskByTypeController.ts(1 hunks)src/controllers/typeNotes/UpdateTypeNotesController.ts(1 hunks)src/controllers/typeNotes/deleteTypeController.ts(1 hunks)src/controllers/users/CreateUsersController.ts(1 hunks)src/controllers/users/DeleteUserByIdController.ts(1 hunks)src/controllers/users/FindAllUsersController.ts(1 hunks)src/controllers/users/FindUserByIdController.ts(1 hunks)src/controllers/users/UpdateUserController.ts(1 hunks)src/database/prismaClient.ts(1 hunks)src/routers/router.ts(1 hunks)src/server.ts(1 hunks)src/tests/login/login.spec.ts(1 hunks)src/tests/task/createTask.spec.ts(1 hunks)src/tests/task/deleteTask.spec.ts(1 hunks)src/tests/task/findAllTaskByUserId.spec.ts(1 hunks)src/tests/task/findTaskById.spec.ts(1 hunks)src/tests/task/updateTask.spec.ts(1 hunks)src/tests/task/updatedCompletedTask.spec.ts(1 hunks)src/tests/user/createUser.spec.ts(1 hunks)src/tests/user/deleteUser.spec.ts(1 hunks)src/tests/user/findAllUsers.spec.ts(1 hunks)src/tests/user/findUserById.spec.ts(1 hunks)src/tests/user/updateUser.spec.ts(1 hunks)start/kernel.ts(0 hunks)start/routes.ts(0 hunks)test.ts(0 hunks)tests/bootstrap.ts(0 hunks)tests/functional/vehicles-api.spec.ts(0 hunks)tsconfig.json(1 hunks)
💤 Files with no reviewable changes (31)
- .adonisrc.json
- README.md
- ace
- config/cors.ts
- .gitignore copy
- server.ts
- app/Types/Vehicle.ts
- .prettierignore
- contracts/hash.ts
- tests/functional/vehicles-api.spec.ts
- app/Exceptions/Handler.ts
- start/routes.ts
- contracts/tests.ts
- env.ts
- .env.example
- config/hash.ts
- providers/AppProvider.ts
- ace-manifest.json
- config/app.ts
- contracts/events.ts
- config/bodyparser.ts
- Leiame.md
- .editorconfig
- test.ts
- config/drive.ts
- start/kernel.ts
- contracts/env.ts
- commands/index.ts
- contracts/drive.ts
- app/Controllers/VehiclesController.ts
- tests/bootstrap.ts
🧰 Additional context used
🧬 Code graph analysis (30)
src/controllers/tasks/FindTaskByIdController.ts (1)
dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/users/FindAllUsersController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/typeNotes/FindTaskByTypeController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/task/createTask.spec.ts (2)
src/controllers/tasks/CreateTaskController.ts (1)
CreateTaskController(10-45)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/database/prismaClient.ts (1)
dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/task/updatedCompletedTask.spec.ts (2)
src/controllers/tasks/UpdateCompletedTaskController.ts (1)
UpdateCompletedTaskController(9-32)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/server.ts (2)
dist/server.js (2)
app(9-9)port(10-10)dist/routers/router.js (1)
router(24-24)
src/tests/user/findAllUsers.spec.ts (2)
src/controllers/users/FindAllUsersController.ts (1)
FindAllUsersController(4-19)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/task/findTaskById.spec.ts (2)
src/controllers/tasks/FindTaskByIdController.ts (1)
FindTaskByIdController(6-26)src/database/prismaClient.ts (1)
prismaClient(5-5)
src/controllers/tasks/DeleteTaskController.ts (3)
dist/routers/router.js (1)
deleteTask(55-55)src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/user/createUser.spec.ts (2)
src/controllers/users/CreateUsersController.ts (1)
CreateUsersController(11-53)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/user/findUserById.spec.ts (2)
src/controllers/users/FindUserByIdController.ts (1)
FindUserByIdController(6-35)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/users/DeleteUserByIdController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/tasks/UpdateCompletedTaskController.ts (1)
dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/users/UpdateUserController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/routers/router.ts (16)
dist/routers/router.js (17)
router(24-24)upload(26-26)createUser(27-27)loginUser(29-29)createTask(31-31)createTypeNotes(33-33)findUserById(35-35)findAllUsers(37-37)findTaskId(39-39)findAllTaskByUser(41-41)findFavoritesTasks(43-43)updateUser(45-45)updateTask(47-47)updateCompleteTask(49-49)updateTypeController(51-51)deleteUser(53-53)deleteTask(55-55)src/controllers/users/CreateUsersController.ts (1)
CreateUsersController(11-53)src/controllers/login/LoginController.ts (1)
LoginController(9-48)src/controllers/tasks/CreateTaskController.ts (1)
CreateTaskController(10-45)src/controllers/typeNotes/CreateTypeNotesController.ts (1)
CreateTypeNotesController(6-29)src/controllers/users/FindUserByIdController.ts (1)
FindUserByIdController(6-35)src/controllers/users/FindAllUsersController.ts (1)
FindAllUsersController(4-19)src/controllers/tasks/FindTaskByIdController.ts (1)
FindTaskByIdController(6-26)src/controllers/tasks/FindAllTasksByUserIdController.ts (1)
FindAllTasksByUserIdController(4-31)src/controllers/typeNotes/FindTaskByTypeController.ts (1)
FindFavoritesTasksController(4-26)src/controllers/users/UpdateUserController.ts (1)
UpdateUserController(10-42)src/controllers/tasks/UpdateTaskController.ts (1)
UpdateTaskController(12-43)src/controllers/tasks/UpdateCompletedTaskController.ts (1)
UpdateCompletedTaskController(9-32)src/controllers/typeNotes/UpdateTypeNotesController.ts (1)
UpdateTypeController(5-40)src/controllers/users/DeleteUserByIdController.ts (1)
DeleteUserByIdController(6-26)src/controllers/tasks/DeleteTaskController.ts (1)
DeleteTaskController(4-21)
src/tests/task/findAllTaskByUserId.spec.ts (2)
src/controllers/tasks/FindAllTasksByUserIdController.ts (1)
FindAllTasksByUserIdController(4-31)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/tasks/FindAllTasksByUserIdController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/users/FindUserByIdController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/login/login.spec.ts (2)
src/controllers/login/LoginController.ts (1)
LoginController(9-48)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/login/LoginController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/task/updateTask.spec.ts (2)
src/controllers/tasks/UpdateTaskController.ts (1)
UpdateTaskController(12-43)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/user/updateUser.spec.ts (2)
src/controllers/users/UpdateUserController.ts (1)
UpdateUserController(10-42)src/database/prismaClient.ts (1)
prismaClient(5-5)
src/tests/task/deleteTask.spec.ts (2)
src/controllers/tasks/DeleteTaskController.ts (1)
DeleteTaskController(4-21)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/tests/user/deleteUser.spec.ts (2)
src/controllers/users/DeleteUserByIdController.ts (1)
DeleteUserByIdController(6-26)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/tasks/UpdateTaskController.ts (3)
dist/routers/router.js (1)
updateTask(47-47)src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/users/CreateUsersController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/typeNotes/CreateTypeNotesController.ts (3)
dist/routers/router.js (1)
createTypeNotes(33-33)src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/tasks/CreateTaskController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
src/controllers/typeNotes/UpdateTypeNotesController.ts (2)
src/database/prismaClient.ts (1)
prismaClient(5-5)dist/database/prismaClient.js (1)
prismaClient(5-5)
🪛 LanguageTool
PULL_REQUEST.md
[typographical] ~21-~21: Símbolo sem par: “[” aparentemente está ausente
Context: ...>
(UNPAIRED_BRACKETS)
[uncategorized] ~41-~41: Esta conjugação deve ser separada por vírgulas.
Context: ... irá precisar de tantos relacionamentos.Porém o prima tbm vai ajudar se houver neccessi...
(VERB_COMMA_CONJUNCTION)
[style] ~41-~41: Evite abreviações de internet. Considere escrever “também” por extenso.
Context: ...de tantos relacionamentos.Porém o prima tbm vai ajudar se houver neccessidade de ex...
(INTERNET_ABBREVIATIONS)
[typographical] ~41-~41: Símbolo sem par: “"” aparentemente está ausente
Context: ...tar prisma migrate dev e prisma generate". Utilizei tbm o orm prisma que se encai...
(UNPAIRED_BRACKETS)
[style] ~42-~42: Evite abreviações de internet. Considere escrever “também” por extenso.
Context: ...igrate dev e prisma generate". Utilizei tbm o orm prisma que se encaixa muito bem c...
(INTERNET_ABBREVIATIONS)
[grammar] ~42-~42: Possível erro de concordância de número.
Context: ...encaixa muito bem com os dois bancos de dados proposto para o desafio . Quanto ao request.para...
(GENERAL_NUMBER_AGREEMENT_ERRORS)
[uncategorized] ~43-~43: Encontrada possível ausência de vírgula.
Context: ...t.params usei os ids buscando direto no body na minha opinião esses dados visíveis n...
(AI_PT_HYDRA_LEO_MISSING_COMMA)
🪛 markdownlint-cli2 (0.17.2)
PULL_REQUEST.md
23-23: No empty links
(MD042, no-empty-links)
82-82: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (9)
babel.config.js (2)
1-6: No decorator usage detected; Babel config is sufficient.Verified that there are no decorators or reflect-metadata imports in the codebase, so no additional Babel plugins are required.
1-6: No TS path alias imports detected—no Babel resolver plugin needed.The search found only the alias definition in tsconfig.json and no actual
@/imports in the codebase, so you can skip adding themodule-resolverplugin.PULL_REQUEST.md (1)
14-16: Verifique URLs dos badges.Os badges apontam para
backendcorelab(sem hífen). Confirme se corresponde ao nome do repositório público atual.src/routers/router.ts (1)
44-45: The scripts will inspectsrc/routers/router.tsaround the affected routes; I’ll analyze the results and then confirm or update the review comment.src/controllers/users/UpdateUserController.ts (1)
37-40: Handle “user not found” with 404 and adopt structured logging
- Catch PrismaClientKnownRequestError and map
error.code === 'P2025'toresponse.status(404).json({ msg: 'User not found' }). P2025 indicates an operation failed because the target record was not found (prisma.io, prismagraphql.com)- Replace noisy
console.log(error)with structured logging, e.g.
req.log.error({ err: error }, 'update user failed')(ensure your request-logging middleware exposesreq.log.error)src/controllers/typeNotes/UpdateTypeNotesController.ts (1)
18-21: No change needed fortypeNotesrelation
ThetypeNotesfield on Task is an optional to-one relation, andconnectis the correct nested write operation to link an existing TypeNote. Thesetoperation only applies to list relations (e.g.posts: { set: [] }) or composite types—not singular relations.Likely an incorrect or invalid review comment.
src/tests/task/deleteTask.spec.ts (2)
32-54: Test logic is correct for successful deletion scenario.The test properly mocks the Prisma client's delete operation and verifies the expected response structure.
56-74: Test logic is correct for error handling scenario.The test appropriately verifies that database errors are handled gracefully with a 500 status response.
src/tests/user/createUser.spec.ts (1)
47-61: Test case correctly validates missing fields scenario.The test properly verifies that the controller returns appropriate error messages when all required fields are missing.
| { | ||
| "rules": { | ||
| "prettier/prettier": "error", | ||
| "import/extensions": [ | ||
| "error", | ||
| "ignorePackages", | ||
| { | ||
| "ts": "never" | ||
| } | ||
| ] | ||
| }, | ||
| "settings": { | ||
| "import/resolver": { | ||
| "typescript": {} | ||
| } |
There was a problem hiding this comment.
Missing TypeScript parser configuration — ESLint will fail on .ts
Add @typescript-eslint/parser and parserOptions. Without it, ESLint uses Espree and will choke on TS syntax.
{
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "project": ["./tsconfig.json"],
+ "sourceType": "module",
+ "ecmaVersion": 2021
+ },
"rules": {
"prettier/prettier": "error",
"import/extensions": [
"error",
"ignorePackages",
{
"ts": "never"
}
]
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| { | |
| "rules": { | |
| "prettier/prettier": "error", | |
| "import/extensions": [ | |
| "error", | |
| "ignorePackages", | |
| { | |
| "ts": "never" | |
| } | |
| ] | |
| }, | |
| "settings": { | |
| "import/resolver": { | |
| "typescript": {} | |
| } | |
| { | |
| "parser": "@typescript-eslint/parser", | |
| "parserOptions": { | |
| "project": ["./tsconfig.json"], | |
| "sourceType": "module", | |
| "ecmaVersion": 2021 | |
| }, | |
| "rules": { | |
| "prettier/prettier": "error", | |
| "import/extensions": [ | |
| "error", | |
| "ignorePackages", | |
| { | |
| "ts": "never" | |
| } | |
| ] | |
| }, | |
| "settings": { | |
| "import/resolver": { | |
| "typescript": {} | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
In .eslintrc.json around lines 1-15, ESLint lacks a TypeScript parser
configuration so it will fail on .ts files; update the config to set "parser" to
"@typescript-eslint/parser" and add "parserOptions" (at minimum sourceType:
"module" and a project pointing to your tsconfig.json, with tsconfigRootDir set
to the repo root if needed) so ESLint uses the TypeScript parser; ensure
@typescript-eslint/parser is installed as a dev dependency and restart linting
to verify .ts files are parsed correctly.
| "extends": [ | ||
| "airbnb-base", | ||
| "plugin:@typescript-eslint/recommended", | ||
| "prettier/@typescript-eslint", | ||
| "plugin:prettier/recommended" | ||
| ] |
There was a problem hiding this comment.
Remove deprecated "prettier/@typescript-eslint" extend
This preset is deprecated and can break ESLint. Use "prettier" (already included via plugin:prettier/recommended) and add "plugin:import/typescript".
"extends": [
"airbnb-base",
"plugin:@typescript-eslint/recommended",
- "prettier/@typescript-eslint",
- "plugin:prettier/recommended"
+ "plugin:import/typescript",
+ "plugin:prettier/recommended"
]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "extends": [ | |
| "airbnb-base", | |
| "plugin:@typescript-eslint/recommended", | |
| "prettier/@typescript-eslint", | |
| "plugin:prettier/recommended" | |
| ] | |
| { | |
| "extends": [ | |
| "airbnb-base", | |
| "plugin:@typescript-eslint/recommended", | |
| "plugin:import/typescript", | |
| "plugin:prettier/recommended" | |
| ] | |
| } |
🤖 Prompt for AI Agents
In .eslintrc.json around lines 17 to 22, remove the deprecated
"prettier/@typescript-eslint" entry from the "extends" array and replace it by
adding "plugin:import/typescript" to the array (keep
"plugin:prettier/recommended" and/or "prettier" as-is), ensuring the extends
order still applies ESLint, TypeScript, import rules and Prettier integration
correctly.
| "@babel/core": "^7.20.12", | ||
| "@babel/preset-env": "^7.20.2", | ||
| "@babel/preset-typescript": "^7.18.6", | ||
| "@types/express": "^4.17.15", | ||
| "@types/jest": "^29.2.5", | ||
| "@types/mocha": "^10.0.1", | ||
| "@types/node": "^20.19.11", | ||
| "@typescript-eslint/eslint-plugin": "^6.19.0", | ||
| "@typescript-eslint/parser": "^6.19.0", | ||
| "babel-jest": "^29.3.1", | ||
| "eslint": "^8.56.0", | ||
| "eslint-config-prettier": "^9.1.0", | ||
| "jest-mock-extended": "^4.0.0", | ||
| "prettier": "^3.2.4", | ||
| "prisma": "^5.6.0", | ||
| "ts-jest": "^29.0.3", | ||
| "ts-node": "^10.9.1", | ||
| "typescript": "^5.3.2" |
There was a problem hiding this comment.
Tests will fail: Jest is not installed.
The script uses jest, but there’s no jest dependency.
"devDependencies": {
+ "jest": "^29.7.0",
"@babel/core": "^7.20.12",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "@babel/core": "^7.20.12", | |
| "@babel/preset-env": "^7.20.2", | |
| "@babel/preset-typescript": "^7.18.6", | |
| "@types/express": "^4.17.15", | |
| "@types/jest": "^29.2.5", | |
| "@types/mocha": "^10.0.1", | |
| "@types/node": "^20.19.11", | |
| "@typescript-eslint/eslint-plugin": "^6.19.0", | |
| "@typescript-eslint/parser": "^6.19.0", | |
| "babel-jest": "^29.3.1", | |
| "eslint": "^8.56.0", | |
| "eslint-config-prettier": "^9.1.0", | |
| "jest-mock-extended": "^4.0.0", | |
| "prettier": "^3.2.4", | |
| "prisma": "^5.6.0", | |
| "ts-jest": "^29.0.3", | |
| "ts-node": "^10.9.1", | |
| "typescript": "^5.3.2" | |
| "devDependencies": { | |
| "jest": "^29.7.0", | |
| "@babel/core": "^7.20.12", | |
| "@babel/preset-env": "^7.20.2", | |
| "@babel/preset-typescript": "^7.18.6", | |
| "@types/express": "^4.17.15", | |
| "@types/jest": "^29.2.5", | |
| "@types/mocha": "^10.0.1", | |
| "@types/node": "^20.19.11", | |
| "@typescript-eslint/eslint-plugin": "^6.19.0", | |
| "@typescript-eslint/parser": "^6.19.0", | |
| "babel-jest": "^29.3.1", | |
| "eslint": "^8.56.0", | |
| "eslint-config-prettier": "^9.1.0", | |
| "jest-mock-extended": "^4.0.0", | |
| "prettier": "^3.2.4", | |
| "prisma": "^5.6.0", | |
| "ts-jest": "^29.0.3", | |
| "ts-node": "^10.9.1", | |
| "typescript": "^5.3.2" | |
| }, |
🤖 Prompt for AI Agents
In package.json around lines 34-51, the project references the jest CLI in
scripts but does not include "jest" in dependencies/devDependencies; add "jest"
to devDependencies (use a Jest 29.x version compatible with existing
babel-jest/ts-jest, e.g. "^29.x") and then run npm/yarn install so tests can
run.
| Para a resolução do desafio, como solicitado usei o `Node.js` ,banco de dados `Mongodb` ,escolhi ele por ser uma aplicação pequena que não irá precisar de tantos relacionamentos.Porém o prima tbm vai ajudar se houver neccessidade de expandir a aplicação ja que com ele e so mudar a string de conexão e executar prisma migrate dev e prisma generate". | ||
| Utilizei tbm o orm prisma que se encaixa muito bem com os dois bancos de dados proposto para o desafio . | ||
| Quanto ao request.params usei os ids buscando direto no body na minha opinião esses dados visíveis no link deixa brechas para curiosos tentarem fazer algo no front tentarem algo... | ||
|
|
There was a problem hiding this comment.
Revise “Tomada de decisões” for clarity and typos.
Corrects “tbm/neccessidade/prima/ja” and run-on sentences.
-Para a resolução do desafio, como solicitado usei o `Node.js` ,banco de dados `Mongodb` ,escolhi ele por ser uma aplicação pequena que não irá precisar de tantos relacionamentos.Porém o prima tbm vai ajudar se houver neccessidade de expandir a aplicação ja que com ele e so mudar a string de conexão e executar prisma migrate dev e prisma generate".
-Utilizei tbm o orm prisma que se encaixa muito bem com os dois bancos de dados proposto para o desafio .
-Quanto ao request.params usei os ids buscando direto no body na minha opinião esses dados visíveis no link deixa brechas para curiosos tentarem fazer algo no front tentarem algo...
+Para este desafio utilizei `Node.js` e banco de dados `MongoDB`, adequado para uma aplicação pequena com poucos relacionamentos. O Prisma facilita uma futura migração/expansão: basta ajustar a string de conexão e executar `prisma migrate dev` e `prisma generate`.
+Também utilizei o ORM Prisma, que funciona bem com os bancos propostos.
+Quanto a `request.params`, optei por ler os IDs no `body`. Observação: esconder IDs na URL não é um mecanismo de segurança; validações e autorização no backend continuam necessárias.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Para a resolução do desafio, como solicitado usei o `Node.js` ,banco de dados `Mongodb` ,escolhi ele por ser uma aplicação pequena que não irá precisar de tantos relacionamentos.Porém o prima tbm vai ajudar se houver neccessidade de expandir a aplicação ja que com ele e so mudar a string de conexão e executar prisma migrate dev e prisma generate". | |
| Utilizei tbm o orm prisma que se encaixa muito bem com os dois bancos de dados proposto para o desafio . | |
| Quanto ao request.params usei os ids buscando direto no body na minha opinião esses dados visíveis no link deixa brechas para curiosos tentarem fazer algo no front tentarem algo... | |
| Para este desafio utilizei `Node.js` e banco de dados `MongoDB`, adequado para uma aplicação pequena com poucos relacionamentos. O Prisma facilita uma futura migração/expansão: basta ajustar a string de conexão e executar `prisma migrate dev` e `prisma generate`. | |
| Também utilizei o ORM Prisma, que funciona bem com os bancos propostos. | |
| Quanto a `request.params`, optei por ler os IDs no `body`. Observação: esconder IDs na URL não é um mecanismo de segurança; validações e autorização no backend continuam necessárias. |
🧰 Tools
🪛 LanguageTool
[uncategorized] ~41-~41: Esta conjugação deve ser separada por vírgulas.
Context: ... irá precisar de tantos relacionamentos.Porém o prima tbm vai ajudar se houver neccessi...
(VERB_COMMA_CONJUNCTION)
[style] ~41-~41: Evite abreviações de internet. Considere escrever “também” por extenso.
Context: ...de tantos relacionamentos.Porém o prima tbm vai ajudar se houver neccessidade de ex...
(INTERNET_ABBREVIATIONS)
[typographical] ~41-~41: Símbolo sem par: “"” aparentemente está ausente
Context: ...tar prisma migrate dev e prisma generate". Utilizei tbm o orm prisma que se encai...
(UNPAIRED_BRACKETS)
[style] ~42-~42: Evite abreviações de internet. Considere escrever “também” por extenso.
Context: ...igrate dev e prisma generate". Utilizei tbm o orm prisma que se encaixa muito bem c...
(INTERNET_ABBREVIATIONS)
[grammar] ~42-~42: Possível erro de concordância de número.
Context: ...encaixa muito bem com os dois bancos de dados proposto para o desafio . Quanto ao request.para...
(GENERAL_NUMBER_AGREEMENT_ERRORS)
[uncategorized] ~43-~43: Encontrada possível ausência de vírgula.
Context: ...t.params usei os ids buscando direto no body na minha opinião esses dados visíveis n...
(AI_PT_HYDRA_LEO_MISSING_COMMA)
🤖 Prompt for AI Agents
In PULL_REQUEST.md around lines 41–44, the "Tomada de decisões" paragraph has
typos and run-on sentences; replace informal abbreviations and misspellings
(e.g., "tbm" → "também", "neccessidade" → "necessidade", "prima" → "Prisma",
"ja" → "já"), break long sentences into shorter, clearer sentences, fix
punctuation and spacing around commas and periods, and rewrite the
request.params sentence to clearly explain that IDs were read from the request
body for privacy reasons (while noting potential trade-offs) in idiomatic
Portuguese.
| import { Request, Response } from 'express'; | ||
| import { prismaClient } from '../../database/prismaClient'; | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Validate id and translate Prisma P2025 to 404
Add a 400 guard for missing id and map “record not found” to 404 instead of 500. Import Prisma error type.
-import { Request, Response } from 'express';
+import { Request, Response } from 'express';
+import { Prisma } from '@prisma/client';
@@
- const id:string = request.params.id;
+ const id: string = request.params.id;
+ if (!id) {
+ return response.status(400).json({ msg: 'Task id is required' });
+ }
@@
- } catch (error) {
- console.log(error);
- return response.status(500).json({ msg: 'Internal server error!' });
+ } catch (error) {
+ console.log(error);
+ if (
+ error instanceof Prisma.PrismaClientKnownRequestError &&
+ error.code === 'P2025'
+ ) {
+ return response.status(404).json({ msg: 'Task not found' });
+ }
+ return response.status(500).json({ msg: 'Internal server error!' });
}Also applies to: 6-6, 16-19
🤖 Prompt for AI Agents
In src/controllers/tasks/DeleteTaskController.ts around lines 1-3 (and adjust
lines 6, and 16-19), add an import for Prisma error types (import { Prisma }
from '@prisma/client'), validate req.params.id and return
res.status(400).json(...) when id is missing, and wrap prisma delete in a
try/catch that checks if error is an instance of
Prisma.PrismaClientKnownRequestError and error.code === 'P2025' then return
res.status(404).json(...) otherwise rethrow or return a 500; ensure the response
messages are clear and map the Prisma "record not found" P2025 to 404 instead of
500.
| it('should create a new task with null values for titulo and task fields and expect a 500 response with an error message', async () => { | ||
| const mockRequest = { | ||
| body: { | ||
| titulo: undefined, | ||
| task: undefined, | ||
| createdAt: '2022-01-01T00:00:00.000Z', | ||
| userId: 'user123' | ||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
|
|
||
| await controller.handle(mockRequest, mockResponse); | ||
|
|
||
| expect(mockResponse.status).toHaveBeenCalledWith(401); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| msg: 'Fields cannot be null or empty!' | ||
| }); | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Align test name with inputs and ensure DB not called
Inputs use undefined (not null). Also assert create() isn’t called.
- it('should create a new task with null values for titulo and task fields and expect a 500 response with an error message', async () => {
+ it('should return 401 when titulo and task are undefined', async () => {
...
- const mockResponse = {
+ const mockResponse = {
status: jest.fn().mockReturnThis(),
json: jest.fn()
} as unknown as Response;
- await controller.handle(mockRequest, mockResponse);
+ const createSpy = jest.spyOn(prismaClient.task, 'create');
+ await controller.handle(mockRequest, mockResponse);
...
expect(mockResponse.json).toHaveBeenCalledWith({
msg: 'Fields cannot be null or empty!'
});
+ expect(createSpy).not.toHaveBeenCalled();
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| it('should create a new task with null values for titulo and task fields and expect a 500 response with an error message', async () => { | |
| const mockRequest = { | |
| body: { | |
| titulo: undefined, | |
| task: undefined, | |
| createdAt: '2022-01-01T00:00:00.000Z', | |
| userId: 'user123' | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(401); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| msg: 'Fields cannot be null or empty!' | |
| }); | |
| }); | |
| it('should return 401 when titulo and task are undefined', async () => { | |
| const mockRequest = { | |
| body: { | |
| titulo: undefined, | |
| task: undefined, | |
| createdAt: '2022-01-01T00:00:00.000Z', | |
| userId: 'user123' | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| const createSpy = jest.spyOn(prismaClient.task, 'create'); | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(401); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| msg: 'Fields cannot be null or empty!' | |
| }); | |
| expect(createSpy).not.toHaveBeenCalled(); | |
| }); |
🤖 Prompt for AI Agents
In src/tests/task/createTask.spec.ts around lines 55 to 75, the test title says
"null values" but the request uses undefined and it doesn't assert that the DB
create() was not invoked; update the test to either use null for titulo and task
to match the title or rename the test to say "undefined values", and add an
assertion that the mocked DB create method (or service create) was not called
(e.g., expect(mockedCreate).not.toHaveBeenCalled()). Ensure the test uses the
correct mocked create reference and that the mockResponse status/json
expectations remain unchanged.
| import { Request, Response } from 'express'; | ||
| import { prismaClient } from '../../database/prismaClient'; | ||
| import { UpdateTaskController } from '../../controllers/tasks/UpdateTaskController'; | ||
|
|
||
| const controller = new UpdateTaskController(); | ||
|
|
||
| describe('UpdateTask', () => { | ||
| it('should update a task with valid input data and return a 200 status code with a success message and the updated task', async () => { | ||
| const mockRequest = { | ||
| body: { | ||
| id: 'validTaskId', | ||
| userId:'validUserId', | ||
| titulo: 'New Title', | ||
| task: 'New Task' | ||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
| prismaClient.task.update = jest.fn().mockResolvedValue({}); | ||
| await controller.handle(mockRequest, mockResponse); | ||
|
|
||
| expect(mockResponse.status).toHaveBeenCalledWith(200); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| msg: 'Task as updated!', | ||
| updateTask: expect.any(Object) | ||
| }); | ||
| }); | ||
| it('should handle and return a 400 status code with an error message for invalid input data', async () => { | ||
| const mockRequest = { | ||
| body: { | ||
| id:undefined, | ||
| userId:undefined, | ||
| titulo: 123, | ||
| task: '' | ||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
| prismaClient.task.update=jest.fn().mockRejectedValue(new Error('Invalid input')); | ||
| await controller.handle(mockRequest, mockResponse); | ||
|
|
||
| expect(mockResponse.status).toHaveBeenCalledWith(500); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| msg: 'Internal server error!' | ||
| }); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Controller under test has correctness issues; consider fixing and then asserting 400 for bad input.
From src/controllers/tasks/UpdateTaskController.ts:
- Uses
if (id !== null || userId !== null)(should be&&with robust checks). update’swheremust be unique; combiningidanduserIdviaANDis invalid unless a composite unique exists. UseupdateManywith both fields orupdate({ where: { id } })and verify ownership separately.updatedAtformatting usesSS(milliseconds); for seconds usess, or store a Date.- Return 400 for validation errors; fix “Erro on server!” typo.
Suggested handle() rewrite:
async handle(request: Request, response: Response) {
const { id, titulo, task, userId } = request.body as {
id?: unknown; titulo?: unknown; task?: unknown; userId?: unknown;
};
if (
typeof id !== 'string' || !id.trim() ||
typeof userId !== 'string' || !userId.trim() ||
typeof titulo !== 'string' || typeof task !== 'string'
) {
return response.status(400).json({ msg: 'Invalid input.' });
}
try {
// Enforce ownership and update atomically
const result = await prismaClient.task.updateMany({
where: { id, userId },
data: { titulo, task, updatedAt: new Date() }
});
if (result.count === 0) {
return response.status(404).json({ msg: 'Task not found for user.' });
}
return response.status(200).json({ msg: 'Task was updated!' });
} catch (error: any) {
return response.status(500).json({ msg: 'Internal server error.' });
}
}If you adopt this, update this test to expect 400 for invalid input instead of 500.
| prismaClient.user.delete = jest.fn().mockResolvedValueOnce({}); | ||
| const mockRequest = { |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Spy instead of reassigning prisma method; restore between tests
Avoid direct reassignment.
- prismaClient.user.delete = jest.fn().mockResolvedValueOnce({});
+ const deleteSpy = jest
+ .spyOn(prismaClient.user, 'delete')
+ .mockResolvedValueOnce({} as any);Add after Line 5:
+afterEach(() => {
+ jest.restoreAllMocks();
+});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| prismaClient.user.delete = jest.fn().mockResolvedValueOnce({}); | |
| const mockRequest = { | |
| // src/tests/user/deleteUser.spec.ts | |
| import { prismaClient } from '../../src/client'; | |
| import deleteUserHandler from '../../src/user/deleteUser'; | |
| afterEach(() => { | |
| jest.restoreAllMocks(); | |
| }); | |
| describe('deleteUser', () => { | |
| it('should delete a user', async () => { | |
| const deleteSpy = jest | |
| .spyOn(prismaClient.user, 'delete') | |
| .mockResolvedValueOnce({} as any); | |
| const mockRequest = { | |
| // … your mock request data … | |
| }; | |
| // … rest of your test … | |
| }); | |
| }); |
🤖 Prompt for AI Agents
In src/tests/user/deleteUser.spec.ts around lines 8-9, the test currently
reassigns prismaClient.user.delete directly which mutates the module; instead,
use jest.spyOn(prismaClient.user, 'delete').mockResolvedValueOnce(...) and
restore the spy after the test (or in afterEach) by calling mockRestore or
jest.restoreAllMocks; add the spy creation after line 5 and ensure cleanup is
performed between tests to avoid cross-test pollution.
| it('should return a 200 status code and the user object when a valid id is provided', async () => { | ||
| const mockRequest = { | ||
| body: { | ||
| id: 'validId' | ||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
|
|
||
| prismaClient.user.findFirst = jest | ||
| .fn() | ||
| .mockResolvedValue({ id: 'validId', name: 'John Doe' }); | ||
|
|
||
| await controller.handle(mockRequest, mockResponse); | ||
|
|
||
| expect(mockResponse.status).toHaveBeenCalledWith(200); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| id: 'validId', | ||
| name: 'John Doe' | ||
| }); | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use spy, align mocked shape to domain, and assert call
Prefer userName over name, and verify the Prisma call.
- prismaClient.user.findFirst = jest
- .fn()
- .mockResolvedValue({ id: 'validId', name: 'John Doe' });
+ const spy = jest.spyOn(prismaClient.user, 'findFirst')
+ .mockResolvedValue({ id: 'validId', userName: 'John Doe', userImages: [] } as any);
...
- expect(mockResponse.json).toHaveBeenCalledWith({
- id: 'validId',
- name: 'John Doe'
- });
+ expect(mockResponse.json).toHaveBeenCalledWith(
+ expect.objectContaining({ id: 'validId', userName: 'John Doe' })
+ );
+ expect(spy).toHaveBeenCalledWith({ where: { id: 'validId' }, include: { userImages: true } });Add once near the top:
+afterEach(() => {
+ jest.restoreAllMocks();
+});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| it('should return a 200 status code and the user object when a valid id is provided', async () => { | |
| const mockRequest = { | |
| body: { | |
| id: 'validId' | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| prismaClient.user.findFirst = jest | |
| .fn() | |
| .mockResolvedValue({ id: 'validId', name: 'John Doe' }); | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(200); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| id: 'validId', | |
| name: 'John Doe' | |
| }); | |
| }); | |
| afterEach(() => { | |
| jest.restoreAllMocks(); | |
| }); | |
| it('should return a 200 status code and the user object when a valid id is provided', async () => { | |
| const mockRequest = { | |
| body: { | |
| id: 'validId' | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| const spy = jest.spyOn(prismaClient.user, 'findFirst') | |
| .mockResolvedValue({ id: 'validId', userName: 'John Doe', userImages: [] } as any); | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(200); | |
| expect(mockResponse.json).toHaveBeenCalledWith( | |
| expect.objectContaining({ id: 'validId', userName: 'John Doe' }) | |
| ); | |
| expect(spy).toHaveBeenCalledWith({ where: { id: 'validId' }, include: { userImages: true } }); | |
| }); |
🤖 Prompt for AI Agents
In src/tests/user/findUserById.spec.ts around lines 7 to 29, the test should use
a Jest spy for prismaClient.user.findFirst, return a domain-shaped user object
(userName instead of name), and assert the Prisma call was made with the
expected query: add a spy near the top (e.g., const findFirstSpy =
jest.spyOn(prismaClient.user, 'findFirst')), change the mockResolvedValue to
return { id: 'validId', userName: 'John Doe' }, update the expected json payload
to use userName, and add an assertion that findFirstSpy was called with the
correct where clause for id 'validId'.
| prismaClient.user.update = jest | ||
| .fn() | ||
| .mockResolvedValue({ | ||
| id: 'validId', | ||
| userName: 'John Doe', | ||
| email: 'johndoe@example.com', | ||
| password: 'password' | ||
| }); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Do not assert on plaintext password in responses; fix controller to omit it.
Returning/storing raw passwords is a critical security flaw. Controller should hash password and never return it; tests must not expect it.
- prismaClient.user.update = jest
- .fn()
- .mockResolvedValue({
- id: 'validId',
- userName: 'John Doe',
- email: 'johndoe@example.com',
- password: 'password'
- });
+ const updateMock = jest
+ .spyOn(prismaClient.user, 'update')
+ .mockResolvedValue({
+ id: 'validId',
+ userName: 'John Doe',
+ email: 'johndoe@example.com'
+ });
...
- expect(mockResponse.json).toHaveBeenCalledWith({
- id: 'validId',
- userName: 'John Doe',
- email: 'johndoe@example.com',
- password: 'password'
- });
+ expect(mockResponse.json).toHaveBeenCalledWith({
+ id: 'validId',
+ userName: 'John Doe',
+ email: 'johndoe@example.com'
+ });
+ updateMock.mockRestore();After fixing the controller to omit password, ensure no tests assert on password:
Also applies to: 38-44
🏁 Script executed:
#!/bin/bash
rg -nP "password['\"]?\s*[:)]|['\"]password['\"]" --type=ts -C2Length of output: 4905
Omit plaintext passwords from responses, mocks, and tests; implement hashing instead.
The controllers (src/controllers/users/UpdateUserController.ts, CreateUsersController.ts, LoginController.ts) still accept and return a password field, and the spec files (src/tests/user/updateUser.spec.ts, src/tests/user/createUser.spec.ts, src/tests/login/login.spec.ts) continue to mock/assert on plaintext passwords. Remove password from all API response payloads and mockResolvedValue objects, refactor to hash/store passwords securely, and update tests to stop expecting a password property.
| model User { | ||
| id String @id @default(auto()) @map("_id") @db.ObjectId | ||
| userName String | ||
| email String | ||
| password String | ||
| createdAt String | ||
| userImages UserImage[] | ||
| tasks Task[] | ||
|
|
||
| @@map("users") | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Make email unique and use proper timestamp type for User.createdAt.
Prevents duplicate accounts and enables time-based queries.
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
userName String
- email String
+ email String @unique
password String
- createdAt String
+ createdAt DateTime @default(now())
userImages UserImage[]
tasks Task[]
@@map("users")
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| model User { | |
| id String @id @default(auto()) @map("_id") @db.ObjectId | |
| userName String | |
| email String | |
| password String | |
| createdAt String | |
| userImages UserImage[] | |
| tasks Task[] | |
| @@map("users") | |
| } | |
| model User { | |
| id String @id @default(auto()) @map("_id") @db.ObjectId | |
| userName String | |
| email String @unique | |
| password String | |
| createdAt DateTime @default(now()) | |
| userImages UserImage[] | |
| tasks Task[] | |
| @@map("users") | |
| } |
🤖 Prompt for AI Agents
In prisma/schema.prisma around lines 13 to 23, make the email field unique and
change createdAt from String to a proper DateTime with a default timestamp:
replace `email String` with `email String @unique` and replace `createdAt
String` with `createdAt DateTime @default(now())`; run prisma migrate after
updating the schema to apply the changes.
| model Task { | ||
| id String @id @default(auto()) @map("_id") @db.ObjectId | ||
| titulo String | ||
| task String | ||
| createdAt String? | ||
| updatedAt String? | ||
| completedAt String? | ||
| userId String @db.ObjectId | ||
| users User @relation(fields: [userId], references: [id]) | ||
| typeId String? @db.ObjectId | ||
| typeNotes TypeNote? @relation(fields: [typeId], references: [id]) | ||
|
|
||
| @@map("tasks") | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use DateTime for task timestamps; add indexes for relations.
Better querying/sorting and faster lookups.
model Task {
id String @id @default(auto()) @map("_id") @db.ObjectId
titulo String
task String
- createdAt String?
- updatedAt String?
- completedAt String?
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ completedAt DateTime?
userId String @db.ObjectId
users User @relation(fields: [userId], references: [id])
typeId String? @db.ObjectId
typeNotes TypeNote? @relation(fields: [typeId], references: [id])
@@map("tasks")
+ @@index([userId])
+ @@index([typeId])
}Note: Adopting this requires updating controllers to stop passing formatted strings (use Date or rely on defaults).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| model Task { | |
| id String @id @default(auto()) @map("_id") @db.ObjectId | |
| titulo String | |
| task String | |
| createdAt String? | |
| updatedAt String? | |
| completedAt String? | |
| userId String @db.ObjectId | |
| users User @relation(fields: [userId], references: [id]) | |
| typeId String? @db.ObjectId | |
| typeNotes TypeNote? @relation(fields: [typeId], references: [id]) | |
| @@map("tasks") | |
| } | |
| model Task { | |
| id String @id @default(auto()) @map("_id") @db.ObjectId | |
| titulo String | |
| task String | |
| createdAt DateTime @default(now()) | |
| updatedAt DateTime @updatedAt | |
| completedAt DateTime? | |
| userId String @db.ObjectId | |
| users User @relation(fields: [userId], references: [id]) | |
| typeId String? @db.ObjectId | |
| typeNotes TypeNote? @relation(fields: [typeId], references: [id]) | |
| @@map("tasks") | |
| @@index([userId]) | |
| @@index([typeId]) | |
| } |
🤖 Prompt for AI Agents
In prisma/schema.prisma around lines 34 to 47, change the task timestamp fields
from String to DateTime and add relation indexes: convert createdAt and
updatedAt to DateTime with createdAt @default(now()) and updatedAt @updatedAt,
make completedAt a nullable DateTime, and add @@index([userId]) and
@@index([typeId]) to the Task model so relation lookups are faster; update
controllers to stop sending formatted strings (pass Date objects or rely on
defaults).
| if (email === null || email === undefined) { | ||
| return response.status(400).json({ msg: 'Email is not found!' }); | ||
| } else if (password === null || password === undefined) { | ||
| return response.status(401).json({ msg: 'Password not found!' }); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add validation for empty string values.
The current validation only checks for null or undefined but doesn't validate empty strings, which should also be considered invalid input.
if (email === null || email === undefined) {
+ if (email === null || email === undefined || email === '') {
return response.status(400).json({ msg: 'Email is not found!' });
- } else if (password === null || password === undefined) {
+ } else if (password === null || password === undefined || password === '') {
return response.status(401).json({ msg: 'Password not found!' });
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/controllers/login/LoginController.ts around lines 12 to 16, the current
checks only reject null/undefined for email and password but allow empty
strings; update the validation to treat empty or whitespace-only strings as
invalid as well (e.g., check for falsy values and/or use trim() to detect empty
after trimming) and return the same HTTP error responses with the existing
messages when email or password is missing or blank.
| const login = await prismaClient.user.findFirst({ | ||
| where: { | ||
| email: email, | ||
| AND: { | ||
| password: password | ||
| } | ||
| }, | ||
| include: { | ||
| userImages: { | ||
| select: { | ||
| image: true | ||
| } | ||
| } | ||
| } | ||
| }); |
There was a problem hiding this comment.
Critical security vulnerability: Plain text password storage and comparison.
The code is comparing passwords in plain text, which is a severe security vulnerability. Passwords should be hashed using a secure algorithm like bcrypt before storage and comparison.
This requires implementing proper password hashing throughout the application. Consider using bcrypt for password hashing:
import bcrypt from 'bcrypt';
// For registration (not shown in this file):
const hashedPassword = await bcrypt.hash(password, 10);
// For login comparison:
const isPasswordValid = await bcrypt.compare(password, user.password);This change will require updating the user registration logic and database schema as well.
🤖 Prompt for AI Agents
In src/controllers/login/LoginController.ts around lines 18 to 32, the code is
querying and comparing plaintext passwords directly from the database; replace
this with hashed-password verification: fetch the user record by email only,
then use a secure hashing library (e.g., bcrypt) to compare the supplied
password to the stored hashed password with bcrypt.compare; ensure registration
code is changed to store bcrypt-hashed passwords (bcrypt.hash with a safe salt
rounds value) and migrate/update the database schema/seed data so passwords are
hashed, and remove any code paths that store or compare raw plaintext passwords.
| .json({ msg: 'Email or Password incorrect!' }); | ||
| } else { | ||
| return response.status(200).json({ | ||
| msg: 'Login sucessfully!', |
There was a problem hiding this comment.
Fix typo in success message.
There's a spelling error in the success message.
- msg: 'Login sucessfully!',
+ msg: 'Login successfully!',📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| msg: 'Login sucessfully!', | |
| msg: 'Login successfully!', |
🤖 Prompt for AI Agents
In src/controllers/login/LoginController.ts around line 39, the success response
message contains a typo "Login sucessfully!"; update it to "Login successfully!"
(or "Logged in successfully!" if preferred for clarity) to correct the spelling
and keep casing/punctuation consistent with other messages.
| it('should handle requests with invalid JSON format in the request body', async () => { | ||
| const mockRequest = { | ||
| body: { | ||
| userId: 'test-on-jest' | ||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
|
|
||
| prismaClient.task.findMany = jest.fn().mockRejectedValue({}); | ||
|
|
||
| await controller.handle(mockRequest, mockResponse); | ||
|
|
||
| expect(mockResponse.status).toHaveBeenCalledWith(500); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| msg: 'Internal server error!' | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Clarify test case purpose and fix request structure.
The test description mentions "invalid JSON format" but the test body appears to have valid JSON. The issue is again using body.userId instead of params.id.
const mockRequest = {
- body: {
- userId: 'test-on-jest'
- }
+ params: {
+ id: 'test-on-jest'
+ }
} as Request;Consider renaming this test to better reflect what scenario it's actually testing.
🤖 Prompt for AI Agents
In src/tests/task/findAllTaskByUserId.spec.ts around lines 49 to 68, the test is
mislabeled as handling "invalid JSON format" and incorrectly uses body.userId
instead of params.id; rename the test to reflect that it's testing an internal
server error when the DB call fails, and change the mockRequest to provide
params: { id: 'test-on-jest' } (not body), leave prismaClient.task.findMany
mocked to reject, and keep assertions expecting a 500 status and the internal
server error JSON.
| it('should search for a task with a valid but non-string ID and return an error message with status code 404', async () => { | ||
| const mockRequest = { | ||
| body: { | ||
| id: 123 | ||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
|
|
||
| await controller.handle(mockRequest, mockResponse); | ||
|
|
||
| expect(mockResponse.status).toHaveBeenCalledWith(404); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| msg: 'Task not found!' | ||
| }); | ||
| }); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify non-string ID handling behavior.
This test expects a 404 response for a numeric ID, but it's unclear if the controller actually validates the ID type before querying the database. The controller might pass the numeric value to Prisma, which could behave differently.
Let me check how the controller handles different ID types:
🏁 Script executed:
#!/bin/bash
# Check the FindTaskByIdController implementation to verify ID type validation
ast-grep --pattern 'class FindTaskByIdController {
$$$
handle($_, $_) {
$$$
}
$$$
}'Length of output: 3708
🏁 Script executed:
#!/bin/bash
# Locate Prisma schema
find . -type f -name schema.prisma
# Display Task model definition (10 lines after the model declaration)
grep -R "model Task" -n prisma/schema.prisma -A10Length of output: 549
Add ID type validation in FindTaskByIdController. Currently numeric IDs are passed straight into Prisma, which throws and yields a 500 error instead of the 404 your test expects. Introduce a guard before the query—for example:
if (typeof id !== 'string') {
return response.status(404).json({ msg: 'Task not found!' });
}🤖 Prompt for AI Agents
In src/tests/task/findTaskById.spec.ts around lines 75 to 92, the test expects a
404 for non-string IDs but the controller currently passes numeric IDs into
Prisma causing a 500; add an early guard in FindTaskByIdController that checks
the incoming id (e.g., const { id } = request.body || request.params) and if
typeof id !== 'string' (or id is null/undefined) immediately return
response.status(404).json({ msg: 'Task not found!' }); so the controller never
calls Prisma with a non-string id and the test will pass.
| it('should search for a task with a valid but non-string ID and return an error message with status code 400', async () => { | ||
| const mockRequest = { | ||
| body: { | ||
| id: '' | ||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
| prismaClient.task.findFirst = jest | ||
| .fn() | ||
| .mockRejectedValue(new Error('Unexpected error')); | ||
| await controller.handle(mockRequest, mockResponse); | ||
|
|
||
| expect(mockResponse.status).toHaveBeenCalledWith(500); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| msg: 'Internal server error!' | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Fix inconsistent test description and expectations.
The test description mentions returning status code 400, but the assertion expects 500. Also, this test case seems redundant as it's testing the same scenario as the previous test with a non-string ID.
- it('should search for a task with a valid but non-string ID and return an error message with status code 400', async () => {
+ it('should handle empty ID and return error message with status code 500', async () => {The empty string test is valid as it triggers a database error, but consider if this scenario is meaningfully different from the previous non-string ID test.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| it('should search for a task with a valid but non-string ID and return an error message with status code 400', async () => { | |
| const mockRequest = { | |
| body: { | |
| id: '' | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| prismaClient.task.findFirst = jest | |
| .fn() | |
| .mockRejectedValue(new Error('Unexpected error')); | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(500); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| msg: 'Internal server error!' | |
| }); | |
| }); | |
| it('should handle empty ID and return error message with status code 500', async () => { | |
| const mockRequest = { | |
| body: { | |
| id: '' | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| prismaClient.task.findFirst = jest | |
| .fn() | |
| .mockRejectedValue(new Error('Unexpected error')); | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(500); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| msg: 'Internal server error!' | |
| }); | |
| }); |
🤖 Prompt for AI Agents
In src/tests/task/findTaskById.spec.ts around lines 93 to 112, the test
description says it should return 400 for a valid but non-string ID but the
assertions expect a 500 and the test duplicates the prior non-string ID case;
update the test to make behavior and intent consistent—either (A) change the
description to state it expects a 500 for an empty-string DB error and keep
assertions as-is, or (B) change the assertions to expect 400 if the controller
should validate and reject non-string/empty IDs; alternatively remove this
redundant test if it doesn't add coverage beyond the previous non-string ID
test.
| it('should create a user with all required fields', async () => { | ||
| prismaClient.user.create = jest.fn().mockResolvedValue({}); | ||
| const mockRequest = { | ||
| body: { | ||
| userName: 'JohnDoe', | ||
| email: 'johndoe@example.com', | ||
| password: 'password123' | ||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
| await controller.handle(mockRequest, mockResponse); | ||
| expect(mockResponse.status).toHaveBeenCalledWith(201); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| msg: 'User as created!', | ||
| users: expect.any(Object) | ||
| }); | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add test for file upload functionality.
The controller handles file uploads (request.file?.buffer), but the test doesn't mock the file object. This could lead to undefined behavior in the controller.
const mockRequest = {
+ file: {
+ buffer: Buffer.from('test image data')
+ },
body: {
userName: 'JohnDoe',
email: 'johndoe@example.com',
password: 'password123'
}
} as Request;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| it('should create a user with all required fields', async () => { | |
| prismaClient.user.create = jest.fn().mockResolvedValue({}); | |
| const mockRequest = { | |
| body: { | |
| userName: 'JohnDoe', | |
| email: 'johndoe@example.com', | |
| password: 'password123' | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(201); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| msg: 'User as created!', | |
| users: expect.any(Object) | |
| }); | |
| }); | |
| it('should create a user with all required fields', async () => { | |
| prismaClient.user.create = jest.fn().mockResolvedValue({}); | |
| const mockRequest = { | |
| file: { | |
| buffer: Buffer.from('test image data') | |
| }, | |
| body: { | |
| userName: 'JohnDoe', | |
| email: 'johndoe@example.com', | |
| password: 'password123' | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(201); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| msg: 'User as created!', | |
| users: expect.any(Object) | |
| }); | |
| }); |
🤖 Prompt for AI Agents
In src/tests/user/createUser.spec.ts around lines 8 to 27, the test is missing a
mocked file on request even though the controller reads request.file?.buffer;
add a mockRequest.file object with at least a buffer property (e.g.,
Buffer.from('test')), and include other commonly used fields (originalname,
mimetype) so the controller's file-handling code runs without undefined errors;
keep the existing prismaClient.user.create mock and existing assertions (or
adjust expected users payload if the controller mutates it when a file is
present).
| it('should return a 500 status code and an error message when there is an error creating the user', async () => { | ||
| const mockRequest = { | ||
| body: { | ||
| userName: 'JohnDoe', | ||
| email: 'johndoe@example.com', | ||
|
|
||
| } | ||
| } as Request; | ||
| const mockResponse = { | ||
| status: jest.fn().mockReturnThis(), | ||
| json: jest.fn() | ||
| } as unknown as Response; | ||
|
|
||
| await controller.handle(mockRequest, mockResponse); | ||
| expect(mockResponse.status).toHaveBeenCalledWith(404); | ||
| expect(mockResponse.json).toHaveBeenCalledWith({ | ||
| msg: 'Fields cannot empty or nulls!' | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Fix misleading test description.
The test description mentions returning a "500 status code" but the test expects a 404 status. The description should match the actual test behavior.
- it('should return a 500 status code and an error message when there is an error creating the user', async () => {
+ it('should return a 404 status code and an error message when required fields are missing', async () => {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| it('should return a 500 status code and an error message when there is an error creating the user', async () => { | |
| const mockRequest = { | |
| body: { | |
| userName: 'JohnDoe', | |
| email: 'johndoe@example.com', | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(404); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| msg: 'Fields cannot empty or nulls!' | |
| }); | |
| }); | |
| it('should return a 404 status code and an error message when required fields are missing', async () => { | |
| const mockRequest = { | |
| body: { | |
| userName: 'JohnDoe', | |
| email: 'johndoe@example.com', | |
| } | |
| } as Request; | |
| const mockResponse = { | |
| status: jest.fn().mockReturnThis(), | |
| json: jest.fn() | |
| } as unknown as Response; | |
| await controller.handle(mockRequest, mockResponse); | |
| expect(mockResponse.status).toHaveBeenCalledWith(404); | |
| expect(mockResponse.json).toHaveBeenCalledWith({ | |
| msg: 'Fields cannot empty or nulls!' | |
| }); | |
| }); |
🤖 Prompt for AI Agents
In src/tests/user/createUser.spec.ts around lines 28 to 46, the test description
incorrectly says "should return a 500 status code..." while the assertions
expect a 404; update the it(...) description to accurately state it expects a
404 and the corresponding error message (e.g., "should return a 404 status code
and an error message when there is an error creating the user" or similar) so
the description matches the test's behavior.
Summary by CodeRabbit
New Features
Tests
Refactor
Chores
Documentation