abmp-npm 1.8.31 → 1.8.33

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.
@@ -0,0 +1,114 @@
1
+ const { taskManager } = require('psdev-task-manager');
2
+
3
+ const { TASKS_NAMES } = require('../consts');
4
+ const { fetchPACMembers } = require('../pac-api-methods');
5
+
6
+ const { bulkProcessAndSaveMemberData } = require('./bulk-process-methods');
7
+ const { isUpdatedMember, isABMPMember } = require('./utils');
8
+
9
+ async function syncMembersDataPerAction(action) {
10
+ try {
11
+ const firstPageResponse = await fetchPACMembers(1, action);
12
+
13
+ if (
14
+ !firstPageResponse ||
15
+ !firstPageResponse.results ||
16
+ firstPageResponse.results.length === 0
17
+ ) {
18
+ return {
19
+ success: true,
20
+ totalPagesProcessed: 0,
21
+ lastPageProcessed: 0,
22
+ completedAt: new Date().toISOString(),
23
+ message: 'No data found',
24
+ };
25
+ }
26
+
27
+ // Calculate total pages from API response
28
+ const totalResults = firstPageResponse.total_results || 0;
29
+ const perPage = firstPageResponse.results.length;
30
+ const totalPages = firstPageResponse.total_pages || 0;
31
+
32
+ // Cap at 1000 pages as safety measure
33
+ const pagesToProcess = Math.min(totalPages, 1000);
34
+
35
+ console.log(
36
+ `Scheduling ${pagesToProcess} pages for processing (${totalResults} total records, ${perPage} per page)`
37
+ );
38
+
39
+ // Schedule tasks for all pages at once
40
+ const toScheduleTasks = Array.from(
41
+ { length: pagesToProcess },
42
+ (_, i) => i + 1 // API expects page number to start from 1
43
+ ).map(pageNumber => ({
44
+ name: TASKS_NAMES.SyncMembers,
45
+ data: {
46
+ pageNumber,
47
+ action,
48
+ },
49
+ type: 'scheduled',
50
+ }));
51
+
52
+ // Wait for all scheduling to complete
53
+ await taskManager().scheduleInBulk(toScheduleTasks);
54
+
55
+ return {
56
+ success: true,
57
+ totalPagesProcessed: pagesToProcess,
58
+ lastPageProcessed: pagesToProcess,
59
+ totalRecords: totalResults,
60
+ recordsPerPage: perPage,
61
+ completedAt: new Date().toISOString(),
62
+ };
63
+ } catch (error) {
64
+ throw new Error(`Synchronization failed: ${error.message}`);
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Synchronizes a single page of member data
70
+ * @param {Object} taskObject - Task object containing page data
71
+ * @returns {Promise<Object>} - Page synchronization result
72
+ */
73
+ async function synchronizeSinglePage(taskObject) {
74
+ const { pageNumber, action } = taskObject.data;
75
+ try {
76
+ const memberDataResponse = await fetchPACMembers(pageNumber, action);
77
+
78
+ if (
79
+ !memberDataResponse ||
80
+ !memberDataResponse.results ||
81
+ memberDataResponse.results.length === 0
82
+ ) {
83
+ throw new Error(`No data found for page ${pageNumber}`);
84
+ }
85
+ const toSyncMembers = memberDataResponse.results.filter(
86
+ member => isUpdatedMember(member) && isABMPMember(member)
87
+ );
88
+ if (toSyncMembers.length === 0) {
89
+ return {
90
+ success: true,
91
+ pageNumber,
92
+ totalPageSize: memberDataResponse.results.length,
93
+ filteredPageSize: toSyncMembers.length,
94
+ message: 'No to be updated, or ABMP members found',
95
+ };
96
+ }
97
+ const result = await bulkProcessAndSaveMemberData(toSyncMembers, pageNumber);
98
+
99
+ return {
100
+ success: true,
101
+ pageNumber,
102
+ totalPageSize: memberDataResponse.results.length,
103
+ filteredPageSize: toSyncMembers.length,
104
+ ...result,
105
+ };
106
+ } catch (error) {
107
+ throw new Error(`Page ${pageNumber} synchronization failed: ${error.message}`);
108
+ }
109
+ }
110
+
111
+ module.exports = {
112
+ syncMembersDataPerAction,
113
+ synchronizeSinglePage,
114
+ };
@@ -0,0 +1,78 @@
1
+ const { updateWixMemberLoginEmail } = require('../members-area-methods');
2
+
3
+ const { MEMBER_ACTIONS } = require('./consts');
4
+
5
+ const isUpdatedMember = member => member.action !== MEMBER_ACTIONS.NONE;
6
+ const isABMPMember = member =>
7
+ member.memberships.some(membership => membership.association === 'ABMP');
8
+
9
+ const changeWixMembersEmails = async toChangeWixMembersEmails => {
10
+ console.log(
11
+ `Changing login emails for ${toChangeWixMembersEmails.length} members with ids: [${toChangeWixMembersEmails.map(member => member.memberId).join(', ')}]`
12
+ );
13
+ return await Promise.all(
14
+ toChangeWixMembersEmails.map(member => updateWixMemberLoginEmail(member, {}))
15
+ );
16
+ };
17
+
18
+ /**
19
+ * Validates core member data requirements
20
+ * @param {Object} inputMemberData - Raw member data from API to validate
21
+ * @returns {boolean} - True if all required fields are valid, false otherwise
22
+ */
23
+ const validateCoreMemberData = inputMemberData => {
24
+ // Check memberid
25
+ if (!inputMemberData?.memberid) {
26
+ console.warn('validateCoreMemberData: Missing required field - memberid is mandatory');
27
+ return false;
28
+ }
29
+
30
+ // Check email
31
+ if (
32
+ !inputMemberData?.email ||
33
+ typeof inputMemberData.email !== 'string' ||
34
+ !inputMemberData.email.trim()
35
+ ) {
36
+ console.warn(
37
+ 'validateCoreMemberData: Missing required field - email (valid string) is mandatory'
38
+ );
39
+ return false;
40
+ }
41
+
42
+ // Check memberships
43
+ if (
44
+ !inputMemberData?.memberships ||
45
+ !Array.isArray(inputMemberData.memberships) ||
46
+ inputMemberData.memberships.length === 0
47
+ ) {
48
+ console.warn(
49
+ 'validateCoreMemberData: Missing required field - memberships (non-empty array) is mandatory'
50
+ );
51
+ return false;
52
+ }
53
+
54
+ return true;
55
+ };
56
+
57
+ const containsNonEnglish = str => /[^a-zA-Z0-9]/.test(str); // if it contains any non-english characters, test1 is allowed, but any others are not
58
+
59
+ /**
60
+ * Creates a full name from first and last name components
61
+ * @param {string} firstName - First name
62
+ * @param {string} lastName - Last name
63
+ * @returns {string} - Combined full name
64
+ */
65
+ const createFullName = (firstName, lastName) => {
66
+ const trimmedFirst = firstName?.trim() || '';
67
+ const trimmedLast = lastName?.trim() || '';
68
+ return `${trimmedFirst} ${trimmedLast}`.trim();
69
+ };
70
+
71
+ module.exports = {
72
+ isUpdatedMember,
73
+ isABMPMember,
74
+ changeWixMembersEmails,
75
+ validateCoreMemberData,
76
+ containsNonEnglish,
77
+ createFullName,
78
+ };
package/backend/index.js CHANGED
@@ -1,6 +1,11 @@
1
1
  module.exports = {
2
2
  ...require('./forms-methods'),
3
3
  ...require('./search-filters-methods'),
4
- ...require('./members-data-methods'),
5
- ...require('./utils'),
4
+ ...require('./jobs'),
5
+ ...require('./utils'), //TODO: remove it once we finish NPM movement
6
+ ...require('./daily-pull'), //TODO: remove it once we finish NPM movement
7
+ ...require('./pac-api-methods'), //TODO: remove it once we finish NPM movement
8
+ ...require('./members-area-methods'), //TODO: remove it once we finish NPM movement
9
+ ...require('./members-data-methods'), //TODO: remove it once we finish NPM movement
10
+ ...require('./cms-data-methods'), //TODO: remove it once we finish NPM movement
6
11
  };
@@ -0,0 +1,30 @@
1
+ const { taskManager } = require('psdev-task-manager');
2
+
3
+ const { TASKS_NAMES } = require('./consts');
4
+ const { TASKS } = require('./tasks');
5
+
6
+ async function runScheduledTasks() {
7
+ try {
8
+ console.log('runScheduledTasks started');
9
+ return await taskManager().runScheduledTasks(TASKS);
10
+ } catch (error) {
11
+ console.error(`Failed to runScheduledTasks: ${error.message}`);
12
+ throw new Error(`Failed to runScheduledTasks: ${error.message}`);
13
+ }
14
+ }
15
+
16
+ async function scheduleDailyPullTask() {
17
+ try {
18
+ console.log('scheduleDailyPullTask started!');
19
+ return await taskManager().schedule({
20
+ name: TASKS_NAMES.ScheduleDailyMembersDataSync,
21
+ data: {},
22
+ type: 'scheduled',
23
+ });
24
+ } catch (error) {
25
+ console.error(`Failed to scheduleDailyPullTask: ${error.message}`);
26
+ throw new Error(`Failed to scheduleDailyPullTask: ${error.message}`);
27
+ }
28
+ }
29
+
30
+ module.exports = { runScheduledTasks, scheduleDailyPullTask };
@@ -1,5 +1,5 @@
1
1
  const { auth } = require('@wix/essentials');
2
- const { members } = require('@wix/members');
2
+ const { members, authentication } = require('@wix/members');
3
3
  const elevatedCreateMember = auth.elevate(members.createMember);
4
4
 
5
5
  function prepareContactData(partner) {
@@ -36,7 +36,54 @@ const getCurrentMember = async () => {
36
36
  return member.member;
37
37
  };
38
38
 
39
+ /**
40
+ * Updates Wix member login email if the member has a contactId (registered Wix member)
41
+ * @param {Object} member - Member object with contactId and email
42
+ * @param {Object} result - Result object to track Wix member updates
43
+ */
44
+ async function updateWixMemberLoginEmail(member, result = {}) {
45
+ if (!member.contactId) {
46
+ console.log(`Member ${member.memberId} has no contactId - skipping Wix login email update`);
47
+ return;
48
+ }
49
+
50
+ try {
51
+ console.log(
52
+ `Updating Wix login email for member ${member.memberId} (contactId: ${member.contactId})`
53
+ );
54
+
55
+ const updatedWixMember = await authentication.changeLoginEmail(member.contactId, member.email);
56
+
57
+ console.log(
58
+ `✅ Successfully updated Wix login email for member ${member.memberId}: ${updatedWixMember.loginEmail}`
59
+ );
60
+
61
+ if (!result.wixMemberUpdates) {
62
+ result.wixMemberUpdates = { successful: 0, failed: 0 };
63
+ }
64
+ result.wixMemberUpdates.successful++;
65
+ } catch (error) {
66
+ console.error(`❌ Failed to update Wix login email for member ${member.memberId}:`, error);
67
+
68
+ if (!result.wixMemberUpdates) {
69
+ result.wixMemberUpdates = { successful: 0, failed: 0 };
70
+ }
71
+ result.wixMemberUpdates.failed++;
72
+
73
+ if (!result.wixMemberErrors) {
74
+ result.wixMemberErrors = [];
75
+ }
76
+ result.wixMemberErrors.push({
77
+ memberId: member.memberId,
78
+ contactId: member.contactId,
79
+ email: member.email,
80
+ error: error.message,
81
+ });
82
+ }
83
+ }
84
+
39
85
  module.exports = {
40
86
  createSiteMember,
41
87
  getCurrentMember,
88
+ updateWixMemberLoginEmail,
42
89
  };
@@ -1,22 +1,19 @@
1
- const { contacts } = require('@wix/crm');
2
- const { auth } = require('@wix/essentials');
3
-
4
1
  const { COLLECTIONS } = require('../public/consts');
5
2
 
6
- const { MEMBER_ACTIONS } = require('./consts');
3
+ const { updateMemberContactInfo } = require('./contacts-methods');
4
+ const { MEMBER_ACTIONS } = require('./daily-pull');
7
5
  const { wixData } = require('./elevated-modules');
8
6
  const { createSiteMember, getCurrentMember } = require('./members-area-methods');
9
7
  const {
8
+ createBatches,
9
+ normalizeUrlForComparison,
10
+ queryAllItems,
10
11
  formatDateToMonthYear,
11
12
  getAddressDisplayOptions,
12
13
  isStudent,
13
14
  generateGeoHash,
14
- urlExists,
15
15
  } = require('./utils');
16
16
 
17
- const elevatedGetContact = auth.elevate(contacts.getContact);
18
- const elevatedUpdateContact = auth.elevate(contacts.updateContact);
19
-
20
17
  /**
21
18
  * Retrieves member data by member ID
22
19
  * @param {string} memberId - The member ID to search for
@@ -136,145 +133,110 @@ async function validateMemberToken(memberIdInput) {
136
133
  }
137
134
  }
138
135
 
139
- /**
140
- * Generic contact update helper function
141
- * @param {string} contactId - The contact ID in Wix CRM
142
- * @param {function} updateInfoCallback - Function that returns the updated info object
143
- * @param {string} operationName - Name of the operation for logging
136
+ /** Performs bulk save operation for member data
137
+ * @param { Array } memberDataList - Array of member data objects to save
138
+ * @returns { Promise < Object >} - Bulk save operation result
144
139
  */
145
- async function updateContactInfo(contactId, updateInfoCallback, operationName) {
146
- if (!contactId) {
147
- throw new Error('Contact ID is required');
140
+ async function bulkSaveMembers(memberDataList) {
141
+ if (!Array.isArray(memberDataList) || memberDataList.length === 0) {
142
+ throw new Error('Invalid member data list provided for bulk save');
148
143
  }
149
144
 
150
145
  try {
151
- const contact = await elevatedGetContact(contactId);
152
- const currentInfo = contact.info;
153
- const updatedInfo = updateInfoCallback(currentInfo);
154
-
155
- await elevatedUpdateContact(contactId, { info: updatedInfo }, contact.revision);
146
+ // bulkSave all with batches of 1000 items as this is the Velo limit for bulkSave
147
+ const batches = createBatches(memberDataList, 1000);
148
+ return await Promise.all(
149
+ batches.map(batch => wixData.bulkSave(COLLECTIONS.MEMBERS_DATA, batch))
150
+ );
156
151
  } catch (error) {
157
- console.error(`Error in ${operationName}:`, error);
158
- throw new Error(`Failed to ${operationName}: ${error.message}`);
152
+ console.error('Error bulk saving members:', error);
153
+ throw new Error(`Bulk save failed: ${error.message}`);
159
154
  }
160
155
  }
161
156
 
162
157
  /**
163
- * Updates contact email in Wix CRM
164
- * @param {string} contactId - The contact ID in Wix CRM
165
- * @param {string} newEmail - The new email address
158
+ * Retrieves member data by member ID
159
+ * @param {string} memberId - The member ID to search for
160
+ * @returns {Promise<Object|null>} - Member data or null if not found
166
161
  */
167
- async function updateContactEmail(contactId, newEmail) {
168
- if (!newEmail) {
169
- throw new Error('New email is required');
162
+ async function findMemberById(memberId) {
163
+ if (!memberId) {
164
+ throw new Error('Member ID is required');
170
165
  }
171
166
 
172
- return await updateContactInfo(
173
- contactId,
174
- currentInfo => ({
175
- ...currentInfo,
176
- emails: {
177
- items: [
178
- {
179
- email: newEmail,
180
- primary: true,
181
- },
182
- ],
183
- },
184
- }),
185
- 'update contact email'
186
- );
187
- }
167
+ try {
168
+ const queryResult = await wixData
169
+ .query(COLLECTIONS.MEMBERS_DATA)
170
+ .eq('memberId', memberId)
171
+ .find();
188
172
 
189
- /**
190
- * Updates contact names in Wix CRM
191
- * @param {string} contactId - The contact ID in Wix CRM
192
- * @param {string} firstName - The new first name
193
- * @param {string} lastName - The new last name
194
- */
195
- async function updateContactNames(contactId, firstName, lastName) {
196
- if (!firstName && !lastName) {
197
- throw new Error('At least one name field is required');
173
+ return queryResult.items.length > 0 ? queryResult.items[0] : null;
174
+ } catch (error) {
175
+ throw new Error(`Failed to retrieve member data: ${error.message}`);
198
176
  }
199
-
200
- return await updateContactInfo(
201
- contactId,
202
- currentInfo => ({
203
- ...currentInfo,
204
- name: {
205
- first: firstName || currentInfo?.name?.first || '',
206
- last: lastName || currentInfo?.name?.last || '',
207
- },
208
- }),
209
- 'update contact names'
210
- );
211
177
  }
212
178
 
213
179
  /**
214
- * Update fields if they have changed
215
- * @param {Array} existingValues - Current values for comparison
216
- * @param {Array} newValues - New values to compare against
217
- * @param {Function} updater - Function to call if values changed
218
- * @param {Function} argsBuilder - Function to build arguments for updater
219
- */
220
- const updateIfChanged = (existingValues, newValues, updater, argsBuilder) => {
221
- const hasChanged = existingValues.some((val, idx) => val !== newValues[idx]);
222
- if (!hasChanged) return null;
223
- return updater(...argsBuilder(newValues));
224
- };
225
-
226
- /**
227
- * Updates member contact information in CRM if fields have changed
228
- * @param {string} id - Member ID
229
- * @param {Object} data - New member data
230
- */
231
- const updateMemberContactInfo = async (id, data) => {
232
- const existing = await findMemberByWixDataId(id);
233
- const { contactId } = existing;
234
-
235
- const updateConfig = [
236
- {
237
- fields: ['contactFormEmail'],
238
- updater: updateContactEmail,
239
- args: ([email]) => [contactId, email],
240
- },
241
- {
242
- fields: ['firstName', 'lastName'],
243
- updater: updateContactNames,
244
- args: ([firstName, lastName]) => [contactId, firstName, lastName],
245
- },
246
- ];
247
-
248
- const updatePromises = updateConfig
249
- .map(({ fields, updater, args }) => {
250
- const existingValues = fields.map(field => existing[field]);
251
- const newValues = fields.map(field => data[field]);
252
- return updateIfChanged(existingValues, newValues, updater, args);
253
- })
254
- .filter(Boolean);
255
-
256
- await Promise.all(updatePromises);
257
- };
258
-
259
- /**
260
- * Checks URL uniqueness for a member
261
- * @param {string} url - The URL to check
262
- * @param {string} memberId - The member ID to exclude from the check
263
- * @returns {Promise<Object>} Result object with isUnique boolean
180
+ * Method to get member by slug with flexible filtering options
181
+ * @param {Object} options - Query options
182
+ * @param {string} options.slug - The slug to search for
183
+ * @param {boolean} options.excludeDropped - Whether to exclude dropped members (default: true)
184
+ * @param {boolean} options.excludeSearchedMember - Whether to exclude a specific member (default: false)
185
+ * @param {string|number} [options.memberId] - Member ID to exclude when excludeSearchedMember is true (optional)
186
+ * @param {boolean} [options.queryAllMatches=false] - Whether to query all matches or just the first one (default: false)
187
+ * @returns {Promise<Object|null>} - Member data or null if not found
264
188
  */
265
- async function checkUrlUniqueness(url, memberId) {
266
- if (!url || !memberId) {
267
- throw new Error('Missing required parameters: url and memberId are required');
268
- }
189
+ async function getMemberBySlug({
190
+ slug,
191
+ excludeDropped = true,
192
+ excludeSearchedMember = false,
193
+ memberId = null,
194
+ queryAllMatches = false,
195
+ }) {
196
+ if (!slug) return null;
269
197
 
270
198
  try {
271
- const trimmedUrl = url.trim();
272
- const exists = await urlExists(trimmedUrl, memberId);
199
+ let query = wixData.query(COLLECTIONS.MEMBERS_DATA).contains('url', slug);
273
200
 
274
- return { isUnique: !exists };
201
+ if (excludeDropped) {
202
+ query = query.ne('action', 'drop');
203
+ }
204
+
205
+ if (excludeSearchedMember && memberId) {
206
+ query = query.ne('memberId', memberId);
207
+ }
208
+ let membersList;
209
+ if (queryAllMatches) {
210
+ query = query.limit(1000);
211
+ membersList = await queryAllItems(query);
212
+ } else {
213
+ membersList = await query.find().then(res => res.items);
214
+ }
215
+ let matchingMembers = membersList.filter(
216
+ item => item.url && item.url.toLowerCase() === slug.toLowerCase()
217
+ );
218
+ if (queryAllMatches) {
219
+ matchingMembers = membersList
220
+ .filter(
221
+ //remove trailing "-1", "-2", etc.
222
+ item => item.url && normalizeUrlForComparison(item.url) === slug.toLowerCase()
223
+ )
224
+ .sort((a, b) => b.url.toLowerCase().localeCompare(a.url.toLowerCase()));
225
+ }
226
+ if (matchingMembers.length > 1) {
227
+ const queryResultMsg = `Multiple members found with same slug ${slug} membersIds are : [${matchingMembers
228
+ .map(member => member.memberId)
229
+ .join(', ')}]`;
230
+ if (!queryAllMatches) {
231
+ throw new Error(queryResultMsg);
232
+ } else {
233
+ console.log(queryResultMsg);
234
+ }
235
+ }
236
+ return matchingMembers[0] || null;
275
237
  } catch (error) {
276
- console.error('Error checking URL uniqueness:', error);
277
- throw new Error(`Failed to check URL uniqueness: ${error.message}`);
238
+ console.error('Error getting member by slug:', error);
239
+ throw error;
278
240
  }
279
241
  }
280
242
 
@@ -321,10 +283,45 @@ async function saveRegistrationData(data, id) {
321
283
  }
322
284
  }
323
285
 
286
+ /**
287
+ * Checks if a URL already exists in the database for a different member (case-insensitive)
288
+ * @param {string} url - The URL to check
289
+ * @param {string|number} excludeMemberId - Member ID to exclude from the check
290
+ * @returns {Promise<boolean>} - True if URL exists for another member
291
+ */
292
+ async function urlExists(url, excludeMemberId) {
293
+ if (!url) return false;
294
+
295
+ try {
296
+ let query = wixData
297
+ .query(COLLECTIONS.MEMBERS_DATA)
298
+ .contains('url', url)
299
+ .ne('action', MEMBER_ACTIONS.DROP);
300
+
301
+ if (excludeMemberId) {
302
+ query = query.ne('memberId', excludeMemberId);
303
+ }
304
+
305
+ const { items } = await query.find();
306
+
307
+ // Case-insensitive comparison
308
+ const matchingMembers = items.filter(
309
+ item => item.url && item.url.toLowerCase() === url.toLowerCase()
310
+ );
311
+
312
+ return matchingMembers.length > 0;
313
+ } catch (error) {
314
+ console.error('Error checking URL existence:', error);
315
+ return false;
316
+ }
317
+ }
318
+
324
319
  module.exports = {
325
320
  findMemberByWixDataId,
326
321
  createContactAndMemberIfNew,
327
322
  validateMemberToken,
328
- checkUrlUniqueness,
329
323
  saveRegistrationData,
324
+ bulkSaveMembers,
325
+ findMemberById,
326
+ getMemberBySlug,
330
327
  };
@@ -0,0 +1,35 @@
1
+ const { secrets } = require('@wix/secrets');
2
+
3
+ const { PAC_API_URL } = require('./daily-pull/consts');
4
+
5
+ const getHeaders = async () => {
6
+ const AUTH_TOKEN = await secrets.getSecretValue('members-data-api-key');
7
+ const headers = {
8
+ Authorization: `Bearer ${AUTH_TOKEN}`,
9
+ };
10
+ return headers;
11
+ };
12
+ const fetchPACMembers = async (pageNum, actionFilter) => {
13
+ const url = `${PAC_API_URL}/Members?page=${pageNum}&actionFilter=${actionFilter}`;
14
+ const headers = await getHeaders();
15
+ const fetchOptions = {
16
+ method: 'get',
17
+ headers: headers,
18
+ };
19
+ const response = await fetch(url, fetchOptions);
20
+ const responseType = response.headers.get('content-type');
21
+ if (!responseType.includes('application/json')) {
22
+ const errorMessage = `[fetchPACMembers] got invalid responseType: ${responseType} for page ${pageNum} and actionFilter ${actionFilter}`;
23
+ console.error(errorMessage);
24
+ throw new Error(errorMessage);
25
+ }
26
+ if (response.ok) {
27
+ return response.json();
28
+ } else {
29
+ const errorMessage = `[fetchPACMembers] failed with status ${response.status} for page ${pageNum} and actionFilter ${actionFilter}`;
30
+ console.error(errorMessage);
31
+ throw new Error(errorMessage);
32
+ }
33
+ };
34
+
35
+ module.exports = { fetchPACMembers, getHeaders }; //TODO: remove getHeaders from exported methods once npm movement finishes
@@ -0,0 +1,37 @@
1
+ const { TASKS_NAMES } = require('./consts');
2
+ const { MEMBER_ACTIONS, synchronizeSinglePage, syncMembersDataPerAction } = require('./daily-pull');
3
+
4
+ const getDailyMembersDataSyncChildTasks = () => {
5
+ // we don't want to sync none action as it means this members data hasn't changed and we don't need to sync it
6
+ const MEMBER_ACTIONS_EXCEPT_NONE = Object.values(MEMBER_ACTIONS).filter(
7
+ action => action !== MEMBER_ACTIONS.NONE
8
+ );
9
+ return MEMBER_ACTIONS_EXCEPT_NONE.map(action => ({
10
+ name: TASKS_NAMES.ScheduleMembersDataPerAction,
11
+ data: { action },
12
+ }));
13
+ };
14
+ const TASKS = {
15
+ [TASKS_NAMES.ScheduleDailyMembersDataSync]: {
16
+ name: TASKS_NAMES.ScheduleDailyMembersDataSync,
17
+ scheduleChildrenSequentially: false,
18
+ estimatedDurationSec: 60,
19
+ childTasks: getDailyMembersDataSyncChildTasks(),
20
+ },
21
+ [TASKS_NAMES.ScheduleMembersDataPerAction]: {
22
+ name: TASKS_NAMES.ScheduleMembersDataPerAction,
23
+ getIdentifier: task => task.data.action,
24
+ process: syncMembersDataPerAction,
25
+ shouldSkipCheck: () => false,
26
+ estimatedDurationSec: 6,
27
+ },
28
+ [TASKS_NAMES.SyncMembers]: {
29
+ name: TASKS_NAMES.SyncMembers,
30
+ getIdentifier: task => task,
31
+ process: synchronizeSinglePage,
32
+ shouldSkipCheck: () => false,
33
+ estimatedDurationSec: 6,
34
+ },
35
+ };
36
+
37
+ module.exports = { TASKS };