abmp-npm 1.1.88 → 1.1.90

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.
@@ -14,13 +14,18 @@ async function updateContactInfo(contactId, updateInfoCallback, operationName) {
14
14
  if (!contactId) {
15
15
  throw new Error('Contact ID is required');
16
16
  }
17
-
17
+ console.log('updateContactInfo contactId', contactId);
18
+ console.log('updateContactInfo operationName', operationName);
18
19
  try {
19
20
  const contact = await elevatedGetContact(contactId);
21
+ console.log('updateContactInfo contact', contact);
20
22
  const currentInfo = contact.info;
23
+ console.log('updateContactInfo currentInfo', currentInfo);
21
24
  const updatedInfo = updateInfoCallback(currentInfo);
22
-
23
- await elevatedUpdateContact(contactId, updatedInfo, contact.revision);
25
+ console.log('updateContactInfo updatedInfo', updatedInfo);
26
+ const updatedContact = await elevatedUpdateContact(contactId, updatedInfo, contact.revision);
27
+ console.log('updateContactInfo updatedContact', updatedContact);
28
+ return updatedContact;
24
29
  } catch (error) {
25
30
  console.error(`Error in ${operationName}:`, error);
26
31
  throw new Error(`Failed to ${operationName}: ${error.message}`);
@@ -33,6 +38,8 @@ async function updateContactInfo(contactId, updateInfoCallback, operationName) {
33
38
  * @param {string} newEmail - The new email address
34
39
  */
35
40
  async function updateContactEmail(contactId, newEmail) {
41
+ console.log('updateContactEmail contactId', contactId);
42
+ console.log('updateContactEmail newEmail', newEmail);
36
43
  if (!newEmail) {
37
44
  throw new Error('New email is required');
38
45
  }
@@ -88,6 +95,7 @@ async function updateContactNames(contactId, firstName, lastName) {
88
95
  const updateIfChanged = (existingValues, newValues, updater, argsBuilder) => {
89
96
  const hasChanged = existingValues.some((val, idx) => val !== newValues[idx]);
90
97
  if (!hasChanged) return null;
98
+ console.log('updateIfChanged hasChanged', hasChanged);
91
99
  return updater(...argsBuilder(newValues));
92
100
  };
93
101
 
@@ -98,7 +106,7 @@ const updateIfChanged = (existingValues, newValues, updater, argsBuilder) => {
98
106
  */
99
107
  const updateMemberContactInfo = async (data, existingMemberData) => {
100
108
  const { contactId } = existingMemberData;
101
-
109
+ console.log('updateMemberContactInfo contactId', contactId);
102
110
  const updateConfig = [
103
111
  {
104
112
  fields: ['contactFormEmail'],
@@ -120,7 +128,9 @@ const updateMemberContactInfo = async (data, existingMemberData) => {
120
128
  })
121
129
  .filter(Boolean);
122
130
 
123
- await Promise.all(updatePromises);
131
+ const resp = await Promise.all(updatePromises);
132
+ console.log('updateMemberContactInfo updatePromises', resp);
133
+ return resp;
124
134
  };
125
135
 
126
136
  module.exports = {
@@ -1,4 +1,4 @@
1
- const { getMemberByEmail, getQAUsers } = require('../members-data-methods');
1
+ const { prepareMemberForQALogin, getQAUsers } = require('../members-data-methods');
2
2
  const { getSecret } = require('../utils');
3
3
 
4
4
  const validateQAUser = async userEmail => {
@@ -20,27 +20,23 @@ const validateQAUser = async userEmail => {
20
20
  */
21
21
  const loginQAMember = async ({ userEmail, secret }, generateSessionToken) => {
22
22
  try {
23
- const userValidation = await validateQAUser(userEmail);
23
+ const [userValidation, qaSecret] = await Promise.all([
24
+ validateQAUser(userEmail),
25
+ getSecret('ABMP_QA_SECRET'),
26
+ ]);
24
27
  if (userValidation.error) {
25
28
  return { success: false, error: userValidation.error };
26
29
  }
27
-
28
- const qaSecret = await getSecret('ABMP_QA_SECRET');
29
30
  if (secret !== qaSecret) {
30
31
  return { success: false, error: 'Invalid secret' };
31
32
  }
32
33
 
33
- const token = await generateSessionToken(userValidation.email, qaSecret);
34
-
35
- const result = await getMemberCMSId(userEmail);
36
- if (!result.success) {
37
- return { success: false, error: result.error };
38
- }
39
-
34
+ const memberData = await prepareMemberForQALogin(userValidation.email);
35
+ const token = await generateSessionToken(memberData.email, qaSecret);
40
36
  return {
41
37
  success: true,
42
38
  token,
43
- memberCMSId: result.memberCMSId,
39
+ memberCMSId: memberData._id,
44
40
  };
45
41
  } catch (error) {
46
42
  console.error('QA login error:', error);
@@ -48,25 +44,6 @@ const loginQAMember = async ({ userEmail, secret }, generateSessionToken) => {
48
44
  }
49
45
  };
50
46
 
51
- async function getMemberCMSId(userEmail) {
52
- try {
53
- const userValidation = await validateQAUser(userEmail);
54
- if (userValidation.error) {
55
- return { success: false, error: userValidation.error };
56
- }
57
-
58
- const member = await getMemberByEmail(userEmail);
59
-
60
- if (!member) {
61
- return { success: false, error: `No Member found in DB matching email: ${userEmail}` };
62
- }
63
- return { success: true, memberCMSId: member._id };
64
- } catch (error) {
65
- console.error('Error getting member CMS ID:', error);
66
- return { success: false, error: 'Failed to retrieve member data' };
67
- }
68
- }
69
-
70
47
  module.exports = {
71
48
  loginQAMember,
72
49
  };
@@ -5,7 +5,7 @@ const { decode } = require('jwt-js-decode');
5
5
  const { CONFIG_KEYS, SSO_TOKEN_AUTH_API_URL } = require('../consts');
6
6
  const { MEMBER_ACTIONS } = require('../daily-pull/consts');
7
7
  const { getCurrentMember } = require('../members-area-methods');
8
- const { getMemberByContactId, getSiteMemberId } = require('../members-data-methods');
8
+ const { getMemberByContactId, prepareMemberForSSOLogin } = require('../members-data-methods');
9
9
  const {
10
10
  formatDateToMonthYear,
11
11
  getAddressDisplayOptions,
@@ -133,12 +133,12 @@ const authenticateSSOToken = async ({ token }, generateSessionToken) => {
133
133
  if (isValidToken) {
134
134
  const jwt = decode(responseToken);
135
135
  const payload = jwt.payload;
136
- const membersData = await getSiteMemberId(payload);
137
- console.log('membersDataCollectionId', membersData._id);
138
- const sessionToken = await generateSessionToken(membersData.email);
136
+ const memberData = await prepareMemberForSSOLogin(payload);
137
+ console.log('memberDataCollectionId', memberData._id);
138
+ const sessionToken = await generateSessionToken(memberData.email);
139
139
  const authObj = {
140
140
  type: 'success',
141
- memberId: membersData._id,
141
+ memberId: memberData._id,
142
142
  sessionToken,
143
143
  };
144
144
  return authObj;
@@ -93,10 +93,16 @@ async function findMemberById(memberId) {
93
93
  const queryResult = await wixData
94
94
  .query(COLLECTIONS.MEMBERS_DATA)
95
95
  .eq('memberId', memberId)
96
+ .limit(2)
96
97
  .find();
97
-
98
- return queryResult.items.length > 0 ? queryResult.items[0] : null;
98
+ if (queryResult.items.length > 1) {
99
+ throw new Error(
100
+ `Multiple members found with memberId ${memberId} members _ids are : [${queryResult.items.map(member => member._id).join(', ')}]`
101
+ );
102
+ }
103
+ return queryResult.items.length === 1 ? queryResult.items[0] : null;
99
104
  } catch (error) {
105
+ console.error('Error finding member by ID:', error);
100
106
  throw new Error(`Failed to retrieve member data: ${error.message}`);
101
107
  }
102
108
  }
@@ -441,38 +447,53 @@ const getQAUsers = async () => {
441
447
  throw new Error(`Failed to get QA users: ${error.message}`);
442
448
  }
443
449
  };
444
- async function getSiteMemberId(data) {
450
+ /**
451
+ * Ensures member has a contact - creates one if missing
452
+ * @param {Object} memberData - Member data from DB
453
+ * @returns {Promise<Object>} - Member data with contactId
454
+ */
455
+ async function ensureMemberHasContact(memberData) {
456
+ if (!memberData) {
457
+ throw new Error('Member data is required');
458
+ }
459
+ if (!memberData.contactId) {
460
+ const memberDataWithContactId = await createContactAndMemberIfNew(memberData);
461
+ return memberDataWithContactId;
462
+ }
463
+ return memberData;
464
+ }
465
+ async function prepareMemberForSSOLogin(data) {
445
466
  try {
446
467
  console.log('data', data);
447
468
  const memberId = data?.pac?.cst_recno;
448
469
  if (!memberId) {
449
- const errorMessage = `Member ID is missing in passed data ${JSON.stringify(data)}`;
450
- console.error(errorMessage);
451
- throw new Error(errorMessage);
470
+ throw new Error(`Member ID is missing in passed data ${JSON.stringify(data)}`);
452
471
  }
453
- const queryMemberResult = await wixData
454
- .query(COLLECTIONS.MEMBERS_DATA)
455
- .eq('memberId', Number(memberId))
456
- .find()
457
- .then(res => res.items);
458
- if (!queryMemberResult.length || queryMemberResult.length > 1) {
459
- throw new Error(
460
- `Invalid Members count found in DB for email ${data.email} members count is : [${
461
- queryMemberResult.length
462
- }] membersIds are : [${queryMemberResult.map(member => member.memberId).join(', ')}]`
463
- );
472
+ const memberData = await findMemberById(Number(memberId));
473
+ if (!memberData) {
474
+ throw new Error(`Member data not found for memberId ${memberId}`);
464
475
  }
465
- let memberData = queryMemberResult[0];
466
476
  console.log('memberData', memberData);
467
- const isNewUser = !memberData.contactId;
468
- if (isNewUser) {
469
- const memberDataWithContactId = await createContactAndMemberIfNew(memberData);
470
- console.log('memberDataWithContactId', memberDataWithContactId);
471
- memberData = memberDataWithContactId;
477
+ return await ensureMemberHasContact(memberData);
478
+ } catch (error) {
479
+ console.error('Error in prepareMemberForSSOLogin', error.message);
480
+ throw error;
481
+ }
482
+ }
483
+ async function prepareMemberForQALogin(email) {
484
+ try {
485
+ console.log('qa email:', email);
486
+ if (!email) {
487
+ throw new Error(`Email is missing in passed data ${email}`);
488
+ }
489
+ const memberData = await getMemberByEmail(email);
490
+ if (!memberData) {
491
+ throw new Error(`Member data not found for email ${email}`);
472
492
  }
473
- return memberData;
493
+ console.log('memberData', memberData);
494
+ return await ensureMemberHasContact(memberData);
474
495
  } catch (error) {
475
- console.error('Error in getSiteMemberId', error.message);
496
+ console.error('Error in prepareMemberForQALogin', error.message);
476
497
  throw error;
477
498
  }
478
499
  }
@@ -494,6 +515,7 @@ module.exports = {
494
515
  getMembersByIds,
495
516
  getMemberByEmail,
496
517
  getQAUsers,
497
- getSiteMemberId,
518
+ prepareMemberForSSOLogin,
519
+ prepareMemberForQALogin,
498
520
  checkUrlUniqueness,
499
521
  };
@@ -9,7 +9,8 @@ const { queryAllItems, chunkArray } = require('../utils');
9
9
  const { TASKS_NAMES } = require('./consts');
10
10
 
11
11
  const COLLECTION_WITH_URLS = 'MembersDataWithUrls';
12
- const CHUNK_SIZE = 5000; // 5k members per task
12
+ const CHUNK_SIZE = 5000; // 5k members per task for migration
13
+ const GENERATION_CHUNK_SIZE = 1000; // 1k members per task for URL generation
13
14
 
14
15
  /**
15
16
  * Step 1: Migrate existing URLs from backup collection
@@ -201,7 +202,7 @@ async function scheduleGenerateMissingUrls() {
201
202
  };
202
203
  }
203
204
 
204
- const chunks = chunkArray(membersToUpdate, CHUNK_SIZE);
205
+ const chunks = chunkArray(membersToUpdate, GENERATION_CHUNK_SIZE);
205
206
 
206
207
  for (let i = 0; i < chunks.length; i++) {
207
208
  const chunk = chunks[i];
@@ -255,11 +256,25 @@ async function generateUrlsChunk(data) {
255
256
  };
256
257
 
257
258
  try {
258
- // Fetch all members at once using hasSome
259
- console.log(`Fetching ${memberIds.length} members from database...`);
260
- const members = await queryAllItems(
261
- wixData.query(COLLECTIONS.MEMBERS_DATA).hasSome('_id', memberIds)
259
+ // Fetch members in smaller batches to avoid cursor size limits
260
+ // hasSome with too many IDs creates cursors that exceed Wix's 150KB limit
261
+ const FETCH_BATCH_SIZE = 200;
262
+ console.log(
263
+ `Fetching ${memberIds.length} members from database in batches of ${FETCH_BATCH_SIZE}...`
262
264
  );
265
+
266
+ const members = [];
267
+ const idBatches = chunkArray(memberIds, FETCH_BATCH_SIZE);
268
+
269
+ for (let i = 0; i < idBatches.length; i++) {
270
+ const idBatch = idBatches[i];
271
+ const batchMembers = await queryAllItems(
272
+ wixData.query(COLLECTIONS.MEMBERS_DATA).hasSome('_id', idBatch)
273
+ );
274
+ members.push(...batchMembers);
275
+ console.log(`Fetched batch ${i + 1}/${idBatches.length}: ${batchMembers.length} members`);
276
+ }
277
+
263
278
  console.log(`Found ${members.length} members in database`);
264
279
 
265
280
  // Create a map of _id -> member for quick lookup
@@ -292,7 +307,7 @@ async function generateUrlsChunk(data) {
292
307
  try {
293
308
  const uniqueUrl = await ensureUniqueUrl({
294
309
  url: '',
295
- memberId: member._id,
310
+ memberId: member.memberId,
296
311
  fullName: name || '', // Let ensureUniqueUrl handle fallback for empty names
297
312
  });
298
313
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abmp-npm",
3
- "version": "1.1.88",
3
+ "version": "1.1.90",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "check-cycles": "madge --circular .",