Skip to content
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

Feature/254 batch actions #600

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
Open

Conversation

printharsh
Copy link

@printharsh printharsh commented Nov 3, 2019

Description

Allows batch actions (hacker status updates and sending emails) for a search query provided.

Currently, updateStatus only works for hacker models, change name to updateHackerStatuses and sendEmailsToHackers?

Fixes #254 #276

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested?

Tested manually with queries of hackers.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Copy link
Member

@pierreTklein pierreTklein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool work! Check my comments for fixes.

async function emailResults(req, res) {
let results = req.body.results;
let message;
if (results === undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error-handling should be done via next(<err message>);. See this example for reference.
This way, *.controller.js only handles successes.

@@ -62,6 +61,48 @@ async function executeQuery(req, res, next) {
return next();
}

/**
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to flesh out this comment so we know what this function does :)!

}

/**
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto about the comment

@@ -62,6 +61,48 @@ async function executeQuery(req, res, next) {
return next();
}

/**
*
* @param {} req
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding what attributes this function expects to be inside of req.


/**
*
* @param {} req
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding what attributes this function expects to be inside of req.

"data": {}
}
*
* @apiSuccess {String} message Error message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be @apiError

services/search.service.js Show resolved Hide resolved
query.sort(sort_by);
query.sort(sortBy);
}
return query.limit(limit).skip(limit * page)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if limit / page are undefined?

* @returns {Promise<[Array]>}
* @description Builds and executes a status update based on a subset of mongodb
*/
function executeStatusAction(model, queryArray, page, limit, sort, sortBy, update, shouldExpand = false) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is more generic than executeStatus. This is a batch update for any model based on a query and a model. Therefore, the method name should reflect that.

* @description Sends a status update email based on a subset of mongodb
*/
async function executeEmailAction(model, queryArray, page, limit, sort, sortBy, status, shouldExpand = false) {
var query = createQuery(model, queryArray, page, limit, sort, sortBy, shouldExpand);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic should not necessarily be in the executeEmailAction method, or at least if it is, then the parameters should reflect some sort of restrictions. For example, the code below assumes that the model is of type Hacker. However, the method parameters take in a model object!

I would recommend this function be used only for Hacker objects, since it send a status update email. Because of this, the function name should change to reflect this.

@pierreTklein
Copy link
Member

  • This requires a documentation change, so run npm run docs or something of that sort.
  • Make sure to write a few test calls to your API!

@@ -11,4 +11,24 @@ module.exports = {
VALIDATOR.booleanValidator("query", "expand", true),
VALIDATOR.searchValidator("query", "q")
],
statusValidator: [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this validator validate for status? It seems not necessarily a search and update status validator, but rather a search and update hacker validator?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, note that you can chain validator middlewares in the route as well! Consider that both your new validators perform the function of 'check for valid search' + 'check for something else', and searchQueryValidator already performs the first part of that. Instead of having your validators duplicate this code, you could chain searchQueryValidator as well as statusValidator in the route.

VALIDATOR.searchValidator("query", "q"),
VALIDATOR.updateHackerValidator("query", "update")
],
emailValidator: [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same notes as above, but also, it's kinda weird that the emailValidator checks the status? I see this is being used in the bulk email endpoint, but should the name of a thing describe what it does, or where it's being used? What kind of coupling does that cause?

Middleware.Validator.Search.emailValidator,
Middleware.parseBody.middleware,
Middleware.Search.parseQuery,
Middleware.Search.executeEmailAction,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This endpoint is interesting. The name sounds like a generic 'send emails' route. The middleware names look like generic 'send emails' validators. But 'emailValidator' validates for 'search + status', and then the executeEmailAction middleware ends up calling a service that seems to only send status update emails. I believe there's a mismatch between what this endpoint says it's doing, and what it actually does.

Are there plans to expand the functionality of the route? I think aligning functionality and naming would help. Also, if this is solely a status email sender, consider (from a comment above):
[...,
Middleware.Validator.Search.searchQueryValidator,
Middleware.Validator.Search.statusValidator,
...]

Does that align more or less with what this endpoint currently does?

Copy link
Member

@YiFeiZhang2 YiFeiZhang2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! My comments really deal with maintainability rather than functionality.

I think the biggest thing for me was a bit of confusion between the names of things and what they actually do.

*/
searchRouter.route("/updateStatus").get(
Middleware.Auth.ensureAuthenticated(),
Middleware.Auth.ensureAuthorized(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure only admins / staff are able to change this status!

*/
searchRouter.route("/sendEmails").get(
Middleware.Auth.ensureAuthenticated(),
Middleware.Auth.ensureAuthorized(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure only admins / staff are able to send emails too

},
"updateStatus": {
requestType: Constants.REQUEST_TYPES.GET,
uri: "/api/search/updateStatus",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we match syntax with other routes?

},
"sendEmails": {
requestType: Constants.REQUEST_TYPES.GET,
uri: "/api/search/sendEmails",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we match syntax with other routes?

@pierreTklein
Copy link
Member

Any updates on this PR?

@loreina
Copy link
Member

loreina commented Dec 5, 2019

@pierreTklein backlogged for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Batch actions
4 participants