shuttlepro-shared 1.2.70 → 1.2.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,578 +1,178 @@
1
- // const { UserRole } = require("../../models/UserRole");
2
- // const { getRedisData, setRedisData } = require("../../config/redis");
3
-
4
- // const defaultSelect =
5
- // "iconUrl thumbUrl name productsCount ordersCount contact email address websiteUrl facebookUrl twitterUrl instagramUrl members defaultModule";
6
-
7
- // // Cache keys
8
- // const CACHE_KEY_ALL_MEMBERS = "userroles_all_members";
9
-
10
- // const getCachedMembers = async (filter = {}) => {
11
- // try {
12
- // let members = await getRedisData(CACHE_KEY_ALL_MEMBERS);
13
-
14
- // if (!members) {
15
- // members = await UserRole.find()
16
- // .select("userId role userShift roleId workspaceId")
17
- // .populate({
18
- // path: "roleId",
19
- // select: "id name userId userShift permissionId modulePermissions",
20
- // populate: [{ path: "permissionId", select: "id name" }],
21
- // })
22
- // .populate({
23
- // path: "userId",
24
- // match: { isDeleted: false, suspended: false },
25
- // select: "firstName lastName role email picture userShift _id",
26
- // })
27
- // .lean()
28
- // .exec();
29
-
30
- // members = members?.filter((m) => m?.userId && m?.roleId) || [];
31
- // await setRedisData(CACHE_KEY_ALL_MEMBERS, members);
32
- // }
33
-
34
- // const userIdFilter = filter.userId
35
- // ? new Set(
36
- // Array.isArray(filter.userId)
37
- // ? filter.userId.map((id) => id.toString())
38
- // : [filter.userId.toString()]
39
- // )
40
- // : null;
41
-
42
- // const roleIdFilter = filter.roleId
43
- // ? Array.isArray(filter.roleId)
44
- // ? new Set(filter.roleId.map((id) => id.toString()))
45
- // : typeof filter.roleId === "object"
46
- // ? filter.roleId
47
- // : new Set([filter.roleId.toString()])
48
- // : null;
49
-
50
- // return members.filter((member) => {
51
- // // Optimize userId filter
52
- // if (userIdFilter && !userIdFilter.has(member.userId?._id?.toString())) {
53
- // return false;
54
- // }
55
-
56
- // // Optimize roleId filter
57
- // if (roleIdFilter) {
58
- // if (roleIdFilter instanceof Set) {
59
- // const roleIdStr =
60
- // member.roleId?._id?.toString() ?? member.roleId?.id?.toString();
61
- // if (!roleIdFilter.has(roleIdStr)) return false;
62
- // } else if (typeof roleIdFilter === "object") {
63
- // for (const [key, value] of Object.entries(roleIdFilter)) {
64
- // const roleVal = key.includes(".")
65
- // ? key.split(".").reduce((obj, k) => obj?.[k], member.roleId)
66
- // : member.roleId?.[key];
67
- // if (Array.isArray(value)) {
68
- // if (!value.includes(roleVal)) return false;
69
- // } else if (roleVal !== value) {
70
- // return false;
71
- // }
72
- // }
73
- // }
74
- // }
75
-
76
- // // General filters
77
- // for (const [key, value] of Object.entries(filter)) {
78
- // if (key === "userId" || key === "roleId") continue;
79
-
80
- // const memberValue = key.includes(".")
81
- // ? key.split(".").reduce((obj, prop) => obj?.[prop], member)
82
- // : member[key];
83
-
84
- // if (Array.isArray(value)) {
85
- // if (!value.includes(memberValue)) return false;
86
- // } else if (typeof value === "object" && value !== null) {
87
- // for (const [subKey, subVal] of Object.entries(value)) {
88
- // if (memberValue?.[subKey] !== subVal) return false;
89
- // }
90
- // } else {
91
- // if (memberValue !== value) return false;
92
- // }
93
- // }
94
-
95
- // return true;
96
- // });
97
- // } catch (error) {
98
- // console.error("Error fetching cached members:", error);
99
- // return [];
100
- // }
101
- // };
102
-
103
- // // Update the cache for all members
104
- // const updateCachedMembers = async (filter = {}) => {
105
- // try {
106
- // const members = await UserRole.find(filter)
107
- // .select("userId role userShift roleId")
108
- // .populate({
109
- // path: "roleId",
110
- // select: "id name userId userShift permissionId modulePermissions",
111
- // populate: [{ path: "permissionId", select: "id name" }],
112
- // })
113
- // .populate({
114
- // path: "userId",
115
- // match: { isDeleted: false, suspended: false },
116
- // select: "firstName lastName role email picture userShift",
117
- // })
118
- // .lean()
119
- // .exec();
120
-
121
- // const validMembers =
122
- // members?.filter((member) => member?.userId && member?.roleId) || [];
123
-
124
- // await setRedisData(CACHE_KEY_ALL_MEMBERS, validMembers);
125
-
126
- // return validMembers;
127
- // } catch (error) {
128
- // console.error("Error updating cached members:", error);
129
- // return [];
130
- // }
131
- // };
132
-
133
- // // Comprehensive cache update method
134
- // const updateAllRelatedCaches = async (userId, workspaceId) => {
135
- // try {
136
- // await updateCachedMembers();
137
- // } catch (error) {
138
- // console.error("Error updating related caches:", error);
139
- // }
140
- // };
141
-
142
- // // Find single user role by filter
143
- // const findSingleUserRoleByFilter = async (
144
- // filter = {},
145
- // populateOptions = {}
146
- // ) => {
147
- // const defaultPopulateOptions = {
148
- // rolePopulate: {
149
- // path: "roleId",
150
- // select: "id name userId userShift permissionId modulePermissions",
151
- // populate: [{ path: "permissionId", select: "id name" }],
152
- // },
153
- // userPopulate: {
154
- // path: "userId",
155
- // match: { isDeleted: false, suspended: false },
156
- // select: "firstName lastName role email picture userShift",
157
- // },
158
- // };
159
- // const mergedPopulateOptions = {
160
- // rolePopulate: {
161
- // ...defaultPopulateOptions.rolePopulate,
162
- // ...populateOptions.rolePopulate,
163
- // },
164
- // userPopulate: {
165
- // ...defaultPopulateOptions.userPopulate,
166
- // ...populateOptions.userPopulate,
167
- // },
168
- // };
169
- // return await UserRole.findOne(filter)
170
- // .populate(mergedPopulateOptions.rolePopulate)
171
- // .populate(mergedPopulateOptions.userPopulate)
172
- // .lean()
173
- // .exec();
174
- // };
175
-
176
- // const convertPermissionsArrayToObject = (originalArray) => {
177
- // return originalArray?.reduce((acc, item) => {
178
- // const { id, actions, integrationPermissions, ...extras } = item;
179
- // const formattedExtras = {};
180
- // if (extras.deletable !== undefined) {
181
- // formattedExtras.deletable = extras.deletable;
182
- // }
183
- // if (extras.createUpdateable !== undefined) {
184
- // formattedExtras.createUpdateable = extras.createUpdateable;
185
- // }
186
- // acc[id] = {
187
- // actions: Object.keys(actions).filter((action) => actions[action]),
188
- // ...formattedExtras,
189
- // ...(integrationPermissions && {
190
- // integrationPermissions: Object.entries(integrationPermissions)
191
- // .filter(([_, allowed]) => allowed)
192
- // .map(([key]) => key),
193
- // }),
194
- // };
195
- // return acc;
196
- // }, {});
197
- // };
198
-
199
- // const createUserRole = async (data) => {
200
- // const savedRole = await UserRole.create(data);
201
-
202
- // // Update all related caches
203
- // await updateAllRelatedCaches(
204
- // savedRole?.userId?.toString(),
205
- // savedRole?.workspaceId?.toString()
206
- // );
207
-
208
- // return savedRole;
209
- // };
210
-
211
- // const findOneAndUpdateUserRole = async ({
212
- // workspaceId,
213
- // userId,
214
- // userShift,
215
- // role,
216
- // }) => {
217
- // const updatedRole = await UserRole.findOneAndUpdate(
218
- // { workspaceId, userId },
219
- // { $set: { userShift, role } },
220
- // { new: true, upsert: false }
221
- // ).exec();
222
- // if (updatedRole) {
223
- // await updateAllRelatedCaches(userId, workspaceId);
224
- // }
225
- // return updatedRole;
226
- // };
227
-
228
- // const findUserRole = async (filter = {}) => {
229
- // return await getCachedMembers(filter);
230
- // };
231
-
232
- // const updateUserRole = async (id, data) => {
233
- // const updatedRole = await UserRole.findByIdAndUpdate(id, data, {
234
- // new: true,
235
- // }).exec();
236
- // if (updatedRole) {
237
- // await updateAllRelatedCaches(updatedRole.userId, updatedRole.workspaceId);
238
- // }
239
- // return updatedRole;
240
- // };
241
-
242
- // const deleteUserRoleByFilter = async (filter) => {
243
- // const roleToDelete = await UserRole.findOne(filter).exec();
244
- // const deletedRole = await UserRole.findOneAndDelete(filter).exec();
245
- // if (deletedRole) {
246
- // await updateAllRelatedCaches(
247
- // roleToDelete?.userId,
248
- // roleToDelete?.workspaceId
249
- // );
250
- // }
251
- // return deletedRole;
252
- // };
253
-
254
- // const deleteUserRole = async (id) => {
255
- // const role = await UserRole.findById(id).exec();
256
- // const userId = role?.userId;
257
- // const workspaceId = role?.workspaceId;
258
- // const deletedRole = await UserRole.findByIdAndDelete(id).exec();
259
- // if (deletedRole) {
260
- // await updateAllRelatedCaches(userId, workspaceId);
261
- // }
262
- // return deletedRole;
263
- // };
264
-
265
- // const findUserWorkspaces = async (userId) => {
266
- // let userRoleWithWorkspaces = await UserRole.find({ userId: userId })
267
- // .select("userId roleId workspaceId")
268
- // .populate({
269
- // path: "roleId",
270
- // select: "id name userId userShift permissionId modulePermissions",
271
- // populate: [{ path: "permissionId", select: "id name" }],
272
- // })
273
- // .populate({
274
- // path: "workspaceId",
275
- // select: defaultSelect,
276
- // match: { isDeleted: false },
277
- // })
278
- // .lean()
279
- // .exec();
280
- // userRoleWithWorkspaces = userRoleWithWorkspaces
281
- // ?.filter((userRole) => userRole?.workspaceId)
282
- // ?.filter((userRole) => userRole?.roleId)
283
- // ?.map((ur) => {
284
- // return {
285
- // ...ur?.workspaceId,
286
- // id: ur?.workspaceId?._id?.toString(),
287
- // _id: ur?.workspaceId?._id?.toString(),
288
- // role: ur?.roleId?.name || "",
289
- // permissions: ur?.roleId?.modulePermissions?.modules || [],
290
- // };
291
- // });
292
- // return userRoleWithWorkspaces || [];
293
- // };
294
-
295
- // const getUserPermissions = async (workspaceId, userId) => {
296
- // try {
297
- // let members = await getCachedMembers({ workspaceId, userId });
298
- // console.log(members, "members");
299
- // if (members?.length) {
300
- // return (
301
- // convertPermissionsArrayToObject(
302
- // members?.[0]?.roleId?.modulePermissions?.modules
303
- // ) || null
304
- // );
305
- // }
306
- // return null;
307
- // } catch (err) {
308
- // console.error("Error in getUserPermissions:", err);
309
- // return null;
310
- // }
311
- // };
312
-
313
- // const getUserRoleWithPermissions = async (workspaceId, userId) => {
314
- // try {
315
- // let members = await getCachedMembers({ workspaceId, userId });
316
- // console.log(members, "members");
317
- // if (members?.length) {
318
- // let data = members?.[0];
319
- // const roleWithPermissions = {
320
- // ...data,
321
- // roleId: data?.roleId?._id?.toString() || "",
322
- // role: data?.roleId?.name || "",
323
- // permissions:
324
- // convertPermissionsArrayToObject(
325
- // data?.roleId?.modulePermissions?.modules
326
- // ) || [],
327
- // parentRole: data?.roleId?.permissionId?.name || "",
328
- // parentRoleId: data?.roleId?.permissionId?._id?.toString() || "",
329
- // defaultModule: data?.roleId?.defaultModule || "",
330
- // };
331
- // return roleWithPermissions || null;
332
- // }
333
- // return null;
334
- // } catch (err) {
335
- // console.error("Error in getUserRoleWithPermissions:", err);
336
- // return null;
337
- // }
338
- // };
339
-
340
- // const getChannelsPermissions = async (workspaceId, userId) => {
341
- // try {
342
- // let members = await getCachedMembers({ workspaceId, userId });
343
- // console.log(members, "members");
344
- // if (members?.length) {
345
- // let data = members?.[0];
346
- // return (
347
- // convertPermissionsArrayToObject(
348
- // data?.roleId?.modulePermissions?.modules
349
- // )?.["conversations"]?.["integrationPermissions"] || []
350
- // );
351
- // }
352
- // return [];
353
- // } catch (err) {
354
- // console.error("Error in getChannelsPermissions:", err);
355
- // return [];
356
- // }
357
- // };
358
-
359
- // module.exports = {
360
- // createUserRole,
361
- // findUserRole,
362
- // updateUserRole,
363
- // deleteUserRoleByFilter,
364
- // deleteUserRole,
365
- // findUserWorkspaces,
366
- // getUserRoleWithPermissions,
367
- // getUserPermissions,
368
- // getChannelsPermissions,
369
- // findOneAndUpdateUserRole,
370
- // findSingleUserRoleByFilter,
371
- // getCachedMembers,
372
- // updateCachedMembers,
373
- // };
374
-
375
1
  const { UserRole } = require("../../models/UserRole");
376
2
  const { getRedisData, setRedisData } = require("../../config/redis");
377
3
 
378
- // Default selection and population configurations
379
- const DEFAULT_USER_ROLE_CONFIG = {
380
- select: {
381
- userRole: "userId role userShift roleId workspaceId",
382
- role: "id name userId userShift permissionId modulePermissions",
383
- permission: "id name",
384
- user: "firstName lastName role email picture userShift _id",
385
- },
386
- match: {
387
- user: { isDeleted: false, suspended: false },
388
- },
389
- };
4
+ const defaultSelect =
5
+ "iconUrl thumbUrl name productsCount ordersCount contact email address websiteUrl facebookUrl twitterUrl instagramUrl members defaultModule";
390
6
 
391
- // Cache key constant
7
+ // Cache keys
392
8
  const CACHE_KEY_ALL_MEMBERS = "userroles_all_members";
393
9
 
394
- /**
395
- * Construct a flexible query builder for UserRole with advanced filtering and population
396
- * @param {Object} options - Query configuration options
397
- * @returns {Promise} Mongoose query result
398
- */
399
- const buildUserRoleQuery = async (options = {}) => {
400
- const {
401
- filter = {},
402
- select = {},
403
- populate = {},
404
- cacheKey = CACHE_KEY_ALL_MEMBERS,
405
- useCache = true,
406
- lean = true,
407
- } = options;
408
-
409
- // Merge default configurations with provided options
410
- const mergedSelect = {
411
- userRole: select.userRole || DEFAULT_USER_ROLE_CONFIG.select.userRole,
412
- role: select.role || DEFAULT_USER_ROLE_CONFIG.select.role,
413
- permission: select.permission || DEFAULT_USER_ROLE_CONFIG.select.permission,
414
- user: select.user || DEFAULT_USER_ROLE_CONFIG.select.user,
415
- };
416
-
417
- const mergedMatch = {
418
- user: {
419
- ...DEFAULT_USER_ROLE_CONFIG.match.user,
420
- ...(select.userMatch || {}),
421
- },
422
- };
423
-
424
- // Populate configuration with fallback defaults
425
- const populateConfig = [
426
- {
427
- path: "roleId",
428
- select: mergedSelect.role,
429
- populate: {
430
- path: "permissionId",
431
- select: mergedSelect.permission,
432
- },
433
- },
434
- {
435
- path: "userId",
436
- match: mergedMatch.user,
437
- select: mergedSelect.user,
438
- },
439
- ...(populate.additional || []),
440
- ];
441
-
10
+ const getCachedMembers = async (filter = {}) => {
442
11
  try {
443
- // Check cache first if useCache is true
444
- if (useCache) {
445
- let cachedData = await getRedisData(cacheKey);
446
-
447
- if (cachedData) {
448
- return applyAdvancedFiltering(cachedData, filter);
449
- }
12
+ let members = await getRedisData(CACHE_KEY_ALL_MEMBERS);
13
+
14
+ if (!members) {
15
+ members = await UserRole.find()
16
+ .select("userId role userShift roleId workspaceId")
17
+ .populate({
18
+ path: "roleId",
19
+ select: "id name userId userShift permissionId modulePermissions",
20
+ populate: [{ path: "permissionId", select: "id name" }],
21
+ })
22
+ .populate({
23
+ path: "userId",
24
+ match: { isDeleted: false, suspended: false },
25
+ select: "firstName lastName role email picture userShift _id",
26
+ })
27
+ .lean()
28
+ .exec();
29
+
30
+ members = members?.filter((m) => m?.userId && m?.roleId) || [];
31
+ await setRedisData(CACHE_KEY_ALL_MEMBERS, members);
450
32
  }
451
33
 
452
- // Construct base query
453
- let query = UserRole.find(filter).select(mergedSelect.userRole);
34
+ const userIdFilter = filter.userId
35
+ ? new Set(
36
+ Array.isArray(filter.userId)
37
+ ? filter.userId.map((id) => id.toString())
38
+ : [filter.userId.toString()]
39
+ )
40
+ : null;
454
41
 
455
- // Apply population
456
- populateConfig.forEach((config) => {
457
- query = query.populate(config);
458
- });
42
+ const roleIdFilter = filter.roleId
43
+ ? Array.isArray(filter.roleId)
44
+ ? new Set(filter.roleId.map((id) => id.toString()))
45
+ : typeof filter.roleId === "object"
46
+ ? filter.roleId
47
+ : new Set([filter.roleId.toString()])
48
+ : null;
459
49
 
460
- // Execute query
461
- const results = lean ? await query.lean().exec() : await query.exec();
50
+ return members.filter((member) => {
51
+ // Optimize userId filter
52
+ if (userIdFilter && !userIdFilter.has(member.userId?._id?.toString())) {
53
+ return false;
54
+ }
462
55
 
463
- // Filter out invalid entries and cache results
464
- const validResults = results.filter(
465
- (result) => result?.userId && result?.roleId
466
- );
56
+ // Optimize roleId filter
57
+ if (roleIdFilter) {
58
+ if (roleIdFilter instanceof Set) {
59
+ const roleIdStr =
60
+ member.roleId?._id?.toString() ?? member.roleId?.id?.toString();
61
+ if (!roleIdFilter.has(roleIdStr)) return false;
62
+ } else if (typeof roleIdFilter === "object") {
63
+ for (const [key, value] of Object.entries(roleIdFilter)) {
64
+ const roleVal = key.includes(".")
65
+ ? key.split(".").reduce((obj, k) => obj?.[k], member.roleId)
66
+ : member.roleId?.[key];
67
+ if (Array.isArray(value)) {
68
+ if (!value.includes(roleVal)) return false;
69
+ } else if (roleVal !== value) {
70
+ return false;
71
+ }
72
+ }
73
+ }
74
+ }
467
75
 
468
- // Cache results if useCache is true
469
- if (useCache) {
470
- await setRedisData(cacheKey, validResults);
471
- }
76
+ // General filters
77
+ for (const [key, value] of Object.entries(filter)) {
78
+ if (key === "userId" || key === "roleId") continue;
79
+
80
+ const memberValue = key.includes(".")
81
+ ? key.split(".").reduce((obj, prop) => obj?.[prop], member)
82
+ : member[key];
83
+
84
+ if (Array.isArray(value)) {
85
+ if (!value.includes(memberValue)) return false;
86
+ } else if (typeof value === "object" && value !== null) {
87
+ for (const [subKey, subVal] of Object.entries(value)) {
88
+ if (memberValue?.[subKey] !== subVal) return false;
89
+ }
90
+ } else {
91
+ if (memberValue !== value) return false;
92
+ }
93
+ }
472
94
 
473
- // Apply advanced filtering
474
- return applyAdvancedFiltering(validResults, filter);
95
+ return true;
96
+ });
475
97
  } catch (error) {
476
- console.error("Error in buildUserRoleQuery:", error);
98
+ console.error("Error fetching cached members:", error);
477
99
  return [];
478
100
  }
479
101
  };
480
102
 
481
- /**
482
- * Apply advanced filtering with nested property support
483
- * @param {Array} data - Data to filter
484
- * @param {Object} filter - Filter conditions
485
- * @returns {Array} Filtered results
486
- */
487
- const applyAdvancedFiltering = (data, filter = {}) => {
488
- if (!data || data.length === 0) return [];
489
-
490
- return data.filter((item) => {
491
- for (const [key, value] of Object.entries(filter)) {
492
- // Skip special filtering keys
493
- if (key === "userId" || key === "roleId") continue;
494
-
495
- // Handle nested property access
496
- const itemValue = key.includes(".")
497
- ? key.split(".").reduce((obj, prop) => obj?.[prop], item)
498
- : item[key];
499
-
500
- // Complex filtering logic
501
- if (Array.isArray(value)) {
502
- if (!value.includes(itemValue)) return false;
503
- } else if (typeof value === "object" && value !== null) {
504
- for (const [subKey, subVal] of Object.entries(value)) {
505
- if (itemValue?.[subKey] !== subVal) return false;
506
- }
507
- } else {
508
- if (itemValue !== value) return false;
509
- }
510
- }
511
- return true;
512
- });
513
- };
514
-
515
- /**
516
- * Wrapper functions using the new query builder
517
- */
518
- const getCachedMembers = async (filter = {}) => buildUserRoleQuery({ filter });
519
-
520
- const findUserRole = async (filter = {}) => buildUserRoleQuery({ filter });
521
-
522
- const updateCachedMembers = async (filter = {}) =>
523
- buildUserRoleQuery({
524
- filter,
525
- cacheKey: CACHE_KEY_ALL_MEMBERS,
526
- });
527
-
528
- const findSingleUserRoleByFilter = async (filter = {}, options = {}) => {
529
- const results = await buildUserRoleQuery({
530
- filter,
531
- ...options,
532
- });
533
- return results[0] || null;
534
- };
535
-
536
- const getUserPermissions = async (workspaceId, userId) => {
103
+ // Update the cache for all members
104
+ const updateCachedMembers = async (filter = {}) => {
537
105
  try {
538
- const members = await getCachedMembers({ workspaceId, userId });
539
- return members?.[0]?.roleId?.modulePermissions?.modules
540
- ? convertPermissionsArrayToObject(
541
- members[0].roleId.modulePermissions.modules
542
- )
543
- : null;
544
- } catch (err) {
545
- console.error("Error in getUserPermissions:", err);
546
- return null;
106
+ const members = await UserRole.find(filter)
107
+ .select("userId role userShift roleId")
108
+ .populate({
109
+ path: "roleId",
110
+ select: "id name userId userShift permissionId modulePermissions",
111
+ populate: [{ path: "permissionId", select: "id name" }],
112
+ })
113
+ .populate({
114
+ path: "userId",
115
+ match: { isDeleted: false, suspended: false },
116
+ select: "firstName lastName role email picture userShift",
117
+ })
118
+ .lean()
119
+ .exec();
120
+
121
+ const validMembers =
122
+ members?.filter((member) => member?.userId && member?.roleId) || [];
123
+
124
+ await setRedisData(CACHE_KEY_ALL_MEMBERS, validMembers);
125
+
126
+ return validMembers;
127
+ } catch (error) {
128
+ console.error("Error updating cached members:", error);
129
+ return [];
547
130
  }
548
131
  };
549
132
 
550
- const getUserRoleWithPermissions = async (workspaceId, userId) => {
133
+ // Comprehensive cache update method
134
+ const updateAllRelatedCaches = async (userId, workspaceId) => {
551
135
  try {
552
- const members = await getCachedMembers({ workspaceId, userId });
553
- if (members?.length) {
554
- const data = members[0];
555
- return {
556
- ...data,
557
- roleId: data?.roleId?._id?.toString() || "",
558
- role: data?.roleId?.name || "",
559
- permissions:
560
- convertPermissionsArrayToObject(
561
- data?.roleId?.modulePermissions?.modules
562
- ) || [],
563
- parentRole: data?.roleId?.permissionId?.name || "",
564
- parentRoleId: data?.roleId?.permissionId?._id?.toString() || "",
565
- defaultModule: data?.roleId?.defaultModule || "",
566
- };
567
- }
568
- return null;
569
- } catch (err) {
570
- console.error("Error in getUserRoleWithPermissions:", err);
571
- return null;
136
+ await updateCachedMembers();
137
+ } catch (error) {
138
+ console.error("Error updating related caches:", error);
572
139
  }
573
140
  };
574
141
 
575
- // Existing utility function
142
+ // Find single user role by filter
143
+ const findSingleUserRoleByFilter = async (
144
+ filter = {},
145
+ populateOptions = {}
146
+ ) => {
147
+ const defaultPopulateOptions = {
148
+ rolePopulate: {
149
+ path: "roleId",
150
+ select: "id name userId userShift permissionId modulePermissions",
151
+ populate: [{ path: "permissionId", select: "id name" }],
152
+ },
153
+ userPopulate: {
154
+ path: "userId",
155
+ match: { isDeleted: false, suspended: false },
156
+ select: "firstName lastName role email picture userShift",
157
+ },
158
+ };
159
+ const mergedPopulateOptions = {
160
+ rolePopulate: {
161
+ ...defaultPopulateOptions.rolePopulate,
162
+ ...populateOptions.rolePopulate,
163
+ },
164
+ userPopulate: {
165
+ ...defaultPopulateOptions.userPopulate,
166
+ ...populateOptions.userPopulate,
167
+ },
168
+ };
169
+ return await UserRole.findOne(filter)
170
+ .populate(mergedPopulateOptions.rolePopulate)
171
+ .populate(mergedPopulateOptions.userPopulate)
172
+ .lean()
173
+ .exec();
174
+ };
175
+
576
176
  const convertPermissionsArrayToObject = (originalArray) => {
577
177
  return originalArray?.reduce((acc, item) => {
578
178
  const { id, actions, integrationPermissions, ...extras } = item;
@@ -596,66 +196,160 @@ const convertPermissionsArrayToObject = (originalArray) => {
596
196
  }, {});
597
197
  };
598
198
 
599
- // Existing methods (simplified)
600
199
  const createUserRole = async (data) => {
601
200
  const savedRole = await UserRole.create(data);
602
- await updateCachedMembers();
201
+
202
+ // Update all related caches
203
+ await updateAllRelatedCaches(
204
+ savedRole?.userId?.toString(),
205
+ savedRole?.workspaceId?.toString()
206
+ );
207
+
603
208
  return savedRole;
604
209
  };
605
210
 
211
+ const findOneAndUpdateUserRole = async ({
212
+ workspaceId,
213
+ userId,
214
+ userShift,
215
+ role,
216
+ }) => {
217
+ const updatedRole = await UserRole.findOneAndUpdate(
218
+ { workspaceId, userId },
219
+ { $set: { userShift, role } },
220
+ { new: true, upsert: false }
221
+ ).exec();
222
+ if (updatedRole) {
223
+ await updateAllRelatedCaches(userId, workspaceId);
224
+ }
225
+ return updatedRole;
226
+ };
227
+
228
+ const findUserRole = async (filter = {}) => {
229
+ return await getCachedMembers(filter);
230
+ };
231
+
606
232
  const updateUserRole = async (id, data) => {
607
233
  const updatedRole = await UserRole.findByIdAndUpdate(id, data, {
608
234
  new: true,
609
235
  }).exec();
610
236
  if (updatedRole) {
611
- await updateCachedMembers();
237
+ await updateAllRelatedCaches(updatedRole.userId, updatedRole.workspaceId);
612
238
  }
613
239
  return updatedRole;
614
240
  };
615
241
 
242
+ const deleteUserRoleByFilter = async (filter) => {
243
+ const roleToDelete = await UserRole.findOne(filter).exec();
244
+ const deletedRole = await UserRole.findOneAndDelete(filter).exec();
245
+ if (deletedRole) {
246
+ await updateAllRelatedCaches(
247
+ roleToDelete?.userId,
248
+ roleToDelete?.workspaceId
249
+ );
250
+ }
251
+ return deletedRole;
252
+ };
253
+
616
254
  const deleteUserRole = async (id) => {
617
255
  const role = await UserRole.findById(id).exec();
256
+ const userId = role?.userId;
257
+ const workspaceId = role?.workspaceId;
618
258
  const deletedRole = await UserRole.findByIdAndDelete(id).exec();
619
259
  if (deletedRole) {
620
- await updateCachedMembers();
260
+ await updateAllRelatedCaches(userId, workspaceId);
621
261
  }
622
262
  return deletedRole;
623
263
  };
624
264
 
625
265
  const findUserWorkspaces = async (userId) => {
626
- const userRoles = await buildUserRoleQuery({
627
- filter: { userId },
628
- populate: {
629
- additional: [
630
- {
631
- path: "workspaceId",
632
- select:
633
- "iconUrl thumbUrl name productsCount ordersCount contact email address websiteUrl facebookUrl twitterUrl instagramUrl members defaultModule",
634
- match: { isDeleted: false },
635
- },
636
- ],
637
- },
638
- });
639
-
640
- return userRoles
641
- .filter((userRole) => userRole.workspaceId)
642
- .map((ur) => ({
643
- ...ur.workspaceId,
644
- id: ur.workspaceId?._id?.toString(),
645
- _id: ur.workspaceId?._id?.toString(),
646
- role: ur.roleId?.name || "",
647
- permissions: ur.roleId?.modulePermissions?.modules || [],
648
- }));
266
+ let userRoleWithWorkspaces = await UserRole.find({ userId: userId })
267
+ .select("userId roleId workspaceId")
268
+ .populate({
269
+ path: "roleId",
270
+ select: "id name userId userShift permissionId modulePermissions",
271
+ populate: [{ path: "permissionId", select: "id name" }],
272
+ })
273
+ .populate({
274
+ path: "workspaceId",
275
+ select: defaultSelect,
276
+ match: { isDeleted: false },
277
+ })
278
+ .lean()
279
+ .exec();
280
+ userRoleWithWorkspaces = userRoleWithWorkspaces
281
+ ?.filter((userRole) => userRole?.workspaceId)
282
+ ?.filter((userRole) => userRole?.roleId)
283
+ ?.map((ur) => {
284
+ return {
285
+ ...ur?.workspaceId,
286
+ id: ur?.workspaceId?._id?.toString(),
287
+ _id: ur?.workspaceId?._id?.toString(),
288
+ role: ur?.roleId?.name || "",
289
+ permissions: ur?.roleId?.modulePermissions?.modules || [],
290
+ };
291
+ });
292
+ return userRoleWithWorkspaces || [];
293
+ };
294
+
295
+ const getUserPermissions = async (workspaceId, userId) => {
296
+ try {
297
+ let members = await getCachedMembers({ workspaceId, userId });
298
+ console.log(members, "members");
299
+ if (members?.length) {
300
+ return (
301
+ convertPermissionsArrayToObject(
302
+ members?.[0]?.roleId?.modulePermissions?.modules
303
+ ) || null
304
+ );
305
+ }
306
+ return null;
307
+ } catch (err) {
308
+ console.error("Error in getUserPermissions:", err);
309
+ return null;
310
+ }
311
+ };
312
+
313
+ const getUserRoleWithPermissions = async (workspaceId, userId) => {
314
+ try {
315
+ let members = await getCachedMembers({ workspaceId, userId });
316
+ console.log(members, "members");
317
+ if (members?.length) {
318
+ let data = members?.[0];
319
+ const roleWithPermissions = {
320
+ ...data,
321
+ roleId: data?.roleId?._id?.toString() || "",
322
+ role: data?.roleId?.name || "",
323
+ permissions:
324
+ convertPermissionsArrayToObject(
325
+ data?.roleId?.modulePermissions?.modules
326
+ ) || [],
327
+ parentRole: data?.roleId?.permissionId?.name || "",
328
+ parentRoleId: data?.roleId?.permissionId?._id?.toString() || "",
329
+ defaultModule: data?.roleId?.defaultModule || "",
330
+ };
331
+ return roleWithPermissions || null;
332
+ }
333
+ return null;
334
+ } catch (err) {
335
+ console.error("Error in getUserRoleWithPermissions:", err);
336
+ return null;
337
+ }
649
338
  };
650
339
 
651
340
  const getChannelsPermissions = async (workspaceId, userId) => {
652
341
  try {
653
- const members = await getCachedMembers({ workspaceId, userId });
654
- return members?.[0]?.roleId?.modulePermissions?.modules
655
- ? convertPermissionsArrayToObject(
656
- members[0].roleId.modulePermissions.modules
342
+ let members = await getCachedMembers({ workspaceId, userId });
343
+ console.log(members, "members");
344
+ if (members?.length) {
345
+ let data = members?.[0];
346
+ return (
347
+ convertPermissionsArrayToObject(
348
+ data?.roleId?.modulePermissions?.modules
657
349
  )?.["conversations"]?.["integrationPermissions"] || []
658
- : [];
350
+ );
351
+ }
352
+ return [];
659
353
  } catch (err) {
660
354
  console.error("Error in getChannelsPermissions:", err);
661
355
  return [];
@@ -666,13 +360,14 @@ module.exports = {
666
360
  createUserRole,
667
361
  findUserRole,
668
362
  updateUserRole,
363
+ deleteUserRoleByFilter,
669
364
  deleteUserRole,
670
365
  findUserWorkspaces,
671
366
  getUserRoleWithPermissions,
672
367
  getUserPermissions,
673
368
  getChannelsPermissions,
369
+ findOneAndUpdateUserRole,
674
370
  findSingleUserRoleByFilter,
675
371
  getCachedMembers,
676
372
  updateCachedMembers,
677
- buildUserRoleQuery, // Expose the new flexible query builder
678
373
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shuttlepro-shared",
3
- "version": "1.2.70",
3
+ "version": "1.2.71",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {