Skip to content

Commit aef3ea3

Browse files
committed
Merge branch 'develop' of https://github.com/ravikumar1002/website-backend into feat/github-created-at
2 parents b1abccb + 3475f19 commit aef3ea3

20 files changed

+556
-113
lines changed

controllers/tasks.js

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const { transformQuery } = require("../utils/tasks");
1111
const { getPaginatedLink } = require("../utils/helper");
1212
const { updateUserStatusOnTaskUpdate, updateStatusOnTaskCompletion } = require("../models/userStatus");
1313
const dataAccess = require("../services/dataAccessLayer");
14+
const { parseSearchQuery } = require("../utils/tasks");
1415
/**
1516
* Creates new task
1617
*
@@ -20,9 +21,6 @@ const dataAccess = require("../services/dataAccessLayer");
2021
*/
2122
const addNewTask = async (req, res) => {
2223
try {
23-
// userStatusFlag is the Feature flag for status update based on task status. This flag is temporary and will be removed once the feature becomes stable.
24-
const { userStatusFlag } = req.query;
25-
const isUserStatusEnabled = userStatusFlag === "true";
2624
const { id: createdBy } = req.userData;
2725
const dependsOn = req.body.dependsOn;
2826
let userStatusUpdate;
@@ -37,7 +35,7 @@ const addNewTask = async (req, res) => {
3735
dependsOn,
3836
};
3937
const taskDependency = dependsOn && (await dependencyModel.addDependency(data));
40-
if (isUserStatusEnabled && req.body.assignee) {
38+
if (req.body.assignee) {
4139
userStatusUpdate = await updateUserStatusOnTaskUpdate(req.body.assignee);
4240
}
4341
return res.json({
@@ -128,7 +126,7 @@ const fetchPaginatedTasks = async (query) => {
128126

129127
const fetchTasks = async (req, res) => {
130128
try {
131-
const { dev, status, page, size, prev, next } = req.query;
129+
const { dev, status, page, size, prev, next, q: queryString } = req.query;
132130
const transformedQuery = transformQuery(dev, status, size, page);
133131

134132
if (dev) {
@@ -139,12 +137,39 @@ const fetchTasks = async (req, res) => {
139137
});
140138
}
141139

140+
if (queryString !== undefined) {
141+
const searchParams = parseSearchQuery(queryString);
142+
if (!searchParams.searchTerm) {
143+
return res.status(404).json({
144+
message: "No tasks found.",
145+
tasks: [],
146+
});
147+
}
148+
const filterTasks = await tasks.fetchTasks(searchParams.searchTerm);
149+
const tasksWithRdsAssigneeInfo = await fetchTasksWithRdsAssigneeInfo(filterTasks);
150+
if (tasksWithRdsAssigneeInfo.length === 0) {
151+
return res.status(404).json({
152+
message: "No tasks found.",
153+
tasks: [],
154+
});
155+
}
156+
return res.json({
157+
message: "Filter tasks returned successfully!",
158+
tasks: tasksWithRdsAssigneeInfo,
159+
});
160+
}
161+
142162
const allTasks = await tasks.fetchTasks();
143163
const tasksWithRdsAssigneeInfo = await fetchTasksWithRdsAssigneeInfo(allTasks);
144-
164+
if (tasksWithRdsAssigneeInfo.length === 0) {
165+
return res.status(404).json({
166+
message: "No tasks found",
167+
tasks: [],
168+
});
169+
}
145170
return res.json({
146171
message: "Tasks returned successfully!",
147-
tasks: tasksWithRdsAssigneeInfo.length > 0 ? tasksWithRdsAssigneeInfo : [],
172+
tasks: tasksWithRdsAssigneeInfo,
148173
});
149174
} catch (err) {
150175
logger.error(`Error while fetching tasks ${err}`);
@@ -241,9 +266,6 @@ const getTask = async (req, res) => {
241266
*/
242267
const updateTask = async (req, res) => {
243268
try {
244-
// userStatusFlag is the Feature flag for status update based on task status. This flag is temporary and will be removed once the feature becomes stable.
245-
const { userStatusFlag } = req.query;
246-
const isUserStatusEnabled = userStatusFlag === "true";
247269
const task = await tasks.fetchTask(req.params.id);
248270
if (!task.taskData) {
249271
return res.boom.notFound("Task not found");
@@ -255,15 +277,14 @@ const updateTask = async (req, res) => {
255277
}
256278
}
257279
await tasks.updateTask(req.body, req.params.id);
258-
if (isUserStatusEnabled && req.body.assignee) {
280+
if (req.body.assignee) {
259281
// New Assignee Status Update
260282
await updateUserStatusOnTaskUpdate(req.body.assignee);
261283
// Old Assignee Status Update if available
262284
if (task.taskData.assigneeId) {
263285
await updateStatusOnTaskCompletion(task.taskData.assigneeId);
264286
}
265287
}
266-
267288
return res.status(204).send();
268289
} catch (err) {
269290
if (err.message.includes("Invalid dependency passed")) {
@@ -283,9 +304,6 @@ const updateTask = async (req, res) => {
283304
*/
284305
const updateTaskStatus = async (req, res, next) => {
285306
try {
286-
// userStatusFlag is the Feature flag for status update based on task status. This flag is temporary and will be removed once the feature becomes stable.
287-
const { userStatusFlag } = req.query;
288-
const isUserStatusEnabled = userStatusFlag === "true";
289307
let userStatusUpdate;
290308
const taskId = req.params.id;
291309
const { dev } = req.query;
@@ -346,7 +364,7 @@ const updateTaskStatus = async (req, res, next) => {
346364
}
347365
}
348366

349-
if (isUserStatusEnabled && req.body.status) {
367+
if (req.body.status) {
350368
userStatusUpdate = await updateStatusOnTaskCompletion(userId);
351369
}
352370
return res.json({

controllers/tasksRequests.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ const fetchTaskRequests = async (_, res) => {
66
try {
77
const data = await taskRequestsModel.fetchTaskRequests();
88

9-
if (data || data.length > 0) {
10-
res.status(200).json({
9+
if (data.length > 0) {
10+
return res.status(200).json({
1111
message: "Task requests returned successfully",
1212
data,
1313
});
@@ -23,6 +23,26 @@ const fetchTaskRequests = async (_, res) => {
2323
}
2424
};
2525

26+
const fetchTaskRequestById = async (req, res) => {
27+
try {
28+
const id = req.params.id;
29+
const data = await taskRequestsModel.fetchTaskRequestById(id);
30+
31+
if (!data.taskRequestExists) {
32+
return res.status(404).json({
33+
message: "Task request not found",
34+
});
35+
}
36+
return res.status(200).json({
37+
message: "Task request returned successfully",
38+
data: data.taskRequestData,
39+
});
40+
} catch (err) {
41+
logger.error("Error while fetching task requests", err);
42+
return res.boom.badImplementation(INTERNAL_SERVER_ERROR);
43+
}
44+
};
45+
2646
const addOrUpdate = async (req, res) => {
2747
try {
2848
const { taskId, userId } = req.body;
@@ -81,4 +101,5 @@ module.exports = {
81101
approveTaskRequest,
82102
addOrUpdate,
83103
fetchTaskRequests,
104+
fetchTaskRequestById,
84105
};

middlewares/validators/tasks.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,19 @@ const getTasksValidator = async (req, res, next) => {
164164
})
165165
),
166166
size: joi.number().integer().positive().min(1).max(100).optional(),
167+
q: joi
168+
.string()
169+
.optional()
170+
.custom((value, helpers) => {
171+
if (value && value.includes(":")) {
172+
const [key] = value.split(":");
173+
const allowedKeywords = ["searchterm"];
174+
if (!allowedKeywords.includes(key.toLowerCase())) {
175+
return helpers.error("any.invalid");
176+
}
177+
}
178+
return value;
179+
}, "Invalid query format"),
167180
});
168181

169182
try {

middlewares/validators/user.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ const updateUser = async (req, res, next) => {
3939
.valid(...Object.values(USER_STATUS))
4040
.optional(),
4141
discordId: joi.string().optional(),
42+
roles: joi.object().keys({
43+
archived: joi.boolean().required(),
44+
in_discord: joi.boolean().required(),
45+
developer: joi.boolean().optional(),
46+
designer: joi.boolean().optional(),
47+
maven: joi.boolean().optional(),
48+
productmanager: joi.boolean().optional(),
49+
}),
4250
});
4351

4452
try {

middlewares/validators/userStatus.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,7 @@ const { userState, CANCEL_OOO } = require("../../constants/userStatus");
33
const threeDaysInMilliseconds = 172800000;
44

55
const validateUserStatusData = async (todaysTime, req, res, next) => {
6-
// userStatusFlag is the Feature flag for status update based on task status. This flag is temporary and will be removed once the feature becomes stable.
7-
const { userStatusFlag } = req.query;
8-
const isUserStatusEnabled = userStatusFlag === "true";
9-
let validUserStates = [userState.OOO, userState.ONBOARDING, userState.IDLE, userState.ACTIVE];
10-
11-
if (isUserStatusEnabled) {
12-
validUserStates = [userState.OOO, userState.ONBOARDING];
13-
}
6+
const validUserStates = [userState.OOO, userState.ONBOARDING];
147

158
const statusSchema = Joi.object({
169
currentStatus: Joi.object().keys({

models/taskRequests.js

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,66 @@ const userModel = require("./users");
1313
const fetchTaskRequests = async () => {
1414
const taskRequests = [];
1515

16-
const taskRequestsSnapshots = (await taskRequestsCollection.get()).docs;
16+
try {
17+
const taskRequestsSnapshots = (await taskRequestsCollection.get()).docs;
1718

18-
const taskPromises = [];
19-
const userPromises = [];
19+
const taskPromises = [];
20+
const userPromises = [];
2021

21-
taskRequestsSnapshots.forEach((taskRequestsSnapshot) => {
22-
const taskRequestData = taskRequestsSnapshot.data();
23-
const { requestors } = taskRequestData;
22+
taskRequestsSnapshots.forEach((taskRequestsSnapshot) => {
23+
const taskRequestData = taskRequestsSnapshot.data();
24+
taskRequestData.id = taskRequestsSnapshot.id;
25+
taskRequestData.url = new URL(`/taskRequests/${taskRequestData.id}`, config.get("services.rdsUi.baseUrl"));
26+
const { requestors } = taskRequestData;
2427

25-
taskPromises.push(tasksModel.fetchTask(taskRequestData.taskId));
26-
userPromises.push(Promise.all(requestors.map((requestor) => userModel.fetchUser({ userId: requestor }))));
28+
taskPromises.push(tasksModel.fetchTask(taskRequestData.taskId));
29+
userPromises.push(Promise.all(requestors.map((requestor) => userModel.fetchUser({ userId: requestor }))));
2730

28-
taskRequests.push(taskRequestData);
29-
});
31+
taskRequests.push(taskRequestData);
32+
});
3033

31-
const tasks = await Promise.all(taskPromises);
32-
const users = await Promise.all(userPromises);
34+
const tasks = await Promise.all(taskPromises);
35+
const users = await Promise.all(userPromises);
3336

34-
taskRequests.forEach((taskRequest, index) => {
35-
taskRequest.task = tasks[+index].taskData;
36-
taskRequest.requestors = users[+index];
37-
});
37+
taskRequests.forEach((taskRequest, index) => {
38+
taskRequest.task = tasks[+index].taskData;
39+
taskRequest.requestors = users[+index];
40+
});
41+
} catch (err) {
42+
logger.error("Error in updating task", err);
43+
}
3844

3945
return taskRequests;
4046
};
4147

48+
/**
49+
* Fetches task request by id
50+
*
51+
* @param taskRequestId { string }: id of task request
52+
* @return Promise<{taskRequest: Object}>
53+
*/
54+
const fetchTaskRequestById = async (taskRequestId) => {
55+
try {
56+
const taskRequestSnapshot = await taskRequestsCollection.doc(taskRequestId).get();
57+
const taskRequestData = taskRequestSnapshot.data();
58+
59+
if (taskRequestData) {
60+
taskRequestData.id = taskRequestSnapshot.id;
61+
taskRequestData.url = new URL(`/taskRequests/${taskRequestData.id}`, config.get("services.rdsUi.baseUrl"));
62+
}
63+
return {
64+
taskRequestData,
65+
taskRequestExists: true,
66+
};
67+
} catch (err) {
68+
logger.error("Error in updating task", err);
69+
}
70+
71+
return {
72+
taskRequestExists: false,
73+
};
74+
};
75+
4276
/**
4377
* Creates a task request
4478
*
@@ -73,11 +107,12 @@ const addOrUpdate = async (taskId, userId) => {
73107
taskId,
74108
};
75109

76-
await taskRequestsCollection.add(newTaskRequest);
110+
const newTaskRequestRef = await taskRequestsCollection.add(newTaskRequest);
77111

78112
return {
79113
isCreate: true,
80114
taskRequest: newTaskRequest,
115+
id: newTaskRequestRef.id,
81116
};
82117
} catch (err) {
83118
logger.error("Error in updating task", err);
@@ -117,6 +152,7 @@ const approveTaskRequest = async (taskRequestId, user) => {
117152

118153
module.exports = {
119154
fetchTaskRequests,
155+
fetchTaskRequestById,
120156
addOrUpdate,
121157
approveTaskRequest,
122158
};

models/tasks.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,14 @@ const addDependency = async (data) => {
9696
* @return {Promise<tasks|Array>}
9797
*/
9898

99-
const getBuiltTasks = async (tasksSnapshot) => {
99+
const getBuiltTasks = async (tasksSnapshot, searchTerm) => {
100100
const tasks = buildTasks(tasksSnapshot);
101101
const promises = tasks.map(async (task) => fromFirestoreData(task));
102-
const updatedTasks = await Promise.all(promises);
102+
let updatedTasks = await Promise.all(promises);
103+
104+
if (searchTerm) {
105+
updatedTasks = updatedTasks.filter((task) => task.title.toLowerCase().includes(searchTerm.toLowerCase()));
106+
}
103107
const taskPromises = updatedTasks.map(async (task) => {
104108
task.status = TASK_STATUS[task.status.toUpperCase()] || task.status;
105109
const taskId = task.id;
@@ -159,10 +163,10 @@ const fetchPaginatedTasks = async ({ status = "", size = TASK_SIZE, page, next,
159163
}
160164
};
161165

162-
const fetchTasks = async () => {
166+
const fetchTasks = async (searchTerm) => {
163167
try {
164168
const tasksSnapshot = await tasksModel.get();
165-
const taskList = await getBuiltTasks(tasksSnapshot);
169+
const taskList = await getBuiltTasks(tasksSnapshot, searchTerm);
166170
return taskList;
167171
} catch (err) {
168172
logger.error("error getting tasks", err);
@@ -469,4 +473,5 @@ module.exports = {
469473
addDependency,
470474
fetchTaskByIssueId,
471475
fetchPaginatedTasks,
476+
getBuiltTasks,
472477
};

routes/taskRequests.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const { cacheResponse } = require("../utils/cache");
88
const { validateUser } = require("../middlewares/taskRequests");
99

1010
router.get("/", authenticate, authorizeRoles([SUPERUSER]), cacheResponse(), taskRequests.fetchTaskRequests);
11+
router.get("/:id", authenticate, authorizeRoles([SUPERUSER]), taskRequests.fetchTaskRequestById);
1112
router.post("/addOrUpdate", authenticate, validateUser, taskRequests.addOrUpdate);
1213
router.patch("/approve", authenticate, authorizeRoles([SUPERUSER]), validateUser, taskRequests.approveTaskRequest);
1314

routes/users.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ router.get("/self", authenticate, users.getSelfDetails);
1919
router.get("/isUsernameAvailable/:username", authenticate, users.getUsernameAvailabilty);
2020
router.get("/chaincode", authenticate, users.generateChaincode);
2121
router.get("/search", userValidator.validateUserQueryParams, users.filterUsers);
22-
router.patch("/remove-tokens", authenticate, authorizeRoles([SUPERUSER]), users.removeTokens);
22+
router.post("/tokens", authenticate, authorizeRoles([SUPERUSER]), users.removeTokens);
2323

2424
router.get("/:username", users.getUser);
2525
router.get("/:userId/intro", authenticate, authorizeRoles([SUPERUSER]), users.getUserIntro);

0 commit comments

Comments
 (0)