@@ -6,10 +6,13 @@ const walletConstants = require("../constants/wallets");
6
6
7
7
const firestore = require ( "../utils/firestore" ) ;
8
8
const { fetchWallet, createWallet } = require ( "../models/wallets" ) ;
9
+ const { arraysHaveCommonItem } = require ( "../utils/array" ) ;
10
+ const { ALLOWED_FILTER_PARAMS } = require ( "../constants/users" ) ;
9
11
const userModel = firestore . collection ( "users" ) ;
10
12
const joinModel = firestore . collection ( "applicants" ) ;
11
13
const itemModel = firestore . collection ( "itemTags" ) ;
12
-
14
+ const userStatusModel = firestore . collection ( "usersStatus" ) ;
15
+ const { ITEM_TAG , USER_STATE } = ALLOWED_FILTER_PARAMS ;
13
16
/**
14
17
* Adds or updates the user data
15
18
*
@@ -126,7 +129,7 @@ const getSuggestedUsers = async (skill) => {
126
129
* @param query { search, next, prev, size, page }: Filter for users
127
130
* @return {Promise<userModel|Array> }
128
131
*/
129
- const fetchUsers = async ( query ) => {
132
+ const fetchPaginatedUsers = async ( query ) => {
130
133
try {
131
134
// INFO: default user size set to 100
132
135
// INFO: https://github.com/Real-Dev-Squad/website-backend/pull/873#discussion_r1064229932
@@ -175,6 +178,33 @@ const fetchUsers = async (query) => {
175
178
}
176
179
} ;
177
180
181
+ const fetchAllUsers = async ( ) => {
182
+ try {
183
+ const dbQuery = userModel ;
184
+
185
+ const snapshot = await dbQuery . get ( ) ;
186
+
187
+ const allUsers = [ ] ;
188
+
189
+ snapshot . forEach ( ( doc ) => {
190
+ allUsers . push ( {
191
+ id : doc . id ,
192
+ ...doc . data ( ) ,
193
+ phone : undefined ,
194
+ email : undefined ,
195
+ tokens : undefined ,
196
+ chaincode : undefined ,
197
+ } ) ;
198
+ } ) ;
199
+ return {
200
+ allUsers,
201
+ } ;
202
+ } catch ( err ) {
203
+ logger . error ( "Error retrieving user data" , err ) ;
204
+ throw err ;
205
+ }
206
+ } ;
207
+
178
208
/**
179
209
* Fetches the user data from the the provided username or userId
180
210
*
@@ -292,9 +322,67 @@ const fetchUserSkills = async (id) => {
292
322
}
293
323
} ;
294
324
325
+ /**
326
+ * Fetches user data based on the filter query
327
+ *
328
+ * @param {Object } query - Object with query parameters
329
+ * @param {Array } query.levelId - Array of levelIds to filter the users on
330
+ * @param {Array } query.levelName - Array of levelNames to filter the users on
331
+ * @param {Array } query.levelNumber - Array of levelNumbers to filter the users on
332
+ * @param {Array } query.tagId - Array of tagIds to filter the users on
333
+ * @param {Array } query.state - Array of states to filter the users on
334
+ * @return {Promise<Array> } - Array of user documents that match the filter criteria
335
+ */
336
+
337
+ const getUsersBasedOnFilter = async ( query ) => {
338
+ const allQueryKeys = Object . keys ( query ) ;
339
+ const doesTagQueryExist = arraysHaveCommonItem ( ITEM_TAG , allQueryKeys ) ;
340
+ const doesStateQueryExist = arraysHaveCommonItem ( USER_STATE , allQueryKeys ) ;
341
+
342
+ const calls = {
343
+ item : itemModel ,
344
+ state : userStatusModel ,
345
+ } ;
346
+ calls . item = calls . item . where ( "itemType" , "==" , "USER" ) . where ( "tagType" , "==" , "SKILL" ) ;
347
+
348
+ Object . entries ( query ) . forEach ( ( [ key , value ] ) => {
349
+ const isTagKey = ITEM_TAG . includes ( key ) ;
350
+ const isStateKey = USER_STATE . includes ( key ) ;
351
+ const isValueArray = Array . isArray ( value ) ;
352
+
353
+ if ( isTagKey ) {
354
+ calls . item = isValueArray ? calls . item . where ( key , "in" , value ) : calls . item . where ( key , "==" , value ) ;
355
+ } else if ( isStateKey ) {
356
+ calls . state = isValueArray
357
+ ? calls . state . where ( "currentStatus.state" , "in" , value )
358
+ : calls . state . where ( "currentStatus.state" , "==" , value ) ;
359
+ }
360
+ } ) ;
361
+
362
+ const tagItems = doesTagQueryExist ? ( await calls . item . get ( ) ) . docs . map ( ( doc ) => ( { id : doc . id , ...doc . data ( ) } ) ) : [ ] ;
363
+ const stateItems = doesStateQueryExist
364
+ ? ( await calls . state . get ( ) ) . docs . map ( ( doc ) => ( { id : doc . id , ...doc . data ( ) } ) )
365
+ : [ ] ;
366
+ let finalItems = [ ] ;
367
+
368
+ if ( doesTagQueryExist && doesStateQueryExist ) {
369
+ const stateItemIds = new Set ( stateItems . map ( ( item ) => item . userId ) ) ;
370
+ finalItems = tagItems . filter ( ( item ) => stateItemIds . has ( item . itemId ) ) . map ( ( item ) => item . itemId ) ;
371
+ } else if ( doesStateQueryExist ) {
372
+ finalItems = stateItems . map ( ( item ) => item . userId ) ;
373
+ } else if ( doesTagQueryExist ) {
374
+ finalItems = tagItems . map ( ( item ) => item . itemId ) ;
375
+ }
376
+
377
+ finalItems = [ ...new Set ( finalItems ) ] ;
378
+ const userRefs = finalItems . map ( ( itemId ) => userModel . doc ( itemId ) ) ;
379
+ const userDocs = ( await firestore . getAll ( ...userRefs ) ) . map ( ( doc ) => ( { id : doc . id , ...doc . data ( ) } ) ) ;
380
+ return userDocs ;
381
+ } ;
382
+
295
383
module . exports = {
296
384
addOrUpdate,
297
- fetchUsers ,
385
+ fetchPaginatedUsers ,
298
386
fetchUser,
299
387
setIncompleteUserDetails,
300
388
initializeUser,
@@ -304,4 +392,6 @@ module.exports = {
304
392
getJoinData,
305
393
getSuggestedUsers,
306
394
fetchUserSkills,
395
+ fetchAllUsers,
396
+ getUsersBasedOnFilter,
307
397
} ;
0 commit comments