Skip to content

Commit fa8ca9c

Browse files
committed
Refactoring user controller into smaller functions based on query parameters
Signed-off-by: Prakhar Kumar <[email protected]>
1 parent 7552eb1 commit fa8ca9c

File tree

2 files changed

+223
-153
lines changed

2 files changed

+223
-153
lines changed

controllers/users.js

Lines changed: 67 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const { profileDiffStatus } = require("../constants/profileDiff");
1111
const { logType } = require("../constants/logs");
1212
const ROLES = require("../constants/roles");
1313
const dataAccess = require("../services/dataAccessLayer");
14-
const { isLastPRMergedWithinDays } = require("../services/githubService");
1514
const logger = require("../utils/logger");
1615
const { SOMETHING_WENT_WRONG, INTERNAL_SERVER_ERROR } = require("../constants/errorMessages");
1716
const { OVERDUE_TASKS } = require("../constants/users");
@@ -20,21 +19,20 @@ const { setInDiscordFalseScript, setUserDiscordNickname } = require("../services
2019
const { generateDiscordProfileImageUrl } = require("../utils/discord-actions");
2120
const { addRoleToUser, getDiscordMembers } = require("../services/discordService");
2221
const { fetchAllUsers } = require("../models/users");
23-
const { getOverdueTasks } = require("../models/tasks");
2422
const { getQualifiers } = require("../utils/helper");
2523
const { parseSearchQuery } = require("../utils/users");
2624
const { getFilteredPRsOrIssues } = require("../utils/pullRequests");
2725
const { getFilteredPaginationLink } = require("../utils/userStatus");
26+
const userUtils = require("../utils/users");
2827
const {
2928
USERS_PATCH_HANDLER_ACTIONS,
3029
USERS_PATCH_HANDLER_ERROR_MESSAGES,
3130
USERS_PATCH_HANDLER_SUCCESS_MESSAGES,
3231
} = require("../constants/users");
3332
const { addLog } = require("../models/logs");
34-
const { getUserStatus } = require("../models/userStatus");
3533
const config = require("config");
3634
const { generateUniqueUsername } = require("../services/users");
37-
const userService = require("../services/users");
35+
const { NotFound, BadRequest } = require("http-errors");
3836
const discordDeveloperRoleId = config.get("discordDeveloperRoleId");
3937
const usersCollection = firestore.collection("users");
4038

@@ -90,204 +88,121 @@ const getUserById = async (req, res) => {
9088
const getUsers = async (req, res) => {
9189
try {
9290
// getting user details by id if present.
93-
const { q, dev: devParam, query } = req.query;
91+
const reqQueryObject = req.query;
92+
const { q, dev: devParam, query, departed, id, profile: profileParam, discordId } = reqQueryObject;
93+
const userData = req.userData || {};
94+
95+
const profile = profileParam === "true";
96+
const isDeparted = departed === "true";
9497
const dev = devParam === "true";
9598
const queryString = (dev ? q : query) || "";
9699
const transformedQuery = parseSearchQuery(queryString);
100+
const { filterBy, days } = transformedQuery;
97101
const qualifiers = getQualifiers(queryString);
98102
// Should throw an error if the new query parameter is without feature flag
99103
if (q && !dev) {
100104
return res.boom.notFound("Route not found");
101105
}
102-
// getting user details by id if present.
103106

104-
if (req.query.id) {
105-
const id = req.query.id;
106-
let result, user;
107-
try {
108-
result = await dataAccess.retrieveUsers({ id: id });
109-
user = result.user;
110-
} catch (error) {
111-
logger.error(`Error while fetching user: ${error}`);
112-
return res.boom.serverUnavailable(SOMETHING_WENT_WRONG);
113-
}
114-
if (!result.userExists) {
115-
return res.boom.notFound("User doesn't exist");
107+
try {
108+
if (id) {
109+
const user = await userUtils.findUserById(id);
110+
return res.json({
111+
message: "User returned successfully!",
112+
user: user,
113+
});
116114
}
117-
return res.json({
118-
message: "User returned successfully!",
119-
user,
120-
});
121-
}
122115

123-
const profile = req.query.profile === "true";
124-
125-
if (profile) {
126-
if (!req.userData.id) {
127-
return res.boom.badRequest("User ID not provided.");
116+
if (profile) {
117+
return res.send(await userUtils.getUserByProfileData(userData));
128118
}
129119

130-
try {
131-
const result = await dataAccess.retrieveUsers({ id: req.userData.id });
132-
return res.send(result.user);
133-
} catch (error) {
134-
logger.error(`Error while fetching user: ${error}`);
135-
return res.boom.serverUnavailable(INTERNAL_SERVER_ERROR);
120+
if (!transformedQuery?.days && transformedQuery?.filterBy === "unmerged_prs") {
121+
return res.boom.badRequest(`Days is required for filterBy ${transformedQuery?.filterBy}`);
136122
}
137-
}
138-
139-
if (!transformedQuery?.days && transformedQuery?.filterBy === "unmerged_prs") {
140-
return res.boom.badRequest(`Days is required for filterBy ${transformedQuery?.filterBy}`);
141-
}
142-
143-
const { filterBy, days } = transformedQuery;
144-
if (filterBy === "unmerged_prs" && days) {
145-
try {
146-
const inDiscordUser = await dataAccess.retrieveUsersWithRole(ROLES.INDISCORD);
147-
const users = [];
148-
149-
for (const user of inDiscordUser) {
150-
const username = user.github_id;
151-
const isMerged = await isLastPRMergedWithinDays(username, days);
152-
if (!isMerged) {
153-
users.push(user.id);
154-
}
155-
}
156123

124+
if (filterBy === "unmerged_prs" && days) {
125+
const users = await userUtils.getUsersByUnmergedPrs(days);
157126
return res.json({
158127
message: "Inactive users returned successfully!",
159128
count: users.length,
160129
users: users,
161130
});
162-
} catch (error) {
163-
logger.error(`Error while fetching all users: ${error}`);
164-
return res.boom.serverUnavailable("Something went wrong please contact admin");
165131
}
166-
}
167132

168-
// getting user details by discord id if present.
169-
const discordId = req.query.discordId;
170-
171-
if (req.query.discordId) {
172-
if (dev) {
173-
let result, user;
174-
try {
175-
result = await dataAccess.retrieveUsers({ discordId });
176-
user = result.user;
177-
if (!result.userExists) {
178-
return res.json({
179-
message: "User not found",
180-
user: null,
181-
});
182-
}
183-
184-
const userStatusResult = await getUserStatus(user.id);
185-
if (userStatusResult.userStatusExists) {
186-
user.state = userStatusResult.data.currentStatus.state;
187-
}
188-
} catch (error) {
189-
logger.error(`Error while fetching user: ${error}`);
190-
return res.boom.serverUnavailable(INTERNAL_SERVER_ERROR);
133+
if (discordId) {
134+
if (dev) {
135+
const user = await userUtils.getUserByDiscordId(discordId);
136+
return res.json({
137+
message: user ? "User returned successfully!" : "User not found",
138+
user: user,
139+
});
140+
} else {
141+
return res.boom.notFound("Route not found");
191142
}
192-
return res.json({
193-
message: "User returned successfully!",
194-
user,
195-
});
196-
} else {
197-
return res.boom.notFound("Route not found");
198143
}
199-
}
200-
201-
const isDeparted = req.query.departed === "true";
202144

203-
if (isDeparted) {
204-
if (!dev) {
205-
return res.boom.notFound("Route not found");
206-
}
207-
try {
208-
const result = await dataAccess.retrieveUsers({ query: req.query });
209-
const departedUsers = await userService.getUsersWithIncompleteTasks(result.users);
145+
if (isDeparted) {
146+
if (!dev) {
147+
return res.boom.notFound("Route not found");
148+
}
149+
const { result, departedUsers } = await userUtils.getDepartedUsers(reqQueryObject);
210150
if (departedUsers.length === 0) return res.status(204).send();
211151
return res.json({
212152
message: "Users with abandoned tasks fetched successfully",
213153
users: departedUsers,
214154
links: {
215-
next: result.nextId ? getPaginationLink(req.query, "next", result.nextId) : "",
216-
prev: result.prevId ? getPaginationLink(req.query, "prev", result.prevId) : "",
155+
next: result.nextId ? getPaginationLink(reqQueryObject, "next", result.nextId) : "",
156+
prev: result.prevId ? getPaginationLink(reqQueryObject, "prev", result.prevId) : "",
217157
},
218158
});
219-
} catch (error) {
220-
logger.error("Error when fetching users who abandoned tasks:", error);
221-
return res.boom.badImplementation(INTERNAL_SERVER_ERROR);
222159
}
223-
}
224160

225-
if (transformedQuery?.filterBy === OVERDUE_TASKS) {
226-
try {
227-
const tasksData = await getOverdueTasks(days);
228-
if (!tasksData.length) {
161+
if (filterBy === OVERDUE_TASKS) {
162+
const users = await userUtils.getUsersByOverDueTasks(days, dev);
163+
if (!users || users.length === 0) {
229164
return res.json({
230165
message: "No users found",
231166
users: [],
232167
});
233168
}
234-
const userIds = new Set();
235-
const usersData = [];
236-
237-
tasksData.forEach((task) => {
238-
if (task.assignee) {
239-
userIds.add(task.assignee);
240-
}
241-
});
242-
243-
const userInfo = await dataAccess.retrieveUsers({ userIds: Array.from(userIds) });
244-
userInfo.forEach((user) => {
245-
if (!user.roles.archived) {
246-
const userTasks = tasksData.filter((task) => task.assignee === user.id);
247-
const userData = {
248-
id: user.id,
249-
discordId: user.discordId,
250-
username: user.username,
251-
};
252-
if (dev) {
253-
userData.tasks = userTasks;
254-
}
255-
usersData.push(userData);
256-
}
169+
return res.json({
170+
message: "Users returned successfully!",
171+
count: users.length,
172+
users: users,
257173
});
174+
}
258175

176+
if (qualifiers?.filterBy) {
177+
const allPRs = await getFilteredPRsOrIssues(qualifiers);
178+
const usernames = getUsernamesFromPRs(allPRs);
179+
const users = await dataAccess.retrieveUsers({ usernames: usernames });
259180
return res.json({
260181
message: "Users returned successfully!",
261-
count: usersData.length,
262-
users: usersData,
182+
users,
263183
});
264-
} catch (error) {
265-
const errorMessage = `Error while fetching users and tasks: ${error}`;
266-
logger.error(errorMessage);
267-
return res.boom.serverUnavailable("Something went wrong, please contact admin");
268184
}
269-
}
270185

271-
if (qualifiers?.filterBy) {
272-
const allPRs = await getFilteredPRsOrIssues(qualifiers);
273-
const usernames = getUsernamesFromPRs(allPRs);
274-
const users = await dataAccess.retrieveUsers({ usernames: usernames });
186+
const data = await dataAccess.retrieveUsers({ query: reqQueryObject });
187+
275188
return res.json({
276189
message: "Users returned successfully!",
277-
users,
190+
users: data.users,
191+
links: {
192+
next: data.nextId ? getPaginationLink(reqQueryObject, "next", data.nextId) : "",
193+
prev: data.prevId ? getPaginationLink(reqQueryObject, "prev", data.prevId) : "",
194+
},
278195
});
279-
}
280-
281-
const data = await dataAccess.retrieveUsers({ query: req.query });
196+
} catch (e) {
197+
if (e instanceof NotFound) {
198+
return res.boom.notFound(e.message);
199+
}
200+
if (e instanceof BadRequest) {
201+
return res.boom.BadRequest(e.message);
202+
}
282203

283-
return res.json({
284-
message: "Users returned successfully!",
285-
users: data.users,
286-
links: {
287-
next: data.nextId ? getPaginationLink(req.query, "next", data.nextId) : "",
288-
prev: data.prevId ? getPaginationLink(req.query, "prev", data.prevId) : "",
289-
},
290-
});
204+
return res.boom.serverUnavailable(SOMETHING_WENT_WRONG);
205+
}
291206
} catch (error) {
292207
logger.error(`Error while fetching all users: ${error}`);
293208
return res.boom.serverUnavailable(SOMETHING_WENT_WRONG);

0 commit comments

Comments
 (0)