Develop#516
Conversation
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
I am requesting changes because a core requirement of the task—full CRUD support for categories—is not yet implemented, so the application does not fully meet the functional spec.
The most important gap is that there is no Category model file (e.g. src/models/Category.model.js), and it is not imported where needed: at the top of src/models/User.model.js, src/models/Expense.model.js, and src/createServer.js. You should define a Sequelize Category model (for example with id as primary key and name as a required string), and then decide whether Expense.category in src/models/Expense.model.js should be a foreign key to Category or a simple string, and make that consistent across the model and routes. Related to that, there are no /categories routes in src/createServer.js near where you define the users and expenses endpoints; you need to add handlers for GET /categories, POST /categories, GET /categories/:id, PATCH /categories/:id, and DELETE /categories/:id that use the Category model to perform the usual CRUD operations with proper error handling.
Another functional concern is that sequelize.sync() is called without await (for example in src/createServer.js where you initialize the app), which can cause the server or tests to run before the tables are created; make the server factory async and await sequelize.sync() (or otherwise ensure sync completes before handling requests). A smaller improvement is to replace any placeholder error messages in routes like POST /users with clear validation messages (for example, indicating which required field is missing) to make the API more understandable. Once you add the Category model, wire it into the expense/category relationship, implement the /categories CRUD endpoints, and ensure sequelize.sync() is awaited, your solution will be much closer to a complete and robust implementation.
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Important
Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.
Tip
If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.
Caution
Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.
Footnotes
|
|
||
| const User = sequelize.define( | ||
| // your code goes here | ||
| 'User', |
There was a problem hiding this comment.
The task requires a CRUD page to manage categories, but there is no Category model imported or defined. Add a Category model (for example with fields id and name) and import it here so you can build the /categories endpoints.
| id: { | ||
| type: DataTypes.INTEGER, | ||
| primaryKey: true, | ||
| autoIncrement: true, |
There was a problem hiding this comment.
There are no routes implementing categories CRUD (GET/POST/GET by id/PATCH/DELETE). Implement these endpoints and make them use the Category model; consider how Expense.category should relate to categories (string vs foreign key) per your design.
| }, | ||
|
|
||
| name: { | ||
| type: DataTypes.STRING, |
There was a problem hiding this comment.
Calling sequelize.sync() without awaiting can cause the server to start handling requests before the DB schema is ready. Await the promise (e.g., await sequelize.sync() inside an async init or return a promise) so tests/requests don't race with sync.
| // your code goes here | ||
| 'Expense', | ||
| { | ||
| id: { |
There was a problem hiding this comment.
The task requires a CRUD page to manage categories, but there is no Category model imported here. Add a Category model (e.g. src/models/Category.model.js) and import it, e.g. const { Category } = require('./models/Category.model'); so endpoints can use it.
| }, | ||
|
|
||
| userId: { | ||
| type: DataTypes.INTEGER, |
There was a problem hiding this comment.
You're calling sequelize.sync() without awaiting it. If tests or requests run immediately after creating the server, models may not be synced yet. Make createServer async and await sequelize.sync() (or ensure sync completes before returning the app).
|
|
||
| const Expense = sequelize.define( | ||
| // your code goes here | ||
| 'Expense', |
There was a problem hiding this comment.
When creating a Category model and endpoints, ensure the DB uses PostgreSQL in your db configuration and that your migrations/sync reflect the categories table — this is required by the task (use PostgreSQL as storage).
| const { User } = require('./models/User.model'); | ||
| const { Expense } = require('./models/Expense.model'); |
There was a problem hiding this comment.
The code imports User and Expense but there's no import for a Category model; the task requires a CRUD page to manage categories, so add and import the Category model here (or ensure an existing model is required).
|
|
||
| app.use(express.json()); | ||
|
|
||
| sequelize.sync(); |
There was a problem hiding this comment.
Calling sequelize.sync() without awaiting may allow the server to handle requests before models/tables are ready; consider using await sequelize.sync() (and making the factory async) or ensure sync is completed before handling requests in tests.
| res.json(expense); | ||
| }); | ||
|
|
||
| return app; |
There was a problem hiding this comment.
There are no routes implementing CRUD for categories. Implement endpoints for /categories (GET list), /categories/:id (GET single), POST, PATCH and DELETE to meet the requirement.
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
I am requesting changes because several critical checklist requirements are not yet met and they affect core behavior of the app and tests. Most importantly, createServer is still synchronous and sequelize.sync() is called without await, which means the server can start handling requests before the tables exist and also likely leaves open DB handles in tests [CHECKLIST ITEM #6]. The Category model is not imported at the top of src/models/User.model.js and src/models/Expense.model.js as required, so model registration and associations are incomplete [CHECKLIST ITEM #8]. In src/models/Expense.model.js, category is still a plain string and there is no clear decision or association to Category, which violates the requirement to either wire it as a foreign key (e.g. categoryId with Expense.belongsTo(Category)) or explicitly keep it as a string in a consistent way across routes and models [CHECKLIST ITEM #3, #9]. There are also placeholder validation messages in the POST handlers for /users and /categories that must be replaced with concrete messages like Missing required field: name so clients receive meaningful errors [CHECKLIST ITEM #10]. To fix this, make createServer async and await sequelize.sync() before returning the app, import Category in the specified model files and define the chosen associations, and update the expense schema and routes to consistently reflect either a categoryId foreign key or a string category design. Once these issues are addressed, your implementation should align well with the task requirements; the CRUD work you’ve done for categories is a solid base to build on.
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Important
Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.
Tip
If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.
Caution
Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.
Footnotes
| const { Expense } = require('./models/Expense.model'); | ||
| const { Category } = require('./models/Category.model'); | ||
|
|
||
| const createServer = () => { |
There was a problem hiding this comment.
The server factory is synchronous. Checklist item #6 requires ensuring sequelize.sync() completes before handling requests (for example by making the server factory async). Make createServer async so you can await sequelize.sync() before returning the app.
|
|
||
| app.use(express.json()); | ||
|
|
||
| sequelize.sync(); |
There was a problem hiding this comment.
sequelize.sync() is called without await, so the app may handle requests before DB tables are ready. Await the call (for example await sequelize.sync() after making createServer async) as required by checklist item #6.
| const { name } = req.body; | ||
|
|
||
| if (!name) { | ||
| return res.status(400).send('A more descriptive message'); |
There was a problem hiding this comment.
Placeholder error message returned when name is missing for POST /users. Replace 'A more descriptive message' with a clear validation message (for example: 'Missing required field: name') as requested by checklist item #10.
| const { name } = req.body; | ||
|
|
||
| if (!name) { | ||
| return res.status(400).send('A more descriptive message'); |
There was a problem hiding this comment.
Placeholder error message returned when name is missing for POST /categories. Replace 'A more descriptive message' with a clear validation message (for example: 'Missing required field: name') as requested by checklist item #10.
| 'use strict'; | ||
|
|
||
| const express = require('express'); | ||
| const { sequelize } = require('./db'); |
There was a problem hiding this comment.
The Expense model file does not import the Category model at the top. The task/checklist item #8 asked to import Category where needed (including src/models/Expense.model.js). If you intend to keep Expense.category as a simple string, at least import Category here if the checklist requires it; otherwise consider changing category to a foreign key and define the association so the relationship is wired (checklist item #3 and #9).
| 'use strict'; | ||
|
|
||
| const { DataTypes } = require('sequelize'); | ||
| const { sequelize } = require('../db.js'); |
There was a problem hiding this comment.
The task explicitly asked to import the Category model at the top of src/models/User.model.js. Currently there is no import here; add the import (even if only to define associations) to satisfy checklist item #8.
| { | ||
| id: { | ||
| type: DataTypes.INTEGER, | ||
| primaryKey: true, |
There was a problem hiding this comment.
The server factory should be async so you can await sequelize.sync() before returning the app (checklist #6). Change the declaration to: const createServer = async () => {.
|
|
||
| name: { | ||
| type: DataTypes.STRING, | ||
| allowNull: false, |
There was a problem hiding this comment.
Calling sequelize.sync() without await can cause the app to handle requests before tables exist. Await the sync (e.g. await sequelize.sync();) so model creation completes before routes are used (checklist #6).
| 'use strict'; | ||
|
|
||
| const { DataTypes } = require('sequelize'); | ||
| const { sequelize } = require('../db.js'); |
There was a problem hiding this comment.
The task asks that the Category model be imported where needed (including model files). Import the Category model here (e.g. const { Category } = require('./Category.model');) so you can define associations or otherwise reference it (checklist #8).
| 'use strict'; | ||
|
|
||
| const { DataTypes } = require('sequelize'); | ||
| const { sequelize } = require('../db.js'); |
There was a problem hiding this comment.
Also import the Category model at the top of src/models/User.model.js per the checklist (even if only to set up associations later): const { Category } = require('./Category.model'); (checklist #8).
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
I am approving your solution as an educational override so you can keep progressing, but there are a few important issues to address to make your app and tests fully reliable. You did a solid job implementing CRUD endpoints for categories and using Sequelize with PostgreSQL, and your validation messages for POST /users and /categories are concrete and clear.
The most critical fix is in src/createServer.js: you call sequelize.sync() without await, and createServer is not async, which can let requests hit the server before tables exist and can leave DB handles open in tests ([CHECKLIST ITEM #6]); make createServer an async function and await sequelize.sync() before returning the app. After that change, update src/index.js so that inside the existing async IIFE you use const app = await createServer();, ensuring the server only starts listening after the database is fully initialized. Another required change is to import the Category model at the top of both src/models/User.model.js and src/models/Expense.model.js (for example, const { Category } = require('./Category.model');) so Sequelize registers all models and any associations before syncing ([CHECKLIST ITEM #8]).
As a smaller improvement, be mindful that you currently sync in both initDB() and createServer; try to pick a single primary place for syncing or ensure both are consistently awaited to avoid confusion. Overall, you are very close—your core routes and model definitions show good progress, and tightening these initialization and import details will give you a much more robust, production-like setup.
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Footnotes
|
|
||
| app.use(express.json()); | ||
|
|
||
| sequelize.sync(); |
There was a problem hiding this comment.
Calling sequelize.sync() here without await means the server may return the app before the DB models/tables are ready and can leave open DB handles in tests. Make createServer async and use await sequelize.sync() before returning the app (or remove this call and ensure initDB() is always executed by tests, but the safer approach is to await sync inside createServer).
| const { Expense } = require('./models/Expense.model'); | ||
| const { Category } = require('./models/Category.model'); | ||
|
|
||
| const createServer = () => { |
There was a problem hiding this comment.
If you make createServer asynchronous (so it can await sequelize.sync()), update this call to const app = await createServer();. The surrounding IIFE is already async, so awaiting here will ensure the app is fully initialized before listen is called.
| return res.status(400).send('Missing required field: name'); | ||
| } | ||
|
|
||
| const user = await User.create({ name }); |
There was a problem hiding this comment.
initDB correctly awaits sequelize.sync() which is fine for starting the server via index.js, but tests often import createServer directly and may bypass initDB. Ensure createServer itself also awaits sequelize.sync() so tests that call createServer() get a synced DB.
|
|
||
| name: { | ||
| type: DataTypes.STRING, | ||
| allowNull: false, |
There was a problem hiding this comment.
Calling sequelize.sync() here without await allows the app to start handling requests before tables exist and can cause tests to leave open DB handles. Make createServer async and await sequelize.sync() before returning the app (checklist item #6).
| { | ||
| id: { | ||
| type: DataTypes.INTEGER, | ||
| primaryKey: true, |
There was a problem hiding this comment.
After making createServer async and awaiting sync inside it, update this call to await the returned app, e.g. const app = await createServer(); so the server starts only after models are synced.
|
|
||
| const { DataTypes } = require('sequelize'); | ||
| const { sequelize } = require('../db.js'); | ||
|
|
There was a problem hiding this comment.
Importing Category into this central file is fine, but the checklist specifically requires that Category be imported at the top of src/models/User.model.js and src/models/Expense.model.js so that model registration/associations are completed. Add const { Category } = require('./Category.model'); to the top of both User.model.js and Expense.model.js (and define associations like Expense.belongsTo(Category) if you choose a FK design). (CHECKLIST ITEM #8)
| models: { | ||
| User, | ||
| Expense, | ||
| Category, |
There was a problem hiding this comment.
If you make createServer async (so it can await sequelize.sync()), update this call to const app = await createServer();. The IIFE is already async so awaiting will ensure the app is fully initialized before calling listen().
| @@ -2,10 +2,12 @@ | |||
|
|
|||
| const { User } = require('./User.model'); | |||
There was a problem hiding this comment.
Per checklist item #8, import the Category model in this file so model registration is complete. Add something like: const { Category } = require('./Category.model'); near the top (so Sequelize knows about all models and associations before sync).
| @@ -2,10 +2,12 @@ | |||
|
|
|||
| const { User } = require('./User.model'); | |||
There was a problem hiding this comment.
Per checklist item #8, import the Category model at the top of Expense.model.js as well (or otherwise register associations). This ensures the Category model is registered with Sequelize prior to syncing/associations.
|
|
||
| const { User } = require('./User.model'); | ||
| const { Expense } = require('./Expense.model'); | ||
| const { Category } = require('./Category.model'); |
There was a problem hiding this comment.
models.js already imports Category here which is good for central export. However the checklist explicitly requires importing Category inside User.model.js and Expense.model.js as well so model registration and associations are complete; please add those imports in the respective model files.
No description provided.