@@ -8,8 +8,12 @@ const firestore = require("../utils/firestore");
8
8
const { fetchWallet, createWallet } = require ( "../models/wallets" ) ;
9
9
const { updateUserStatus } = require ( "../models/userStatus" ) ;
10
10
const { arraysHaveCommonItem, chunks } = require ( "../utils/array" ) ;
11
- const { archiveUsers } = require ( "../services/users" ) ;
12
- const { ALLOWED_FILTER_PARAMS , FIRESTORE_IN_CLAUSE_SIZE } = require ( "../constants/users" ) ;
11
+ const {
12
+ ALLOWED_FILTER_PARAMS ,
13
+ FIRESTORE_IN_CLAUSE_SIZE ,
14
+ USERS_PATCH_HANDLER_SUCCESS_MESSAGES ,
15
+ USERS_PATCH_HANDLER_ERROR_MESSAGES ,
16
+ } = require ( "../constants/users" ) ;
13
17
const { DOCUMENT_WRITE_SIZE } = require ( "../constants/constants" ) ;
14
18
const { userState } = require ( "../constants/userStatus" ) ;
15
19
const { BATCH_SIZE_IN_CLAUSE } = require ( "../constants/firebase" ) ;
@@ -27,6 +31,52 @@ const { formatUsername } = require("../utils/username");
27
31
const { logType } = require ( "../constants/logs" ) ;
28
32
const { addLog } = require ( "../services/logService" ) ;
29
33
34
+ /**
35
+ * Archive users by setting the roles.archived field to true.
36
+ * This function commits the write in batches to avoid reaching the maximum number of writes per batch.
37
+ * @param {Array } usersData - An array of user objects with the following properties: id, first_name, last_name
38
+ * @returns {Promise } - A promise that resolves with a summary object containing the number of users updated and failed, and an array of updated and failed user details.
39
+ */
40
+ const archiveUsers = async ( usersData ) => {
41
+ const batch = firestore . batch ( ) ;
42
+ const usersBatch = [ ] ;
43
+ const summary = {
44
+ totalUsersArchived : 0 ,
45
+ totalOperationsFailed : 0 ,
46
+ updatedUserDetails : [ ] ,
47
+ failedUserDetails : [ ] ,
48
+ } ;
49
+
50
+ usersData . forEach ( ( user ) => {
51
+ const { id, first_name : firstName , last_name : lastName } = user ;
52
+ const updatedUserData = {
53
+ ...user ,
54
+ roles : {
55
+ ...user . roles ,
56
+ archived : true ,
57
+ } ,
58
+ updated_at : Date . now ( ) ,
59
+ } ;
60
+ batch . update ( userModel . doc ( id ) , updatedUserData ) ;
61
+ usersBatch . push ( { id, firstName, lastName } ) ;
62
+ } ) ;
63
+
64
+ try {
65
+ await batch . commit ( ) ;
66
+ summary . totalUsersArchived += usersData . length ;
67
+ summary . updatedUserDetails = [ ...usersBatch ] ;
68
+ return {
69
+ message : USERS_PATCH_HANDLER_SUCCESS_MESSAGES . ARCHIVE_USERS . SUCCESSFULLY_COMPLETED_BATCH_UPDATES ,
70
+ ...summary ,
71
+ } ;
72
+ } catch ( err ) {
73
+ logger . error ( "Firebase batch Operation Failed!" ) ;
74
+ summary . totalOperationsFailed += usersData . length ;
75
+ summary . failedUserDetails = [ ...usersBatch ] ;
76
+ return { message : USERS_PATCH_HANDLER_ERROR_MESSAGES . ARCHIVE_USERS . BATCH_DATA_UPDATED_FAILED , ...summary } ;
77
+ }
78
+ } ;
79
+
30
80
/**
31
81
* Adds or updates the user data
32
82
*
@@ -182,11 +232,11 @@ const getSuggestedUsers = async (skill) => {
182
232
*/
183
233
const fetchPaginatedUsers = async ( query ) => {
184
234
const isDevMode = query . dev === "true" ;
185
-
186
235
try {
187
236
const size = parseInt ( query . size ) || 100 ;
188
237
const doc = ( query . next || query . prev ) && ( await userModel . doc ( query . next || query . prev ) . get ( ) ) ;
189
238
239
+ const isArchived = query . departed === "true" ;
190
240
let dbQuery ;
191
241
/**
192
242
* !!NOTE : At the time of writing we only support member in the role query
@@ -195,9 +245,9 @@ const fetchPaginatedUsers = async (query) => {
195
245
* if you're making changes to this code remove the archived check in the role query, example: role=archived,member
196
246
*/
197
247
if ( query . roles === "member" ) {
198
- dbQuery = userModel . where ( "roles.archived" , "==" , false ) . where ( "roles.member" , "==" , true ) ;
248
+ dbQuery = userModel . where ( "roles.archived" , "==" , isArchived ) . where ( "roles.member" , "==" , true ) ;
199
249
} else {
200
- dbQuery = userModel . where ( "roles.archived" , "==" , false ) . orderBy ( "username" ) ;
250
+ dbQuery = userModel . where ( "roles.archived" , "==" , isArchived ) . orderBy ( "username" ) ;
201
251
}
202
252
203
253
let compositeQuery = [ dbQuery ] ;
@@ -217,6 +267,10 @@ const fetchPaginatedUsers = async (query) => {
217
267
}
218
268
219
269
if ( Object . keys ( query ) . length ) {
270
+ if ( query . departed ) {
271
+ compositeQuery = compositeQuery . map ( ( query ) => query . where ( "roles.in_discord" , "==" , false ) ) ;
272
+ dbQuery = dbQuery . where ( "roles.in_discord" , "==" , false ) ;
273
+ }
220
274
if ( query . search ) {
221
275
const searchValue = query . search . toLowerCase ( ) . trim ( ) ;
222
276
dbQuery = dbQuery . startAt ( searchValue ) . endAt ( searchValue + "\uf8ff" ) ;
@@ -1031,6 +1085,7 @@ const updateUsersWithNewUsernames = async () => {
1031
1085
} ;
1032
1086
1033
1087
module . exports = {
1088
+ archiveUsers,
1034
1089
addOrUpdate,
1035
1090
fetchPaginatedUsers,
1036
1091
fetchUser,
0 commit comments