From 28bce3d1773d1047d09cb0780f68917961685f6a Mon Sep 17 00:00:00 2001 From: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> Date: Thu, 16 May 2024 19:41:20 +0530 Subject: [PATCH] add: one-time script to filter unfinished tasks from archived users. (#2040) * add: one-time script to filter unfinished tasks from archived users. * fix: remove verified status as done --------- Co-authored-by: Amit Prakash <34869115+iamitprakash@users.noreply.github.com> --- controllers/tasks.js | 4 +-- models/tasks.js | 24 ++++++++---------- routes/tasks.js | 3 +-- test/integration/tasks.test.js | 46 +++++++++++++++------------------- 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/controllers/tasks.js b/controllers/tasks.js index c0ea2aa9d..c4bc6ee1c 100644 --- a/controllers/tasks.js +++ b/controllers/tasks.js @@ -491,9 +491,7 @@ const updateStatus = async (req, res) => { const orphanTasks = async (req, res) => { try { - const { lastOrphanTasksFilterationTimestamp = 0 } = req.body; - - const updatedTasksData = await tasks.updateOrphanTasksStatus(lastOrphanTasksFilterationTimestamp); + const updatedTasksData = await tasks.updateOrphanTasksStatus(); return res.status(200).json({ message: "Orphan tasks filtered successfully", updatedTasksData }); } catch (error) { diff --git a/models/tasks.js b/models/tasks.js index 5d1697b46..113065ba0 100644 --- a/models/tasks.js +++ b/models/tasks.js @@ -648,17 +648,11 @@ const updateTaskStatus = async () => { } }; -const updateOrphanTasksStatus = async (lastOrphanTasksFilterationTimestamp) => { - const lastTimestamp = Number(lastOrphanTasksFilterationTimestamp); +const updateOrphanTasksStatus = async () => { try { const users = []; - const currentTimeStamp = Date.now(); - - const usersQuerySnapshot = await userModel - .where("roles.in_discord", "==", false) - .where("updated_at", ">=", lastTimestamp) - .where("updated_at", "<=", currentTimeStamp) - .get(); + const batch = firestore.batch(); + const usersQuerySnapshot = await userModel.where("roles.in_discord", "==", false).get(); usersQuerySnapshot.forEach((user) => users.push({ ...user.data(), id: user.id })); @@ -666,15 +660,17 @@ const updateOrphanTasksStatus = async (lastOrphanTasksFilterationTimestamp) => { for (const user of users) { const tasksQuerySnapshot = await tasksModel - .where("assigneeId", "==", user.id) - .where("status", "not-in", [COMPLETED, BACKLOG]) + .where("assignee", "==", user.id) + .where("status", "not-in", [BACKLOG, COMPLETED, DONE]) .get(); - tasksQuerySnapshot.forEach(async (taskDoc) => { + tasksQuerySnapshot.forEach((taskDoc) => { orphanTasksUpdatedCount++; - await tasksModel.doc(taskDoc.id).update({ status: BACKLOG }); + const taskRef = tasksModel.doc(taskDoc.id); + batch.update(taskRef, { status: BACKLOG, updated_at: Date.now() }); }); } + await batch.commit(); return { orphanTasksUpdatedCount }; } catch (error) { logger.error("Error marking tasks as backlog:", error); @@ -691,7 +687,7 @@ const markUnDoneTasksOfArchivedUsersBacklog = async (users) => { .where("assignee", "==", user.id) .where("status", "not-in", [COMPLETED, DONE, BACKLOG]) .get(); - tasksQuerySnapshot.forEach(async (taskDoc) => { + tasksQuerySnapshot.forEach((taskDoc) => { orphanTasksUpdatedCount++; const taskRef = tasksModel.doc(taskDoc.id); batch.update(taskRef, { status: BACKLOG, updated_at: Date.now() }); diff --git a/routes/tasks.js b/routes/tasks.js index 5d8d80eae..5596f982c 100644 --- a/routes/tasks.js +++ b/routes/tasks.js @@ -8,7 +8,6 @@ const { updateSelfTask, getTasksValidator, getUsersValidator, - filterOrphanTasksValidator, } = require("../middlewares/validators/tasks"); const authorizeRoles = require("../middlewares/authorizeRoles"); const { authorizeAndAuthenticate } = require("../middlewares/authorizeUsersAndService"); @@ -68,6 +67,6 @@ router.patch("/assign/self", authenticate, invalidateCache({ invalidationKeys: [ router.get("/users/discord", verifyCronJob, getUsersValidator, tasks.getUsersHandler); router.post("/migration", authenticate, authorizeRoles([SUPERUSER]), tasks.updateStatus); -router.post("/orphanTasks", verifyCronJob, filterOrphanTasksValidator, tasks.orphanTasks); +router.post("/orphanTasks", authenticate, authorizeRoles([SUPERUSER]), tasks.orphanTasks); module.exports = router; diff --git a/test/integration/tasks.test.js b/test/integration/tasks.test.js index 12f0b0f44..ef3cee88f 100644 --- a/test/integration/tasks.test.js +++ b/test/integration/tasks.test.js @@ -1573,41 +1573,41 @@ describe("Tasks", function () { }); describe("POST /tasks/orphanTasks", function () { - let jwtToken; - beforeEach(async function () { + const superUserId = await addUser(superUser); + superUserJwt = authService.generateAuthToken({ userId: superUserId }); const user1 = userData[6]; user1.roles.in_discord = false; user1.updated_at = 1712053284000; const user2 = userData[18]; - user2.updated_at = 1712064084000; + user2.roles.in_discord = false; const [{ id: userId }, { id: userId2 }] = await Promise.all([userDBModel.add(user1), userDBModel.add(user2)]); const task1 = { - assigneeId: userId, + assignee: userId, status: "ACTIVE", }; const task2 = { - assigneeId: userId2, + assignee: userId2, status: "COMPLETED", }; const task3 = { - assigneeId: userId2, + assignee: userId2, status: "IN_PROGRESS", }; - await Promise.all([tasksModel.add(task1), tasksModel.add(task2), tasksModel.add(task3)]); - - jwtToken = generateCronJobToken({ name: CRON_JOB_HANDLER }); + const task4 = { + assignee: userId, + status: "DONE", + }; + await Promise.all([tasksModel.add(task1), tasksModel.add(task2), tasksModel.add(task3), tasksModel.add(task4)]); }); afterEach(async function () { await cleanDb(); }); - it("Should update status of orphan tasks to BACKLOG", async function () { - const res = await chai.request(app).post("/tasks/orphanTasks").set("Authorization", `Bearer ${jwtToken}`).send({ - lastOrphanTasksFilterationTimestamp: 1712040715000, - }); + it("Should update status of orphan tasks to BACKLOG", async function () { + const res = await chai.request(app).post("/tasks/orphanTasks").set("cookie", `${cookieName}=${superUserJwt}`); expect(res).to.have.status(200); expect(res.body).to.deep.equal({ message: "Orphan tasks filtered successfully", @@ -1615,24 +1615,18 @@ describe("Tasks", function () { orphanTasksUpdatedCount: 2, }, }); - }).timeout(10000); + }); - it("Should return 400 if not cron worker", async function () { + it("Should return 400 if not super user", async function () { const nonSuperUserId = await addUser(appOwner); const nonSuperUserJwt = authService.generateAuthToken({ userId: nonSuperUserId }); - const res = await chai - .request(app) - .post("/tasks/orphanTasks") - .set("Authorization", `Bearer ${nonSuperUserJwt}`) - .send({ - lastOrphanTasksFilterationTimestamp: 1712040715000, - }); + const res = await chai.request(app).post("/tasks/orphanTasks").set("Authorization", `Bearer ${nonSuperUserJwt}`); - expect(res).to.have.status(400); + expect(res).to.have.status(401); expect(res.body).to.deep.equal({ - statusCode: 400, - error: "Bad Request", - message: "Unauthorized Cron Worker", + statusCode: 401, + error: "Unauthorized", + message: "You are not authorized for this action.", }); }); });