-
Notifications
You must be signed in to change notification settings - Fork 56
#86, #87 #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#86, #87 #88
Conversation
(code, unit tests, Postman updates)
#87 - updated Swagger
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderReview I have added few comments which we need to be fixed before getting this merged.
Overall it is looking good @ngoctay
config/default.json
Outdated
"AUTH0_CLIENT_SECRET": "", | ||
"AUTH0_AUDIENCE": "", | ||
"AUTH0_URL": "", | ||
"AUTH0_CLIENT_ID": "5fctfjaLJHdvM04kSrCcC8yn0I4t1JTd", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this complete file from the commit. Where did you find these values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Will remove the AUTH_*** values from this file.
I got it from forum. It seems that we can't deploy the service without these values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ngoctay Can you please point me to the forum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vikasrohit I found those in another topcoder-platform github project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/models/project.js
Outdated
@@ -39,6 +36,7 @@ module.exports = function defineProject(sequelize, DataTypes) { | |||
cancelReason: DataTypes.STRING, | |||
version: DataTypes.STRING(15), | |||
templateId: DataTypes.BIGINT, | |||
projectTemplateId: DataTypes.BIGINT, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the templateId
instead, which is already added to the project schema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
permissions('projectType.view'), | ||
(req, res, next) => models.ProjectType.findOne({ | ||
where: { | ||
key: req.params.key, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should not retrieve records which are deleted i.e. deletedAt
is not null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need it.
Sequelize will add the "deletedAt IS NOT NULL" condition automatically because the ProjectType model is paranoid.
tableName: 'project_types',
paranoid: true,
timestamps: true,
I also have a test case to verify it in get.spec.js
:
it('should return 404 for deleted type', (done) => {
models.ProjectType.destroy({ where: { key } })
.then(() => {
request(server)
.get(`/v4/projectTypes/${key}`)
.set({
Authorization: `Bearer ${testUtil.jwts.admin}`,
})
.expect(404, done);
});
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay
module.exports = [ | ||
permissions('projectType.view'), | ||
(req, res, next) => models.ProjectType.findAll({ | ||
attributes: { exclude: ['deletedAt', 'deletedBy'] }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not retrieve the deleted records i.e. where deletedAt
is not null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with get.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay
|
||
return models.ProjectType.findOne({ | ||
where: { | ||
key: req.params.key, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not update a deleted record i.e. where deletedAt
is not null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with get.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay
src/routes/projects/create.js
Outdated
details: Joi.any(), | ||
challengeEligibility: Joi.array().items(Joi.object().keys({ | ||
role: Joi.string().valid('submitter', 'reviewer', 'copilot'), | ||
users: Joi.array().items(Joi.number().positive()), | ||
groups: Joi.array().items(Joi.number().positive()), | ||
})).allow(null), | ||
templateId: Joi.number().positive(), | ||
projectTemplateId: Joi.number().integer().positive(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use templateId
instead of new field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
src/routes/projects/create.js
Outdated
}) | ||
// Validate the projectTemplateId | ||
.then(() => { | ||
if (project.projectTemplateId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use templateId
instead of projectTemplateId
everywhere in the new code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
src/routes/projects/create.js
Outdated
} | ||
|
||
const phases = _.values(projectTemplate.phases); | ||
return Promise.all(_.map(phases, phase => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to create phases before creating direct project. Please try to wrap (may be in the projects model) all project child entities creation in single promise so that projects.create does not look too much nested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to create phases before creating direct project. Please try to wrap (may be in the projects model) all project child entities creation in single promise so that projects.create does not look too much nested.
OK. Will move it to a then() right after creating the project
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we wrap it in a single method which creates project,phase and products and use that in project.create route?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i will wrap a single method which creates phases and products. Cannot wrap creating project because we need to return the project instance for creating direct project later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't get it. Even if we wrap phase/product creation in project creation method, we can still return project object for creating direct project later. Wrapping all 3 in single method would ease having a single database transaction as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will wrap all 3 into a single method.
Regarding to the transaction, we don't need to specify it explicitly since we use continuation-local-storage
.
src/routes/projects/update.js
Outdated
details: Joi.any(), | ||
memers: Joi.any(), | ||
projectTemplateId: Joi.any().strip(), // ignore the project template id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use templateId
field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
src/routes/projects/create.js
Outdated
return Promise.resolve(); | ||
}); | ||
}))); | ||
return createPhases(req, newProject, projectTemplate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ngoctay for the changes, however, can we use the same database transaction, for creating phase/product, which project creation is using? I mean if project creation is not using transaction specifically, can we create a new transaction and pass that to both project and phase/product creation calls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for late reply, @vikasrohit and @coderReview
Please don't worry about the transaction.
We have the transaction wrapper already:
models.sequelize.transaction(() => {
And we don't need the option { transaction: tx }
because we use continuation-local-storage
.
All db operations inside the models.sequelize.transaction(() => {
are automatically wrapped in the transaction.
Reference: http://docs.sequelizejs.com/manual/tutorial/transactions.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ngoctay for the update. Understood.
src/routes/projects/create.js
Outdated
} | ||
|
||
const phases = _.values(projectTemplate.phases); | ||
return Promise.all(_.map(phases, phase => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't get it. Even if we wrap phase/product creation in project creation method, we can still return project object for creating direct project later. Wrapping all 3 in single method would ease having a single database transaction as well.
Thanks @ngoctay for the hard work. |
#86 #87