Skip to content

Commit e19d58c

Browse files
tektaxiJamieXiao
andauthored
Feat/assign reviewers (#959)
* Assign 2 reviewers per unreviewed Hacker submitted before cutoff time. Will need a cleaning for documentation * removed to requirement that the reviewer name has to be empty (now it's just filtering if hacker was created before cutoff) * clean * Use string[] parameter instead of hardcoded names --------- Co-authored-by: JAMIE XIAO <[email protected]>
1 parent 543d046 commit e19d58c

File tree

5 files changed

+147
-4
lines changed

5 files changed

+147
-4
lines changed

constants/routes.constant.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,16 @@ const hackerRoutes = {
213213
uri: "/api/hacker/reviewerComments2/" + Constants.ROLE_CATEGORIES.SELF,
214214
_id: mongoose.Types.ObjectId.createFromTime(179)
215215
},
216+
// patchAnyReviewerNameById: {
217+
// requestType: Constants.REQUEST_TYPES.PATCH,
218+
// uri: "/api/hacker/reviewerName/" + Constants.ROLE_CATEGORIES.ALL,
219+
// _id: mongoose.Types.ObjectId.createFromTime(168)
220+
// },
221+
// patchSelfReviewerNameById: {
222+
// requestType: Constants.REQUEST_TYPES.PATCH,
223+
// uri: "/api/hacker/reviewerName/" + Constants.ROLE_CATEGORIES.SELF,
224+
// _id: mongoose.Types.ObjectId.createFromTime(169)
225+
// },
216226
patchSelfCheckInById: {
217227
requestType: Constants.REQUEST_TYPES.PATCH,
218228
uri: "/api/hacker/checkin/" + Constants.ROLE_CATEGORIES.SELF,

controllers/hacker.controller.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,27 @@ function updatedHackerBatch(req, res) {
102102
});
103103
}
104104

105+
/**
106+
* @function assignReviewers
107+
* @param {{body: {names: string[]}}} req
108+
* @param {*} res
109+
* @return {JSON} Success or error status
110+
* @description
111+
* Assign reviewers to hackers who've not yet been assigned reviewers and submitted applications before the deadline.
112+
* Returns a 200 status after bulk assignment reviewers.
113+
* The assignments are located in req.body.
114+
*/
115+
function assignedReviewers(req, res) {
116+
return res.status(200).json({
117+
message: 'Successfully assigned reviewers to hackers',
118+
data: req.body
119+
});
120+
}
121+
105122
module.exports = {
106123
updatedHacker: updatedHacker,
107124
updatedHackerBatch: updatedHackerBatch,
125+
assignedReviewers: assignedReviewers,
108126
createdHacker: createdHacker,
109127
uploadedResume: uploadedResume,
110128
downloadedResume: downloadedResume,

middlewares/hacker.middleware.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
const TAG = `[ HACKER.MIDDLEWARE.js ]`;
55
const mongoose = require("mongoose");
6+
const ObjectId = mongoose.Types.ObjectId;
67
const { HACKER_REVIEWER_STATUS_NONE } = require("../constants/general.constant");
78
const { HACKER_REVIEWER_STATUSES } = require("../constants/general.constant");
89
const { HACKER_REVIEWER_NAMES } = require("../constants/general.constant");
@@ -740,6 +741,97 @@ async function updateBatchHacker(req, res, next) {
740741
next();
741742
}
742743

744+
745+
/**
746+
* Updates a hacker that is specified by req.params.id, and then sets req.email
747+
* to the email of the hacker, found in Account.
748+
* Assigns reviewers to hackers in a batch process.
749+
* @param {*} req
750+
* @param {*} res
751+
* @param {*} next
752+
*/
753+
async function assignReviewers(req, res, next) {
754+
try {
755+
console.log('Starting assignReviewers');
756+
757+
// const REVIEWER_NAMES = HACKER_REVIEWER_NAMES.filter(name => name !== ''); // get all non-empty reviewer names
758+
const REVIEWER_NAMES = req.body.names;
759+
console.log('Reviewer names:', REVIEWER_NAMES);
760+
761+
const cutoff = new Date('2025-11-27T17:23:59.000Z'); // EDIT: set your desired cutoff date here
762+
const cutoffObjectId = new ObjectId(Math.floor(cutoff.getTime() / 1000).toString(16) + "0000000000000000");
763+
764+
const hackerModel = require('../models/hacker.model');
765+
766+
// find all hackers created before the cutoff date
767+
const hackers = await hackerModel.find({
768+
_id: { $lte: cutoffObjectId }
769+
}).select('_id');
770+
771+
console.log('Found hackers:', hackers.length);
772+
773+
// get counts
774+
const hackerCount = hackers.length;
775+
const revwiewerCount = REVIEWER_NAMES.length;
776+
777+
if (hackerCount === 0) {
778+
console.log('No hackers found for reviewer assignment.');
779+
780+
req.body = {
781+
success: true,
782+
assigned: 0,
783+
reviewers: revwiewerCount,
784+
assignments: []
785+
}
786+
787+
return next();
788+
}
789+
790+
console.log(`Found ${hackerCount} assignable reviewers.`);
791+
792+
let assignments = [];
793+
let hackerIndex = 0;
794+
let updatePromises = [];
795+
796+
// assign reviewers to hackers
797+
for (const hacker of hackers) {
798+
const assignedReviewer1 = REVIEWER_NAMES[hackerIndex % revwiewerCount];
799+
const assignedReviewer2 = REVIEWER_NAMES[(hackerIndex + 1) % revwiewerCount];
800+
801+
assignments.push({ hackerId: hacker._id, reviewer: assignedReviewer1, reviewer2: assignedReviewer2 });
802+
803+
updatePromises.push(
804+
Services.Hacker.updateOne(hacker._id, { reviewerName: assignedReviewer1, reviewerName2: assignedReviewer2 })
805+
);
806+
807+
hackerIndex++;
808+
}
809+
810+
// exec all updates
811+
await Promise.all(updatePromises);
812+
813+
console.log(`Completed reviewer assignment at ${new Date().toISOString()}`);
814+
console.log(`Assignments:`, assignments);
815+
816+
req.body = {
817+
success: true,
818+
assigned: hackerCount,
819+
reviewers: revwiewerCount,
820+
assignments: assignments
821+
}
822+
823+
return next();
824+
825+
} catch (error) {
826+
console.error('Error during reviewer assignment:', error);
827+
return next({
828+
status: 500,
829+
message: Constants.Error.GENERIC_500_MESSAGE,
830+
data: { error: error }
831+
});
832+
}
833+
}
834+
743835
/**
744836
* Sets req.body.status to Accepted for next middleware, and store req.params.id as req.hackerId
745837
* @param {{params:{id: string}, body: *}} req
@@ -911,6 +1003,7 @@ module.exports = {
9111003
),
9121004
updateHacker: Middleware.Util.asyncMiddleware(updateHacker),
9131005
updateBatchHacker: Middleware.Util.asyncMiddleware(updateBatchHacker),
1006+
assignReviewers: Middleware.Util.asyncMiddleware(assignReviewers),
9141007
parseAccept: parseAccept,
9151008
parseAcceptBatch: parseAcceptBatch,
9161009
parseAcceptEmail: parseAcceptEmail,

routes/api/hacker.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,32 @@ module.exports = {
299299
Controllers.Hacker.updatedHacker
300300
);
301301

302+
/**
303+
* @api {post} /hacker/assignReviewers update a hacker's reviewer status
304+
* @apiName patchAssignReviewers
305+
* @apiGroup Hacker
306+
* @apiVersion 0.0.9
307+
*
308+
* @apiParam (body) None
309+
* @apiSuccess {string} message Success message
310+
* @apiSuccess {object} data Hacker object
311+
* @apiSuccessExample {object} Success-Response:
312+
* {
313+
* "message": "Assigned reviewers to hackers",
314+
* }
315+
* @apiPermission Administrator
316+
*/
317+
hackerRouter.route("/assignReviewers").post(
318+
// Middleware.Validator.RouteParam.idValidator,
319+
// Middleware.Auth.ensureAuthenticated(),
320+
// Middleware.Auth.ensureAuthorized([Services.Hacker.findById]),
321+
// Middleware.Validator.Hacker.updateReviewerStatusValidator,
322+
// Middleware.parseBody.middleware,
323+
// Middleware.Hacker.parsePatch,
324+
Middleware.Hacker.assignReviewers,
325+
Controllers.Hacker.assignedReviewers
326+
);
327+
302328
/**
303329
* @api {patch} /hacker/reviewerStatus/:id update a hacker's reviewer status
304330
* @apiName patchHackerReviewerStatus

scripts/accept_script.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,6 @@ def updateReviewerComments2():
619619
else:
620620
_print('could not find {0}'.format(
621621
ID), 1, index, len(HACKER_IDs))
622-
623-
def assignReviewers():
624-
HACKER_IDs = getIdList()
625-
numHackers = HACKER_IDs.count
626622

627623

628624
# def sendDayOfEmail():

0 commit comments

Comments
 (0)