Skip to content

Commit 5b524ca

Browse files
Merge pull request #2225 from OneCommunityGlobal/Sayali-Fix-AllTime-Members-Backend
Sayali: add projectHistory tracking and getAllTimeprojectMembership endpoint
2 parents 582873e + 7b460bb commit 5b524ca

5 files changed

Lines changed: 69 additions & 5 deletions

File tree

src/controllers/projectController.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const timeentry = require('../models/timeentry');
55
const task = require('../models/task');
66
const wbs = require('../models/wbs');
77
const userProfile = require('../models/userProfile');
8-
// const { hasPermission } = require('../utilities/permissions');
8+
const { hasPermission } = require('../utilities/permissions');
99
const helper = require('../utilities/permissions');
1010
const escapeRegex = require('../utilities/escapeRegex');
1111
const logger = require('../startup/logger');
@@ -492,7 +492,6 @@ const projectController = function (Project) {
492492
*/
493493
const getprojectMembership = async function (req, res) {
494494
try {
495-
// GETs usually have no body; prefer req.user populated by your auth middleware.
496495
const requestor =
497496
(req.user && (req.user._id || req.user.id)) || req.query?.requestor || req.body?.requestor;
498497

@@ -514,7 +513,7 @@ const projectController = function (Project) {
514513

515514
const results = await userProfile
516515
.find(
517-
{ projects: projectId },
516+
{ projects: mongoose.Types.ObjectId(projectId) },
518517
{ firstName: 1, lastName: 1, profilePic: 1, _id: 1, isActive: 1 },
519518
)
520519
.sort({ firstName: 1, lastName: 1 });
@@ -525,6 +524,32 @@ const projectController = function (Project) {
525524
return res.status(500).send('Error fetching project members');
526525
}
527526
};
527+
const getAllTimeprojectMembership = async function (req, res) {
528+
const { projectId } = req.params;
529+
if (!mongoose.Types.ObjectId.isValid(projectId)) {
530+
res.status(400).send('Invalid request');
531+
return;
532+
}
533+
const requestor =
534+
(req.user && (req.user._id || req.user.id)) || req.query?.requestor || req.body?.requestor;
535+
const getProjMembers = await hasPermission(requestor, 'getProjectMembers');
536+
const postTask = await hasPermission(requestor, 'postTask');
537+
const updateTask = await hasPermission(requestor, 'updateTask');
538+
const suggestTask = await hasPermission(requestor, 'suggestTask');
539+
const getId = getProjMembers || postTask || updateTask || suggestTask;
540+
userProfile
541+
.find(
542+
{ projectHistory: projectId },
543+
{ firstName: 1, lastName: 1, isActive: 1, profilePic: 1, _id: getId },
544+
)
545+
.sort({ firstName: 1, lastName: 1 })
546+
.then((results) => {
547+
res.status(200).send(results);
548+
})
549+
.catch((error) => {
550+
res.status(500).send(error);
551+
});
552+
};
528553

529554
/**
530555
* Get project members summary (fast version)
@@ -555,7 +580,6 @@ const projectController = function (Project) {
555580
res.status(200).json(results);
556581
})
557582
.catch((error) => {
558-
console.error('Summary query error:', error);
559583
res.status(500).send(error);
560584
});
561585
};
@@ -667,6 +691,7 @@ const projectController = function (Project) {
667691
getprojectMembershipSummary,
668692
searchProjectMembers,
669693
getProjectsWithActiveUserCounts,
694+
getAllTimeprojectMembership,
670695
};
671696
};
672697

src/controllers/userProfileController.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,18 @@ const createControllerMethods = function (UserProfile, Project, cache) {
501501

502502
const addedProjects = newProjects.filter((id) => !oldProjects.includes(id));
503503
const removedProjects = oldProjects.filter((id) => !newProjects.includes(id));
504+
// update the projects history
505+
const changedProjectHistoryIds = Array.from(new Set(oldProjects.concat(newProjects))).map(
506+
(id) => mongoose.Types.ObjectId(id),
507+
);
508+
509+
const existingProjectIds = new Set(record.projectHistory.map((id) => id.toString()));
510+
511+
const newProjectIds = changedProjectHistoryIds.filter(
512+
(id) => !existingProjectIds.has(id.toString()),
513+
);
514+
515+
record.projectHistory.push(...newProjectIds);
504516
const changedProjectIds = [...addedProjects, ...removedProjects].map((id) =>
505517
mongoose.Types.ObjectId(id),
506518
);
@@ -2857,6 +2869,25 @@ const createControllerMethods = function (UserProfile, Project, cache) {
28572869
return res.status(500).send({ error: 'Internal server error' });
28582870
}
28592871
};
2872+
const getProjectHistory = async function (req, res) {
2873+
try {
2874+
const { userId } = req.params;
2875+
const user = await UserProfile.findById(userId);
2876+
const projectHistory = [...user.projectHistory];
2877+
res.status(200).send(projectHistory);
2878+
} catch (error) {
2879+
res.status(500).send(error);
2880+
}
2881+
};
2882+
2883+
const postClearProjectHistory = async function (req, res) {
2884+
try {
2885+
const result = await UserProfile.updateMany({}, { $set: { projectHistory: [] } });
2886+
res.status(200).send({ message: 'Project history cleared for all users', result });
2887+
} catch (error) {
2888+
res.status(500).send({ message: 'Error clearing project history', error });
2889+
}
2890+
};
28602891

28612892
const getAllMembersSkillsAndContact = async function (req, res) {
28622893
try {
@@ -3068,6 +3099,8 @@ const createControllerMethods = function (UserProfile, Project, cache) {
30683099
updateProfileImageFromWebsite,
30693100
getUserByAutocomplete,
30703101
getUserProfileBasicInfo,
3102+
getProjectHistory,
3103+
postClearProjectHistory,
30713104
updateUserInformation,
30723105
getAllMembersSkillsAndContact,
30733106
replaceTeamCodeForUsers,

src/models/userProfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ const userProfileSchema = new Schema({
104104
personalLinks: [{ _id: Schema.Types.ObjectId, Name: String, Link: { type: String } }],
105105
adminLinks: [{ _id: Schema.Types.ObjectId, Name: String, Link: String }],
106106
teams: [{ type: mongoose.SchemaTypes.ObjectId, ref: 'team' }],
107-
projects: [{ type: mongoose.SchemaTypes.ObjectId, ref: 'project' }],
107+
projectHistory: [{ type: mongoose.SchemaTypes.ObjectId, ref: 'project' }],
108108
badgeCollection: [
109109
{
110110
badge: { type: mongoose.SchemaTypes.ObjectId, ref: 'badge' },

src/routes/projectRouter.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ const routes = function (project) {
2525
.post(controller.assignProjectToUsers)
2626
.get(controller.getprojectMembership);
2727

28+
projectRouter
29+
.route('/project/:projectId/alltimeusers/')
30+
.get(controller.getAllTimeprojectMembership);
31+
2832
projectRouter
2933
.route('/project/:projectId/users/summary')
3034
.get(controller.getprojectMembershipSummary);

src/routes/userProfileRouter.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const routes = function (userProfile, project) {
2929
.get(param('name').exists(), controller.searchUsersByName);
3030

3131
userProfileRouter.route('/userProfile/update').patch(controller.updateUserInformation);
32+
userProfileRouter.route('/userProfile/:userId/projectHistory/').get(controller.getProjectHistory);
33+
userProfileRouter.route('/clearAllProjectHistory/').post(controller.postClearProjectHistory);
3234
userProfileRouter.route('/userProfile/basicInfo').get(controller.getUserProfileBasicInfo);
3335

3436
// Endpoint to retrieve basic user profile information after verifying access permission based on the request source.

0 commit comments

Comments
 (0)