feature/corenote-backend#65
Conversation
Autor: Mauro Luiz dos Santos Junior Este pull request implementa o backend do CoreNotes, uma API RESTful em Node.js (AdonisJS + TypeScript) para gerenciamento de tarefas, com persistência em SQLite, validação robusta, tipagem forte e integração total com o frontend. O projeto segue os requisitos do desafio e está alinhado ao mockup e integrações descritas em [`Leiame.md`](../../Leiame.md). 1. **Ajuste a versão do Node.js:** O backend requer Node.js na versão ^16.15.0, que foi mantido para preservar o formato original do desafio. Recomenda-se o uso de [nvm](https://github.com/nvm-sh/nvm) ou [nvm-windows](https://github.com/coreybutler/nvm-windows) para garantir compatibilidade. ```sh nvm install 16 nvm use 16 ``` 2. Instale as dependências: ```sh npm install ``` 3. Configure as variáveis de ambiente: ```sh cp .env.example .env node ace generate:key ``` 4. Inicie o servidor de desenvolvimento: ```sh npm run dev ``` 5. A API estará disponível em [http://localhost:3333](http://localhost:3333) - [x] CRUD completo de tarefas (criar, listar, editar, deletar) - [x] Marcar/desmarcar favorito - [x] Definir cor para cada tarefa - [x] Validação robusta dos dados - [x] Testes automatizados cobrindo fluxos principais - [x] Tipagem forte e interfaces explícitas - [x] Padronização com Prettier e ESLint - **Tipo de Tarefa:** [`app/Types/Task.ts`](backend/app/Types/Task.ts:1) define as interfaces `ITask`, `ICreateTaskDTO`, `IUpdateTaskDTO` e `IErrorResponse` para garantir clareza e segurança na manipulação dos dados. - **Model de Tarefa:** [`app/Models/Task.ts`](backend/app/Models/Task.ts:1) centraliza toda a lógica de acesso ao banco SQLite, desacoplando o controller e facilitando manutenção. - **Controller:** [`app/Controllers/TasksController.ts`](backend/app/Controllers/TasksController.ts:1) implementa os endpoints REST (`index`, `store`, `show`, `update`, `destroy`), utilizando o model e validadores. - **Validação:** [`app/Validators/TaskValidator.ts`](backend/app/Validators/TaskValidator.ts:1) define schemas para criação e atualização, exigindo título obrigatório e cor válida. Agora, a cor aceita apenas nomes `color1` a `color12` ou `#FFF`, exatamente como no frontend. - **Rotas:** [`start/routes.ts`](backend/start/routes.ts:1) utiliza `Route.resource('/tasks', 'TasksController').apiOnly()` para expor as rotas RESTful. - **Persistência:** Utiliza SQLite via `sqlite3` e `sqlite`, garantindo persistência real dos dados em `database/database.sqlite`. A escolha vem do fato de não usarmos esse backend em produção, mas sim para fins de cumprir o desafio. - **Padronização:** Respostas da API seguem camelCase, alinhadas ao contrato do frontend. - Criação, edição, exclusão e listagem de tarefas - Marcação de tarefas como favoritas (favoritas no topo) - Definição de cor para cada tarefa - Validação de dados e tratamento de erros detalhado - Tipagem forte em todas as operações - Integração total com o frontend - Testes funcionais em [`tests/functional/tasks-api.spec.ts`](backend/tests/functional/tasks-api.spec.ts:1) cobrem: - Criação, listagem, atualização e remoção de tarefas via API - Validação dos fluxos principais e respostas esperadas - Casos de erro: criação sem título, cor inválida, operações em tarefas inexistentes - Utiliza `supertest` para simular requisições reais - O backend exige Node.js ^16.15.0 para funcionamento correto. - É necessário configurar o `.env` e gerar uma `APP_KEY` antes de rodar. - O código está limpo, modular, com separação clara entre model, controller, tipos e validação. - A estrutura facilita manutenção, testes e futuras expansões. - [`scripts/reset-db.ts`](backend/scripts/reset-db.ts:1): Reseta o banco de dados (apaga e recria a tabela de tarefas). - [`scripts/seed-db.ts`](backend/scripts/seed-db.ts:1): Popula o banco com tarefas de demonstração, usando apenas cores válidas (`color1` a `color12` ou `#FFF`), alinhadas ao frontend. ```bash npx ts-node scripts/reset-db.ts npx ts-node scripts/seed-db.ts ```
WalkthroughThis update replaces the previous vehicles API with a new, fully implemented task management backend using AdonisJS, TypeScript, and SQLite. It introduces models, controllers, validation, RESTful routing, and functional tests for tasks. Supporting scripts for database setup and seeding, as well as configuration files for environment, linting, and formatting, are also added. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Router
participant TasksController
participant TaskModel
participant SQLiteDB
Client->>Router: HTTP Request (/tasks)
Router->>TasksController: Route request (index, store, show, update, destroy)
TasksController->>TaskModel: Call static method (all, create, find, update, delete)
TaskModel->>SQLiteDB: Execute SQL query
SQLiteDB-->>TaskModel: Return result
TaskModel-->>TasksController: Return data or error
TasksController-->>Client: HTTP Response (data or error)
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
npm error Exit handler never called! ✨ Finishing Touches
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. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 9
🔭 Outside diff range comments (1)
package.json (1)
31-40: Remove conflicting Prettier configuration.This Prettier configuration conflicts with the
.prettierrcfile, causing inconsistent formatting behavior. Since.prettierrctakes precedence, this section should be removed to avoid confusion.Apply this diff to remove the conflicting configuration:
- "prettier": { - "trailingComma": "es5", - "semi": false, - "singleQuote": true, - "useTabs": false, - "quoteProps": "consistent", - "bracketSpacing": true, - "arrowParens": "always", - "printWidth": 100 - },
♻️ Duplicate comments (3)
scripts/seed-db.ts (3)
6-6: Use consistent database path across files.Same issue as in
reset-db.ts- the hardcoded database path should be consistent across all files.
76-76: Consider using English for console messages.Same consistency issue as in other scripts - consider using English for console messages.
80-80: Consider using English for error messages.Same consistency issue as in other scripts - consider using English for error messages.
🧹 Nitpick comments (12)
config/database.ts (2)
16-16: Consider using environment variable for database path.The database file path is hardcoded, which may cause issues in different environments. Consider using an environment variable for better flexibility and deployment consistency.
- filename: './database/database.sqlite', + filename: process.env.DB_DATABASE || './database/database.sqlite',
22-23: Review production settings for health checks and debug mode.Both
healthCheckanddebugare disabled, which is appropriate for production but may hinder development and monitoring. Consider making these environment-dependent.- healthCheck: false, - debug: false, + healthCheck: process.env.NODE_ENV !== 'production', + debug: process.env.NODE_ENV === 'development',scripts/reset-db.ts (2)
23-23: Consider using English for console messages.The console message is in Portuguese while the rest of the codebase appears to be in English. Consider using English for consistency.
- console.log('Banco de dados resetado com sucesso.') + console.log('Database reset successfully.')
27-27: Consider using English for error messages.The error message is in Portuguese while the rest of the codebase appears to be in English. Consider using English for consistency.
- console.error('Erro ao resetar banco:', err) + console.error('Error resetting database:', err)app/Types/Task.ts (2)
7-8: Consider using consistent timestamp types.The
createdAtandupdatedAtfields accept bothDateandstring, which may lead to type confusion. Consider using a consistent type based on how the data is stored and retrieved.If SQLite stores timestamps as strings (ISO format), consider:
- createdAt: Date | string - updatedAt: Date | string + createdAt: string + updatedAt: stringOr create a specific type:
+type Timestamp = Date | string + export interface ITask { id: number title: string description: string isFavorite: boolean color: string - createdAt: Date | string - updatedAt: Date | string + createdAt: Timestamp + updatedAt: Timestamp }
1-29: Add JSDoc comments for better documentation.The interfaces would benefit from documentation describing their purpose, field constraints, and usage examples.
+/** + * Represents a task entity in the system + */ export interface ITask { + /** Unique identifier for the task */ id: number + /** Task title (required) */ title: string + /** Task description (optional) */ description: string + /** Whether the task is marked as favorite */ isFavorite: boolean + /** Task color (predefined color names or #FFF) */ color: string + /** Task creation timestamp */ createdAt: Date | string + /** Task last update timestamp */ updatedAt: Date | string }app/Validators/TaskValidator.ts (1)
3-6: Simplify redundant color representations.The COLORS array contains three different representations of white (
'#FFF','#fff','#ffffff') which creates unnecessary redundancy. Consider standardizing to a single format for consistency.export const COLORS = [ 'color1', 'color2', 'color3', 'color4', 'color5', 'color6', - 'color7', 'color8', 'color9', 'color10', 'color11', 'color12', '#FFF', '#fff', '#ffffff' + 'color7', 'color8', 'color9', 'color10', 'color11', 'color12', '#ffffff' ]app/Models/Task.ts (1)
26-107: Consider refactoring static-only class to module functions.While the current implementation is functionally correct, the static analysis hint correctly identifies that this class contains only static methods. Consider refactoring to use plain exported functions for better simplicity and tree-shaking.
Example refactor:
// Instead of static class methods export async function getAllTasks(): Promise<ITask[]> { const db = await dbPromise const tasks = await db.all('SELECT * FROM tasks ORDER BY is_favorite DESC, created_at DESC') return tasks.map(toITask) } export async function findTask(id: number): Promise<ITask | null> { // ... implementation }This approach aligns with functional programming principles and modern JavaScript best practices.
PULL_REQUEST.md (4)
54-78: Remove line-number suffixes from file links.
Links like(backend/app/Types/Task.ts:1)include a:1suffix that won't resolve. Please adjust all references to point to the file path only.- [`app/Types/Task.ts`](backend/app/Types/Task.ts:1) + [`app/Types/Task.ts`](backend/app/Types/Task.ts)Apply the same change to other links under Models, Controllers, Validators, routes, tests and scripts.
79-91: Consolidate duplicate feature lists.
The “Funcionalidades Implementadas” section repeats items from the checklist. Consider merging or removing one of these lists to reduce redundancy.
105-113: Streamline “Observações” section.
The notes reiterate Node version and env-var setup already covered above. Consider merging them into the setup steps or removing redundancies to keep the doc concise.
102-102: Remove trailing colon in heading.
Markdown style lint flags the colon in### Como usar:. Remove it for consistency with other headings.- ### Como usar: + ### Como usar
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (19)
.env.example(1 hunks).prettierrc(1 hunks)PULL_REQUEST.md(1 hunks)app/Controllers/TasksController.ts(1 hunks)app/Controllers/VehiclesController.ts(0 hunks)app/Models/Task.ts(1 hunks)app/Types/Task.ts(1 hunks)app/Types/Vehicle.ts(0 hunks)app/Validators/TaskValidator.ts(1 hunks)config/database.ts(1 hunks)contracts/tests.ts(1 hunks)eslint.config.js(1 hunks)package.json(2 hunks)scripts/reset-db.ts(1 hunks)scripts/seed-db.ts(1 hunks)start/routes.ts(1 hunks)tests/functional/tasks-api.spec.ts(1 hunks)tests/functional/vehicles-api.spec.ts(0 hunks)tests/testApp.ts(1 hunks)
💤 Files with no reviewable changes (3)
- app/Controllers/VehiclesController.ts
- tests/functional/vehicles-api.spec.ts
- app/Types/Vehicle.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
app/Models/Task.ts (1)
app/Types/Task.ts (3)
ITask(1-9)ICreateTaskDTO(11-16)IUpdateTaskDTO(18-23)
app/Controllers/TasksController.ts (3)
app/Models/Task.ts (1)
Task(26-107)app/Validators/TaskValidator.ts (2)
createTaskSchema(8-13)updateTaskSchema(15-20)app/Types/Task.ts (1)
IErrorResponse(25-28)
🪛 dotenv-linter (3.3.0)
.env.example
[warning] 5-5: [UnorderedKey] The DB_CONNECTION key should go before the HOST key
[warning] 6-6: [UnorderedKey] The DB_DATABASE key should go before the HOST key
🪛 Biome (1.9.4)
app/Models/Task.ts
[error] 26-107: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
🪛 LanguageTool
PULL_REQUEST.md
[typographical] ~36-~36: Símbolo sem par: “]” aparentemente está ausente
Context: ...v ``` 5. A API estará disponível em [http://localhost:3333](http://localhost:...
(UNPAIRED_BRACKETS)
[uncategorized] ~99-~99: Sinal de pontuação isolado.
Context: ...t-db.ts`](backend/scripts/reset-db.ts:1): Reseta o banco de dados (apaga e recria...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~100-~100: Sinal de pontuação isolado.
Context: ...ed-db.ts`](backend/scripts/seed-db.ts:1): Popula o banco com tarefas de demonstra...
(UNLIKELY_OPENING_PUNCTUATION)
🪛 markdownlint-cli2 (0.17.2)
PULL_REQUEST.md
102-102: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
🔇 Additional comments (16)
package.json (2)
9-9: Good improvement to the lint script.Removing the
--ext .tsrestriction allows ESLint to process all relevant file types, which is more comprehensive for a mixed codebase.
52-52: Appropriate dependencies for the AdonisJS backend.The added dependencies are well-suited for the task management backend:
supertest: Essential for API endpoint testing@adonisjs/lucid: AdonisJS ORM for database operationssqliteandsqlite3: SQLite database driversAlso applies to: 59-59, 64-65
.env.example (1)
5-6: Appropriate SQLite database configuration.The database environment variables are correctly configured for SQLite usage:
DB_CONNECTION=sqlitespecifies the database driverDB_DATABASE=./database/database.sqlitesets a conventional database file pathcontracts/tests.ts (1)
15-17: Good cleanup of unused interface extension.Commenting out the empty
Testinterface extension is appropriate since it wasn't providing any custom typing. This simplifies the test contracts while preserving the code for future reference if needed.start/routes.ts (1)
23-23: Excellent use of resource routing for RESTful API.The resource route with
.apiOnly()is the correct approach for a RESTful API, automatically generating the standard CRUD endpoints (index, show, store, update, destroy) while excluding form-based routes. This provides clean, conventional URL patterns for the task management API.scripts/seed-db.ts (2)
62-73: Good use of parameterized queries.Excellent security practice using parameterized queries to prevent SQL injection attacks when inserting the seed data.
16-56: Verify color values align with validation rules.The script uses predefined color names (
color1throughcolor5) and#FFF. Ensure these values are consistent with the color validation rules mentioned in the PR objectives.#!/bin/bash # Description: Check if the color values used in seed data match the validation rules # Expected: Find validation rules for colors to ensure consistency # Search for color validation rules rg -A 10 -B 5 "color.*valid" --type ts rg -A 10 -B 5 "color.*enum|enum.*color" --type ts rg -A 10 -B 5 "color[0-9]|#FFF" --type tsapp/Validators/TaskValidator.ts (1)
8-13: Well-structured validation schema for task creation.The validation logic correctly enforces required title with proper trimming and minimum length validation. Optional fields are handled appropriately with consistent typing.
app/Controllers/TasksController.ts (2)
8-11: Clean and straightforward index implementation.The method correctly retrieves all tasks and returns them with appropriate HTTP status. The implementation is clean and follows REST conventions.
13-25: Well-implemented task creation with proper validation.The store method correctly validates input data and handles both validation errors and successful creation with appropriate HTTP status codes and error formatting.
tests/functional/tasks-api.spec.ts (1)
9-18: Excellent test coverage for validation scenarios.The tests appropriately cover both successful task creation and validation failure cases, ensuring the API behaves correctly with invalid inputs.
Also applies to: 43-50
app/Models/Task.ts (2)
56-88: Efficient dynamic update implementation.The update method excellently handles partial updates by building the SQL query dynamically based on provided fields. The approach avoids unnecessary database writes while ensuring the
updated_attimestamp is always updated.
96-106: Proper type conversion and field mapping.The
toITaskhelper correctly handles the impedance mismatch between SQLite storage (snake_case, integer booleans) and TypeScript interfaces (camelCase, proper booleans). The boolean conversion using double negation is appropriate.PULL_REQUEST.md (3)
1-4: Header and attribution are clear.
The title and author information succinctly identify the scope and owner of this PR.
9-36: Environment setup and server startup instructions are clear.
The steps to install dependencies, configure environment variables, and launch the dev server are well-documented and easy to follow.
38-52: Checklist of features is comprehensive.
All core functionalities are tracked with checkboxes, making it easy to verify completeness.
| { | ||
| "singleQuote": true, | ||
| "trailingComma": "all", | ||
| "printWidth": 100, | ||
| "tabWidth": 2, | ||
| "semi": true | ||
| } |
There was a problem hiding this comment.
Resolve conflicting Prettier configurations.
The .prettierrc settings conflict with the Prettier configuration in package.json. Specifically:
- Semicolons:
.prettierrchas"semi": truewhilepackage.jsonhas"semi": false - Trailing commas:
.prettierrchas"trailingComma": "all"whilepackage.jsonhas"trailingComma": "es5"
Choose one configuration approach to ensure consistent formatting across the project.
Apply this diff to use the .prettierrc file exclusively by removing the Prettier config from package.json:
Remove the "prettier" section from package.json (lines 31-40)Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In the .prettierrc file at lines 1 to 7, there is a conflict with Prettier
settings in package.json regarding semicolons and trailing commas. To fix this,
remove the Prettier configuration section entirely from package.json so that
only the .prettierrc file governs formatting rules, ensuring consistent
formatting across the project.
| import { Ignitor } from '@adonisjs/core/build/standalone' | ||
|
|
||
| export async function getAppCallback() { | ||
| const ignitor = new Ignitor(__dirname + '/..') |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use path.join for safer path construction.
String concatenation for paths can be error-prone and platform-dependent. Use Node.js path.join for better reliability.
+import path from 'path'
import { Ignitor } from '@adonisjs/core/build/standalone'
export async function getAppCallback() {
- const ignitor = new Ignitor(__dirname + '/..')
+ const ignitor = new Ignitor(path.join(__dirname, '..'))📝 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.
| const ignitor = new Ignitor(__dirname + '/..') | |
| import path from 'path' | |
| import { Ignitor } from '@adonisjs/core/build/standalone' | |
| export async function getAppCallback() { | |
| const ignitor = new Ignitor(path.join(__dirname, '..')) |
🤖 Prompt for AI Agents
In tests/testApp.ts at line 4, replace the string concatenation used to
construct the path for the Ignitor constructor with Node.js's path.join method.
Import the path module if not already imported, then use path.join(__dirname,
'..') to build the path safely and in a platform-independent way.
| export async function getAppCallback() { | ||
| const ignitor = new Ignitor(__dirname + '/..') | ||
| const httpServer = await ignitor.httpServer().start() | ||
| return httpServer.handle.bind(httpServer) | ||
| } No newline at end of file |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add error handling for server startup failures.
The function doesn't handle potential failures during server startup, which could lead to unhandled promise rejections in tests.
export async function getAppCallback() {
- const ignitor = new Ignitor(path.join(__dirname, '..'))
- const httpServer = await ignitor.httpServer().start()
- return httpServer.handle.bind(httpServer)
+ try {
+ const ignitor = new Ignitor(path.join(__dirname, '..'))
+ const httpServer = await ignitor.httpServer().start()
+ return httpServer.handle.bind(httpServer)
+ } catch (error) {
+ console.error('Failed to start test server:', error)
+ throw error
+ }Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In tests/testApp.ts around lines 3 to 7, the getAppCallback function lacks error
handling for the asynchronous server startup, which can cause unhandled promise
rejections. Modify the function to include a try-catch block around the server
startup code to catch and handle any errors that occur during the call to
ignitor.httpServer().start(). In the catch block, log the error or rethrow it to
ensure failures are properly managed during tests.
|
|
||
| async function resetDatabase() { | ||
| const db = await open({ | ||
| filename: './database/database.sqlite', |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use consistent database path across files.
The hardcoded database path should match the configuration in config/database.ts or use a shared constant to avoid inconsistencies.
Consider creating a shared database configuration:
+const DB_PATH = './database/database.sqlite'
+
async function resetDatabase() {
const db = await open({
- filename: './database/database.sqlite',
+ filename: DB_PATH,
driver: sqlite3.Database,
})📝 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.
| filename: './database/database.sqlite', | |
| const DB_PATH = './database/database.sqlite' | |
| async function resetDatabase() { | |
| const db = await open({ | |
| filename: DB_PATH, | |
| driver: sqlite3.Database, | |
| }) | |
| // …rest of reset logic… | |
| } |
🤖 Prompt for AI Agents
In scripts/reset-db.ts at line 6, the database path is hardcoded and may differ
from the path used in config/database.ts. To fix this, import the database path
constant or configuration from config/database.ts and replace the hardcoded
string with this shared value to ensure consistency across files.
| 'no-unused-vars': 'off', | ||
| 'no-undef': ['off'], | ||
| }, |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Review disabled ESLint rules carefully.
Disabling no-undef entirely may mask legitimate undefined variable errors that TypeScript doesn't catch in edge cases. Consider using 'no-undef': 'off' only for TypeScript files while keeping it enabled for JavaScript files.
rules: {
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'no-unused-vars': 'off',
- 'no-undef': ['off'],
+ 'no-undef': 'off',
},📝 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.
| 'no-unused-vars': 'off', | |
| 'no-undef': ['off'], | |
| }, | |
| rules: { | |
| '@typescript-eslint/no-unused-vars': [ | |
| 'error', | |
| { | |
| argsIgnorePattern: '^_', | |
| varsIgnorePattern: '^_', | |
| }, | |
| ], | |
| 'no-unused-vars': 'off', | |
| 'no-undef': 'off', | |
| }, |
🤖 Prompt for AI Agents
In eslint.config.js around lines 35 to 37, the 'no-undef' rule is disabled
globally, which can hide undefined variable errors in JavaScript files. Modify
the ESLint configuration to disable 'no-undef' only for TypeScript files by
applying an override for '*.ts' and '*.tsx' files, while keeping 'no-undef'
enabled for JavaScript files to ensure proper error detection.
| public async show({ params, response }: HttpContextContract) { | ||
| const task = await Task.find(Number(params.id)) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add input validation for numeric ID parameters.
The Number() conversion doesn't validate that the ID is a valid positive integer, which could lead to unexpected behavior with invalid inputs like negative numbers or non-numeric strings.
public async show({ params, response }: HttpContextContract) {
- const task = await Task.find(Number(params.id))
+ const id = parseInt(params.id, 10)
+ if (isNaN(id) || id <= 0) {
+ const error: IErrorResponse = { message: 'Invalid task ID' }
+ return response.badRequest(error)
+ }
+ const task = await Task.find(id)Apply similar validation to the update and destroy methods.
Also applies to: 36-38, 57-58
🤖 Prompt for AI Agents
In app/Controllers/TasksController.ts around lines 27-28, 36-38, and 57-58, the
code converts params.id to a number without validating it, which can cause
issues with invalid or negative IDs. Add input validation to ensure params.id is
a valid positive integer before using it. If the validation fails, return an
appropriate error response. Apply this validation consistently in the show,
update, and destroy methods.
| test('should update a task', async ({ assert }) => { | ||
| const res = await request.put(`/tasks/${createdId}`).send({ | ||
| isFavorite: true, | ||
| color: '#000000', | ||
| }) | ||
| assert.equal(res.status, 200) | ||
| assert.isTrue(res.body.isFavorite) | ||
| assert.equal(res.body.color, '#000000') | ||
| }) |
There was a problem hiding this comment.
Fix color validation test inconsistency.
The test uses color '#000000' which is not included in the COLORS array defined in TaskValidator.ts. This test should fail validation, but it expects a 200 status code, creating a mismatch between test expectations and actual validation rules.
test('should update a task', async ({ assert }) => {
const res = await request.put(`/tasks/${createdId}`).send({
isFavorite: true,
- color: '#000000',
+ color: '#ffffff',
})
assert.equal(res.status, 200)
assert.isTrue(res.body.isFavorite)
- assert.equal(res.body.color, '#000000')
+ assert.equal(res.body.color, '#ffffff')
})📝 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.
| test('should update a task', async ({ assert }) => { | |
| const res = await request.put(`/tasks/${createdId}`).send({ | |
| isFavorite: true, | |
| color: '#000000', | |
| }) | |
| assert.equal(res.status, 200) | |
| assert.isTrue(res.body.isFavorite) | |
| assert.equal(res.body.color, '#000000') | |
| }) | |
| test('should update a task', async ({ assert }) => { | |
| const res = await request.put(`/tasks/${createdId}`).send({ | |
| isFavorite: true, | |
| color: '#ffffff', | |
| }) | |
| assert.equal(res.status, 200) | |
| assert.isTrue(res.body.isFavorite) | |
| assert.equal(res.body.color, '#ffffff') | |
| }) |
🤖 Prompt for AI Agents
In tests/functional/tasks-api.spec.ts around lines 26 to 34, the test updates a
task with color '#000000', which is not in the allowed COLORS array in
TaskValidator.ts, causing a validation mismatch. To fix this, change the color
value in the test to one that exists in the COLORS array so the test aligns with
the validation rules and expects a 200 status code correctly.
| - É necessário configurar o `.env` e gerar uma `APP_KEY` antes de rodar. | ||
| - O código está limpo, modular, com separação clara entre model, controller, tipos e validação. | ||
| - A estrutura facilita manutenção, testes e futuras expansões. | ||
|
|
||
| ## Scripts Utilitários | ||
|
|
||
| - [`scripts/reset-db.ts`](backend/scripts/reset-db.ts:1): Reseta o banco de dados (apaga e recria a tabela de tarefas). | ||
| - [`scripts/seed-db.ts`](backend/scripts/seed-db.ts:1): Popula o banco com tarefas de demonstração, usando apenas cores válidas (`color1` a `color12` ou `#FFF`), alinhadas ao frontend. | ||
|
|
||
| ### Como usar: | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add instructions to run tests.
You’ve documented the functional tests but haven’t shown how to execute them. Please include a step (e.g., npm run test or node ace test) under the setup section.
## Como configurar e executar o backend localmente
4. Inicie o servidor de desenvolvimento:
```sh
npm run dev
```
+ 5. Execute a suíte de testes:
+ ```sh
+ npm run test
+ ```🧰 Tools
🪛 LanguageTool
[uncategorized] ~99-~99: Sinal de pontuação isolado.
Context: ...t-db.ts`](backend/scripts/reset-db.ts:1): Reseta o banco de dados (apaga e recria...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~100-~100: Sinal de pontuação isolado.
Context: ...ed-db.ts`](backend/scripts/seed-db.ts:1): Popula o banco com tarefas de demonstra...
(UNLIKELY_OPENING_PUNCTUATION)
🪛 markdownlint-cli2 (0.17.2)
102-102: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
🤖 Prompt for AI Agents
In PULL_REQUEST.md around lines 93 to 103, add instructions on how to run the
test suite under the setup section. Specifically, include a step after the
existing commands showing the command to execute tests, such as "npm run test"
or "node ace test", formatted as a code block for clarity.
|
|
||
| ## Descrição Geral | ||
|
|
||
| Este pull request implementa o backend do CoreNotes, uma API RESTful em Node.js (AdonisJS + TypeScript) para gerenciamento de tarefas, com persistência em SQLite, validação robusta, tipagem forte e integração total com o frontend. O projeto segue os requisitos do desafio e está alinhado ao mockup e integrações descritas em [`Leiame.md`](../../Leiame.md). |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix broken relative link to README.
The reference Leiame.md likely points outside the repo. It should link directly to the README in the project root.
- Este pull request implementa ... descritas em [`Leiame.md`](../../Leiame.md).
+ Este pull request implementa ... descritas em [`Leiame.md`](Leiame.md).📝 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.
| Este pull request implementa o backend do CoreNotes, uma API RESTful em Node.js (AdonisJS + TypeScript) para gerenciamento de tarefas, com persistência em SQLite, validação robusta, tipagem forte e integração total com o frontend. O projeto segue os requisitos do desafio e está alinhado ao mockup e integrações descritas em [`Leiame.md`](../../Leiame.md). | |
| Este pull request implementa o backend do CoreNotes, uma API RESTful em Node.js (AdonisJS + TypeScript) para gerenciamento de tarefas, com persistência em SQLite, validação robusta, tipagem forte e integração total com o frontend. O projeto segue os requisitos do desafio e está alinhado ao mockup e integrações descritas em [`Leiame.md`](Leiame.md). |
🤖 Prompt for AI Agents
In PULL_REQUEST.md at line 7, the relative link to the README file is incorrect
and points outside the repository. Update the link to point directly to the
README file in the project root by changing the path to a correct relative or
absolute path within the repo, ensuring it resolves properly when viewed on the
repository platform.
CoreNotes – Backend de Tarefas
Autor: Mauro Luiz dos Santos Junior
Descrição Geral
Este pull request implementa o backend do CoreNotes, uma API RESTful em Node.js (AdonisJS + TypeScript) para gerenciamento de tarefas, com persistência em SQLite, validação robusta, tipagem forte e integração total com o frontend. O projeto segue os requisitos do desafio e está alinhado ao mockup e integrações descritas em
Leiame.md.Como configurar e executar o backend localmente
Ajuste a versão do Node.js:
O backend requer Node.js na versão ^16.15.0, que foi mantido para preservar o formato original do desafio.
Recomenda-se o uso de nvm ou nvm-windows para garantir compatibilidade.
Instale as dependências:
Configure as variáveis de ambiente:
Inicie o servidor de desenvolvimento:
A API estará disponível em http://localhost:3333
Checklist de Funcionalidades
Detalhes Técnicos das Implementações
Tipo de Tarefa:
app/Types/Task.tsdefine as interfacesITask,ICreateTaskDTO,IUpdateTaskDTOeIErrorResponsepara garantir clareza e segurança na manipulação dos dados.Model de Tarefa:
app/Models/Task.tscentraliza toda a lógica de acesso ao banco SQLite, desacoplando o controller e facilitando manutenção.Controller:
app/Controllers/TasksController.tsimplementa os endpoints REST (index,store,show,update,destroy), utilizando o model e validadores.Validação:
app/Validators/TaskValidator.tsdefine schemas para criação e atualização, exigindo título obrigatório e cor válida.Agora, a cor aceita apenas nomes
color1acolor12ou#FFF, exatamente como no frontend.Rotas:
start/routes.tsutilizaRoute.resource('/tasks', 'TasksController').apiOnly()para expor as rotas RESTful.Persistência:
Utiliza SQLite via
sqlite3esqlite, garantindo persistência real dos dados emdatabase/database.sqlite.A escolha vem do fato de não usarmos esse backend em produção, mas sim para fins de cumprir o desafio.
Padronização:
Respostas da API seguem camelCase, alinhadas ao contrato do frontend.
Funcionalidades Implementadas
Testes Automatizados
tests/functional/tasks-api.spec.tscobrem:supertestpara simular requisições reaisObservações
.enve gerar umaAPP_KEYantes de rodar.Scripts Utilitários
scripts/reset-db.ts: Reseta o banco de dados (apaga e recria a tabela de tarefas).scripts/seed-db.ts: Popula o banco com tarefas de demonstração, usando apenas cores válidas (color1acolor12ou#FFF), alinhadas ao frontend.Como usar:
Summary by CodeRabbit
New Features
Bug Fixes
Chores