abmp-npm 2.0.76 → 2.0.78

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.
Files changed (99) hide show
  1. package/package.json +8 -1
  2. package/pages/Home.js +27 -55
  3. package/pages/index.js +0 -1
  4. package/public/Utils/personalDetailsUtils.js +5 -1
  5. package/public/Utils/sharedUtils.js +32 -0
  6. package/public/consts.js +0 -1
  7. package/.claude/worktrees/fix-save-button-disable/.husky/pre-commit +0 -19
  8. package/.claude/worktrees/fix-save-button-disable/.prettierignore +0 -7
  9. package/.claude/worktrees/fix-save-button-disable/.prettierrc.json +0 -16
  10. package/.claude/worktrees/fix-save-button-disable/README.md +0 -1
  11. package/.claude/worktrees/fix-save-button-disable/backend/README-member-contact-flows.md +0 -136
  12. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  13. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  14. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/login-email-sync.test.js +0 -49
  15. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  16. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/url-uniqueness.test.js +0 -194
  17. package/.claude/worktrees/fix-save-button-disable/backend/automations-methods.js +0 -13
  18. package/.claude/worktrees/fix-save-button-disable/backend/cms-data-methods.js +0 -251
  19. package/.claude/worktrees/fix-save-button-disable/backend/consts.js +0 -58
  20. package/.claude/worktrees/fix-save-button-disable/backend/contacts-methods.js +0 -67
  21. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/bulk-process-methods.js +0 -222
  22. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/consts.js +0 -39
  23. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/index.js +0 -5
  24. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/process-member-methods.js +0 -213
  25. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/schedule-methods.js +0 -41
  26. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/sync-to-cms-methods.js +0 -161
  27. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/utils.js +0 -151
  28. package/.claude/worktrees/fix-save-button-disable/backend/data-hooks.js +0 -29
  29. package/.claude/worktrees/fix-save-button-disable/backend/dev-only-methods.js +0 -58
  30. package/.claude/worktrees/fix-save-button-disable/backend/elevated-modules.js +0 -18
  31. package/.claude/worktrees/fix-save-button-disable/backend/forms-methods.js +0 -52
  32. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/httpFunctions.js +0 -86
  33. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/index.js +0 -3
  34. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/interests.js +0 -35
  35. package/.claude/worktrees/fix-save-button-disable/backend/index.js +0 -19
  36. package/.claude/worktrees/fix-save-button-disable/backend/jobs.js +0 -158
  37. package/.claude/worktrees/fix-save-button-disable/backend/login/generate-member-session-token.js +0 -27
  38. package/.claude/worktrees/fix-save-button-disable/backend/login/index.js +0 -8
  39. package/.claude/worktrees/fix-save-button-disable/backend/login/qa-login-methods.js +0 -54
  40. package/.claude/worktrees/fix-save-button-disable/backend/login/sso-methods.js +0 -159
  41. package/.claude/worktrees/fix-save-button-disable/backend/member-contact-orchestration.js +0 -111
  42. package/.claude/worktrees/fix-save-button-disable/backend/members-area-methods.js +0 -88
  43. package/.claude/worktrees/fix-save-button-disable/backend/members-data-methods.js +0 -789
  44. package/.claude/worktrees/fix-save-button-disable/backend/pac-api-methods.js +0 -54
  45. package/.claude/worktrees/fix-save-button-disable/backend/routers/index.js +0 -3
  46. package/.claude/worktrees/fix-save-button-disable/backend/routers/methods.js +0 -191
  47. package/.claude/worktrees/fix-save-button-disable/backend/routers/utils.js +0 -128
  48. package/.claude/worktrees/fix-save-button-disable/backend/search-filters-methods.js +0 -124
  49. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-primary-methods.js +0 -256
  50. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-visibility-methods.js +0 -160
  51. package/.claude/worktrees/fix-save-button-disable/backend/tasks/consts.js +0 -34
  52. package/.claude/worktrees/fix-save-button-disable/backend/tasks/daily-pull-check-methods.js +0 -78
  53. package/.claude/worktrees/fix-save-button-disable/backend/tasks/email-normalize-methods.js +0 -134
  54. package/.claude/worktrees/fix-save-button-disable/backend/tasks/index.js +0 -10
  55. package/.claude/worktrees/fix-save-button-disable/backend/tasks/migration-methods.js +0 -46
  56. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-configs.js +0 -251
  57. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-helpers-methods.js +0 -433
  58. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-process-methods.js +0 -606
  59. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-migration-methods.js +0 -378
  60. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-space-fix-methods.js +0 -174
  61. package/.claude/worktrees/fix-save-button-disable/backend/utils.js +0 -277
  62. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  63. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-ids.js +0 -159
  64. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-urls.js +0 -201
  65. package/.claude/worktrees/fix-save-button-disable/eslint.config.js +0 -120
  66. package/.claude/worktrees/fix-save-button-disable/index.js +0 -5
  67. package/.claude/worktrees/fix-save-button-disable/package-lock.json +0 -12160
  68. package/.claude/worktrees/fix-save-button-disable/package.json +0 -60
  69. package/.claude/worktrees/fix-save-button-disable/pages/ContactUs.js +0 -129
  70. package/.claude/worktrees/fix-save-button-disable/pages/Home.js +0 -779
  71. package/.claude/worktrees/fix-save-button-disable/pages/LearnMore.js +0 -27
  72. package/.claude/worktrees/fix-save-button-disable/pages/LoadingPage.js +0 -29
  73. package/.claude/worktrees/fix-save-button-disable/pages/Profile.js +0 -354
  74. package/.claude/worktrees/fix-save-button-disable/pages/QAPage.js +0 -39
  75. package/.claude/worktrees/fix-save-button-disable/pages/SaveAlerts.js +0 -13
  76. package/.claude/worktrees/fix-save-button-disable/pages/SelectBannerImages.js +0 -46
  77. package/.claude/worktrees/fix-save-button-disable/pages/deleteConfirm.js +0 -19
  78. package/.claude/worktrees/fix-save-button-disable/pages/index.js +0 -12
  79. package/.claude/worktrees/fix-save-button-disable/pages/personalDetails.js +0 -2486
  80. package/.claude/worktrees/fix-save-button-disable/public/Utils/homePage.js +0 -798
  81. package/.claude/worktrees/fix-save-button-disable/public/Utils/personalDetailsUtils.js +0 -25
  82. package/.claude/worktrees/fix-save-button-disable/public/Utils/sharedUtils.js +0 -235
  83. package/.claude/worktrees/fix-save-button-disable/public/consts.js +0 -113
  84. package/.claude/worktrees/fix-save-button-disable/public/index.js +0 -5
  85. package/.claude/worktrees/fix-save-button-disable/public/messages.js +0 -16
  86. package/.claude/worktrees/fix-save-button-disable/public/sso-auth-methods.js +0 -43
  87. package/.husky/pre-commit +0 -19
  88. package/.prettierignore +0 -7
  89. package/.prettierrc.json +0 -16
  90. package/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  91. package/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  92. package/backend/__tests__/login-email-sync.test.js +0 -49
  93. package/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  94. package/backend/__tests__/url-uniqueness.test.js +0 -194
  95. package/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  96. package/dev-only-scripts/find-duplicate-ids.js +0 -159
  97. package/dev-only-scripts/find-duplicate-urls.js +0 -201
  98. package/eslint.config.js +0 -120
  99. package/pages/contactForLocation.js +0 -28
@@ -1,256 +0,0 @@
1
- const { taskManager } = require('psdev-task-manager');
2
-
3
- const { COLLECTIONS } = require('../../public/consts');
4
- const { wixData } = require('../elevated-modules');
5
- const { bulkSaveMembers, getMembersByIds } = require('../members-data-methods');
6
- const { chunkArray, queryAllItems } = require('../utils');
7
-
8
- const { TASKS_NAMES } = require('./consts');
9
-
10
- const CHUNK_SIZE = 1000;
11
-
12
- const getAddressKey = (address, index) =>
13
- address?.key || address?.addressid || address?.addressId || `address_${index}`;
14
-
15
- const hasPrimaryAddress = addressDisplayOption =>
16
- Array.isArray(addressDisplayOption) &&
17
- addressDisplayOption.some(option => option?.isMain === true);
18
-
19
- /**
20
- * Schedules tasks to fix members with multiple addresses and no primary address.
21
- */
22
- async function scheduleFixPrimaryAddressForMembers() {
23
- console.log('=== Scheduling Fix Primary Address Tasks ===');
24
-
25
- try {
26
- const membersQuery = await wixData
27
- .query(COLLECTIONS.MEMBERS_DATA)
28
- .isNotEmpty('addresses')
29
- .limit(1000);
30
- const members = await queryAllItems(membersQuery);
31
- console.log(`Fetched ${members.length} members with addresses`);
32
-
33
- const membersToFix = members.filter(member => {
34
- const addresses = Array.isArray(member.addresses) ? member.addresses : [];
35
- if (addresses.length === 0) {
36
- return false;
37
- }
38
- return !hasPrimaryAddress(member.addressDisplayOption);
39
- });
40
-
41
- const memberIds = [
42
- ...new Set(
43
- membersToFix
44
- .map(member => Number(member.memberId))
45
- .filter(memberId => Number.isFinite(memberId) && memberId > 0)
46
- ),
47
- ];
48
- console.log(`Members with addresses and no primary: ${memberIds.length}`);
49
-
50
- if (memberIds.length === 0) {
51
- console.log('No members need primary address fixes');
52
- return {
53
- success: true,
54
- message: 'No members need primary address fixes',
55
- totalMembers: 0,
56
- tasksScheduled: 0,
57
- };
58
- }
59
-
60
- const chunks = chunkArray(memberIds, CHUNK_SIZE);
61
- for (let i = 0; i < chunks.length; i++) {
62
- const chunk = chunks[i];
63
- const task = {
64
- name: TASKS_NAMES.fixPrimaryAddressChunk,
65
- data: {
66
- memberIds: chunk,
67
- chunkIndex: i,
68
- totalChunks: chunks.length,
69
- },
70
- type: 'scheduled',
71
- };
72
- await taskManager().schedule(task);
73
- console.log(`Scheduled task ${i + 1}/${chunks.length} (${chunk.length} members)`);
74
- }
75
-
76
- const result = {
77
- success: true,
78
- message: `Scheduled ${chunks.length} tasks for ${memberIds.length} members`,
79
- totalMembers: memberIds.length,
80
- tasksScheduled: chunks.length,
81
- };
82
-
83
- console.log('=== Scheduling Complete ===');
84
- console.log(`Sample memberIds: ${memberIds.slice(0, 10).join(', ')}`);
85
- console.log(JSON.stringify(result, null, 2));
86
-
87
- return result;
88
- } catch (error) {
89
- console.error('Error scheduling primary address fix:', error);
90
- throw error;
91
- }
92
- }
93
-
94
- /**
95
- * Processes a chunk of members and sets the first address as primary
96
- * when a member has multiple addresses and no primary address.
97
- */
98
- async function fixPrimaryAddressChunk(data) {
99
- const { memberIds, chunkIndex, totalChunks } = data;
100
- console.log(
101
- `Processing primary address fix chunk ${chunkIndex + 1}/${totalChunks} (${memberIds.length} members)`
102
- );
103
-
104
- const result = {
105
- successful: 0,
106
- failed: 0,
107
- skipped: 0,
108
- errors: [],
109
- skippedIds: [],
110
- failedIds: [],
111
- };
112
- const skippedNoAddress = [];
113
- const skippedHasPrimary = [];
114
- const updatedIds = [];
115
-
116
- try {
117
- const members = await getMembersByIds(memberIds);
118
- console.log(`Loaded ${members.length} members for this chunk`);
119
- const membersToUpdate = [];
120
-
121
- members.forEach(member => {
122
- const addresses = Array.isArray(member.addresses) ? member.addresses : [];
123
- if (addresses.length === 0) {
124
- result.skipped++;
125
- result.skippedIds.push(member.memberId);
126
- if (skippedNoAddress.length < 20) {
127
- skippedNoAddress.push(member.memberId);
128
- }
129
- return;
130
- }
131
- if (hasPrimaryAddress(member.addressDisplayOption)) {
132
- result.skipped++;
133
- result.skippedIds.push(member.memberId);
134
- if (skippedHasPrimary.length < 20) {
135
- skippedHasPrimary.push(member.memberId);
136
- }
137
- return;
138
- }
139
-
140
- const firstKey = getAddressKey(addresses[0], 0);
141
- const normalizedAddresses = addresses.map((address, index) => {
142
- if (index !== 0 || address?.key) {
143
- return address;
144
- }
145
- return { ...address, key: firstKey };
146
- });
147
-
148
- const updatedDisplayOptions = Array.isArray(member.addressDisplayOption)
149
- ? member.addressDisplayOption.map(option => ({
150
- ...option,
151
- isMain: false,
152
- }))
153
- : [];
154
-
155
- const existingOption = updatedDisplayOptions.find(option => option?.key === firstKey);
156
- if (existingOption) {
157
- existingOption.isMain = true;
158
- } else {
159
- updatedDisplayOptions.push({ key: firstKey, isMain: true });
160
- }
161
-
162
- membersToUpdate.push({
163
- ...member,
164
- addresses: normalizedAddresses,
165
- addressDisplayOption: updatedDisplayOptions,
166
- });
167
- if (updatedIds.length < 20) {
168
- updatedIds.push(member.memberId);
169
- }
170
- });
171
-
172
- if (membersToUpdate.length === 0) {
173
- console.log('No members need updating in this batch');
174
- return result;
175
- }
176
-
177
- try {
178
- await bulkSaveMembers(membersToUpdate);
179
- result.successful += membersToUpdate.length;
180
- console.log(`✅ Successfully updated ${membersToUpdate.length} members`);
181
- if (updatedIds.length > 0) {
182
- console.log(`Updated memberIds (sample): ${updatedIds.join(', ')}`);
183
- }
184
- } catch (error) {
185
- console.error('❌ Error bulk saving members:', error);
186
- result.failed += membersToUpdate.length;
187
- result.failedIds.push(...membersToUpdate.map(member => member.memberId));
188
- result.errors.push({
189
- error: error.message,
190
- memberCount: membersToUpdate.length,
191
- });
192
- }
193
-
194
- if (skippedNoAddress.length > 0) {
195
- console.log(`Skipped (no addresses) sample: ${skippedNoAddress.join(', ')}`);
196
- }
197
- if (skippedHasPrimary.length > 0) {
198
- console.log(`Skipped (already has primary) sample: ${skippedHasPrimary.join(', ')}`);
199
- }
200
-
201
- return result;
202
- } catch (error) {
203
- console.error(`Error processing primary address fix chunk ${chunkIndex}:`, error);
204
- throw error;
205
- }
206
- }
207
-
208
- /**
209
- * Returns count of members with addresses but no primary address.
210
- */
211
- async function countMembersMissingPrimaryAddress() {
212
- console.log('=== Counting Members Missing Primary Address ===');
213
-
214
- try {
215
- const membersQuery = await wixData
216
- .query(COLLECTIONS.MEMBERS_DATA)
217
- .isNotEmpty('addresses')
218
- .limit(1000);
219
- const members = await queryAllItems(membersQuery);
220
- console.log(`Fetched ${members.length} members with addresses`);
221
-
222
- const membersToFix = members.filter(member => {
223
- const addresses = Array.isArray(member.addresses) ? member.addresses : [];
224
- if (addresses.length === 0) {
225
- return false;
226
- }
227
- return !hasPrimaryAddress(member.addressDisplayOption);
228
- });
229
-
230
- const memberIds = [
231
- ...new Set(
232
- membersToFix
233
- .map(member => Number(member.memberId))
234
- .filter(memberId => Number.isFinite(memberId) && memberId > 0)
235
- ),
236
- ];
237
-
238
- const result = {
239
- success: true,
240
- totalMembers: memberIds.length,
241
- sampleMemberIds: memberIds.slice(0, 20),
242
- };
243
-
244
- console.log(JSON.stringify(result, null, 2));
245
- return result;
246
- } catch (error) {
247
- console.error('Error counting members missing primary address:', error);
248
- throw error;
249
- }
250
- }
251
-
252
- module.exports = {
253
- scheduleFixPrimaryAddressForMembers,
254
- fixPrimaryAddressChunk,
255
- countMembersMissingPrimaryAddress,
256
- };
@@ -1,160 +0,0 @@
1
- const { taskManager } = require('psdev-task-manager');
2
-
3
- const { COLLECTIONS, ADDRESS_STATUS_TYPES } = require('../../public/consts');
4
- const { wixData } = require('../elevated-modules');
5
- const { bulkSaveMembers, getMembersByIds } = require('../members-data-methods');
6
- const { chunkArray, queryAllItems } = require('../utils');
7
-
8
- const { TASKS_NAMES } = require('./consts');
9
-
10
- const CHUNK_SIZE = 1000;
11
-
12
- // Target visibility for every address: show city / state / zip, hide the street address.
13
- const TARGET_STATUS = ADDRESS_STATUS_TYPES.STATE_CITY_ZIP;
14
-
15
- const getMemberAddresses = member => (Array.isArray(member.addresses) ? member.addresses : []);
16
-
17
- /**
18
- * Whether a member has at least one address not already at the target status.
19
- * @param {Object} member
20
- * @returns {boolean}
21
- */
22
- const needsCityStateUpdate = member =>
23
- getMemberAddresses(member).some(address => address && address.addressStatus !== TARGET_STATUS);
24
-
25
- /**
26
- * Sets every address on a member to STATE_CITY_ZIP (other address fields are preserved).
27
- * @param {Object} member
28
- * @returns {Array} the member's addresses with addressStatus set to STATE_CITY_ZIP
29
- */
30
- const setAddressesToCityState = member =>
31
- getMemberAddresses(member).map(address => ({
32
- ...address,
33
- addressStatus: TARGET_STATUS,
34
- }));
35
-
36
- /**
37
- * Schedules tasks to set ALL addresses for ALL members to STATE_CITY_ZIP (show city/state/zip,
38
- * hide the street). Manually triggered (not cron-wired).
39
- */
40
- async function scheduleSetAddressesToCityState() {
41
- console.log('=== Scheduling Set Addresses To City/State Tasks ===');
42
-
43
- try {
44
- const membersQuery = await wixData
45
- .query(COLLECTIONS.MEMBERS_DATA)
46
- .isNotEmpty('addresses')
47
- .limit(1000);
48
- const members = await queryAllItems(membersQuery);
49
- console.log(`Fetched ${members.length} members with addresses`);
50
-
51
- // Only members that still have an address not at the target status need updating.
52
- const memberIds = [
53
- ...new Set(
54
- members
55
- .filter(needsCityStateUpdate)
56
- .map(member => Number(member.memberId))
57
- .filter(memberId => Number.isFinite(memberId) && memberId > 0)
58
- ),
59
- ];
60
- console.log(`Members needing a city/state update: ${memberIds.length}`);
61
-
62
- if (memberIds.length === 0) {
63
- console.log('No members need their addresses set to city/state');
64
- return {
65
- success: true,
66
- message: 'No members need their addresses set to city/state',
67
- totalMembers: 0,
68
- tasksScheduled: 0,
69
- };
70
- }
71
-
72
- const chunks = chunkArray(memberIds, CHUNK_SIZE);
73
- for (let i = 0; i < chunks.length; i++) {
74
- const chunk = chunks[i];
75
- await taskManager().schedule({
76
- name: TASKS_NAMES.setAddressesToCityStateChunk,
77
- data: {
78
- memberIds: chunk,
79
- chunkIndex: i,
80
- totalChunks: chunks.length,
81
- },
82
- type: 'scheduled',
83
- });
84
- console.log(`Scheduled task ${i + 1}/${chunks.length} (${chunk.length} members)`);
85
- }
86
-
87
- const result = {
88
- success: true,
89
- message: `Scheduled ${chunks.length} tasks for ${memberIds.length} members`,
90
- totalMembers: memberIds.length,
91
- tasksScheduled: chunks.length,
92
- };
93
- console.log('=== Scheduling Complete ===');
94
- console.log(JSON.stringify(result, null, 2));
95
- return result;
96
- } catch (error) {
97
- console.error('Error scheduling set-addresses-to-city-state:', error);
98
- throw error;
99
- }
100
- }
101
-
102
- /**
103
- * Processes a chunk of members and sets every address to STATE_CITY_ZIP.
104
- * @param {Object} data
105
- * @param {Array<number|string>} data.memberIds
106
- * @param {number} data.chunkIndex
107
- * @param {number} data.totalChunks
108
- */
109
- async function setAddressesToCityStateChunk(data) {
110
- const { memberIds, chunkIndex, totalChunks } = data;
111
- console.log(
112
- `Processing set-city-state chunk ${chunkIndex + 1}/${totalChunks} (${memberIds.length} members)`
113
- );
114
-
115
- const result = { successful: 0, failed: 0, skipped: 0, errors: [], failedIds: [] };
116
-
117
- try {
118
- const members = await getMembersByIds(memberIds);
119
- console.log(`Loaded ${members.length} members for this chunk`);
120
-
121
- const membersToUpdate = [];
122
- members.forEach(member => {
123
- // Skip members that have no address or are already all at the target status.
124
- if (!needsCityStateUpdate(member)) {
125
- result.skipped++;
126
- return;
127
- }
128
- membersToUpdate.push({
129
- ...member,
130
- addresses: setAddressesToCityState(member),
131
- });
132
- });
133
-
134
- if (membersToUpdate.length === 0) {
135
- console.log('No members need updating in this batch');
136
- return result;
137
- }
138
-
139
- try {
140
- await bulkSaveMembers(membersToUpdate);
141
- result.successful += membersToUpdate.length;
142
- console.log(`✅ Set addresses to city/state for ${membersToUpdate.length} members`);
143
- } catch (error) {
144
- console.error('❌ Error bulk saving members:', error);
145
- result.failed += membersToUpdate.length;
146
- result.failedIds.push(...membersToUpdate.map(member => member.memberId));
147
- result.errors.push({ error: error.message, memberCount: membersToUpdate.length });
148
- }
149
-
150
- return result;
151
- } catch (error) {
152
- console.error(`Error processing set-city-state chunk ${chunkIndex}:`, error);
153
- throw error;
154
- }
155
- }
156
-
157
- module.exports = {
158
- scheduleSetAddressesToCityState,
159
- setAddressesToCityStateChunk,
160
- };
@@ -1,34 +0,0 @@
1
- const TASKS_NAMES = {
2
- ScheduleDailyMembersDataSync: 'ScheduleDailyMembersDataSync',
3
- ScheduleMembersDataPerAction: 'ScheduleMembersDataPerAction',
4
- SyncMembers: 'SyncMembers',
5
- scheduleTaskForEmptyAboutYouMembers: 'scheduleTaskForEmptyAboutYouMembers',
6
- convertHtmlToRichContent: 'convertHtmlToRichContent',
7
- CompileFiltersOptions: 'CompileFiltersOptions',
8
- scheduleTaskForExternalProfileImages: 'scheduleTaskForExternalProfileImages',
9
- convertExternalProfilesToWixImages: 'convertExternalProfilesToWixImages',
10
- updateSiteMapS3: 'updateSiteMapS3',
11
- scheduleEmailSync: 'scheduleEmailSync',
12
- syncMemberLoginEmails: 'syncMemberLoginEmails',
13
- scheduleContactFormEmailMigration: 'scheduleContactFormEmailMigration',
14
- migrateContactFormEmails: 'migrateContactFormEmails',
15
- scheduleMigrateExistingUrls: 'scheduleMigrateExistingUrls',
16
- migrateUrlsChunk: 'migrateUrlsChunk',
17
- scheduleGenerateMissingUrls: 'scheduleGenerateMissingUrls',
18
- generateUrlsChunk: 'generateUrlsChunk',
19
- scheduleCreateContactsFromMembers: 'scheduleCreateContactsFromMembers',
20
- createContactsFromMembers: 'createContactsFromMembers',
21
- scheduleFixPrimaryAddressForMembers: 'scheduleFixPrimaryAddressForMembers',
22
- fixPrimaryAddressChunk: 'fixPrimaryAddressChunk',
23
- scheduleFixUrlsWithSpaces: 'scheduleFixUrlsWithSpaces',
24
- fixUrlsWithSpacesChunk: 'fixUrlsWithSpacesChunk',
25
- scheduleSetAddressesToCityState: 'scheduleSetAddressesToCityState',
26
- setAddressesToCityStateChunk: 'setAddressesToCityStateChunk',
27
- scheduleNormalizeMemberEmails: 'scheduleNormalizeMemberEmails',
28
- normalizeMemberEmailsChunk: 'normalizeMemberEmailsChunk',
29
- dailyPullExecutionCheck: 'dailyPullExecutionCheck',
30
- };
31
-
32
- module.exports = {
33
- TASKS_NAMES,
34
- };
@@ -1,78 +0,0 @@
1
- const { COLLECTIONS } = require('psdev-task-manager/public/consts');
2
-
3
- const { scheduleDailyPullTasks } = require('../daily-pull/schedule-methods');
4
- const { wixData } = require('../elevated-modules');
5
- const { queryAllItems } = require('../utils');
6
-
7
- const { TASKS_NAMES } = require('./consts');
8
-
9
- const DEFAULT_HOURS_BACK = 4;
10
-
11
- // The cron path (scheduleDailyPullTask) creates ScheduleMembersDataPerAction tasks
12
- // directly; ScheduleDailyMembersDataSync only exists when the pull is triggered via
13
- // the root task. Either one in the window is evidence the daily pull was scheduled.
14
- const DAILY_PULL_TASK_NAMES = [
15
- TASKS_NAMES.ScheduleMembersDataPerAction,
16
- TASKS_NAMES.ScheduleDailyMembersDataSync,
17
- ];
18
-
19
- /**
20
- * Detects whether the daily pull was scheduled in the lookback window.
21
- * If no daily pull task exists, re-schedules the same per-action tasks the cron
22
- * would have created, propagating the environment flags from the task data so a
23
- * test site's fallback pulls from the test PAC API.
24
- * @param {Object} [taskData]
25
- * @param {number} [taskData.hoursBack=4] - Lookback window in hours
26
- * @param {boolean} [taskData.isTestEnvironment=false] - Pull from the test PAC API on fallback
27
- * @param {boolean} [taskData.includeNone=false] - Include the NONE action on fallback
28
- * @returns {Promise<Object>} - Check result
29
- */
30
- async function dailyPullExecutionCheck(taskData) {
31
- const hoursBack =
32
- taskData?.hoursBack && Number.isFinite(taskData.hoursBack)
33
- ? taskData.hoursBack
34
- : DEFAULT_HOURS_BACK;
35
- const isTestEnvironment = Boolean(taskData?.isTestEnvironment);
36
- const includeNone = Boolean(taskData?.includeNone);
37
- const sinceDate = new Date(Date.now() - hoursBack * 60 * 60 * 1000);
38
-
39
- console.log('dailyPullExecutionCheck started', {
40
- hoursBack,
41
- sinceDate,
42
- isTestEnvironment,
43
- includeNone,
44
- });
45
-
46
- const dailyPullTasksQuery = wixData
47
- .query(COLLECTIONS.TASKS)
48
- .hasSome('name', DAILY_PULL_TASK_NAMES)
49
- .ge('_createdDate', sinceDate);
50
-
51
- const dailyPullTasks = await queryAllItems(dailyPullTasksQuery);
52
- const dailyPullScheduled = dailyPullTasks.length > 0;
53
-
54
- const result = {
55
- success: dailyPullScheduled,
56
- sinceDate: sinceDate.toISOString(),
57
- checkedTaskNames: DAILY_PULL_TASK_NAMES,
58
- dailyPullTasksFound: dailyPullTasks.length,
59
- };
60
-
61
- if (!dailyPullScheduled) {
62
- console.log('No daily pull tasks found in window; re-scheduling per-action pull tasks', {
63
- hoursBack,
64
- isTestEnvironment,
65
- includeNone,
66
- });
67
- await scheduleDailyPullTasks({ isTestEnvironment, includeNone });
68
- result.fallbackScheduled = true;
69
- }
70
-
71
- console.log('dailyPullExecutionCheck result', JSON.stringify(result, null, 2));
72
-
73
- return result;
74
- }
75
-
76
- module.exports = {
77
- dailyPullExecutionCheck,
78
- };
@@ -1,134 +0,0 @@
1
- const { taskManager } = require('psdev-task-manager');
2
-
3
- const {
4
- bulkSaveMembers,
5
- getMembersByIds,
6
- getAllMembersNeedingEmailNormalization,
7
- memberNeedsEmailNormalization,
8
- } = require('../members-data-methods');
9
- const { chunkArray } = require('../utils');
10
-
11
- const { TASKS_NAMES } = require('./consts');
12
-
13
- const CHUNK_SIZE = 1000;
14
-
15
- /**
16
- * One-off backfill: schedules tasks to normalize (lowercase + trim) the email and
17
- * contactFormEmail fields of existing members so stored values match the normalize-on-write
18
- * behavior, keeping case-insensitive uniqueness lookups reliable.
19
- */
20
- async function scheduleNormalizeMemberEmails() {
21
- console.log('=== Scheduling Member Email Normalization ===');
22
-
23
- try {
24
- const members = await getAllMembersNeedingEmailNormalization();
25
- console.log(`Fetched ${members.length} members needing email normalization`);
26
-
27
- const memberIds = [
28
- ...new Set(
29
- members
30
- .map(member => Number(member.memberId))
31
- .filter(memberId => Number.isFinite(memberId) && memberId > 0)
32
- ),
33
- ];
34
- console.log(`Members to normalize: ${memberIds.length}`);
35
-
36
- if (memberIds.length === 0) {
37
- console.log('No members need email normalization');
38
- return {
39
- success: true,
40
- message: 'No members need email normalization',
41
- totalMembers: 0,
42
- tasksScheduled: 0,
43
- };
44
- }
45
-
46
- const chunks = chunkArray(memberIds, CHUNK_SIZE);
47
- for (let i = 0; i < chunks.length; i++) {
48
- const chunk = chunks[i];
49
- const task = {
50
- name: TASKS_NAMES.normalizeMemberEmailsChunk,
51
- data: {
52
- memberIds: chunk,
53
- chunkIndex: i,
54
- totalChunks: chunks.length,
55
- },
56
- type: 'scheduled',
57
- };
58
- await taskManager().schedule(task);
59
- console.log(`Scheduled task ${i + 1}/${chunks.length} (${chunk.length} members)`);
60
- }
61
-
62
- const result = {
63
- success: true,
64
- message: `Scheduled ${chunks.length} tasks for ${memberIds.length} members`,
65
- totalMembers: memberIds.length,
66
- tasksScheduled: chunks.length,
67
- };
68
-
69
- console.log('=== Scheduling Complete ===');
70
- console.log(JSON.stringify(result, null, 2));
71
-
72
- return result;
73
- } catch (error) {
74
- console.error('Error scheduling member email normalization:', error);
75
- throw error;
76
- }
77
- }
78
-
79
- /**
80
- * Processes a chunk of members, normalizing their email fields.
81
- * bulkSaveMembers normalizes on write, so we only need to select the members that still
82
- * have non-canonical values and save them.
83
- */
84
- async function normalizeMemberEmailsChunk(data) {
85
- const { memberIds, chunkIndex, totalChunks } = data;
86
- console.log(
87
- `Processing email normalization chunk ${chunkIndex + 1}/${totalChunks} (${memberIds.length} members)`
88
- );
89
-
90
- const result = {
91
- successful: 0,
92
- failed: 0,
93
- skipped: 0,
94
- errors: [],
95
- failedIds: [],
96
- };
97
-
98
- try {
99
- const members = await getMembersByIds(memberIds);
100
- console.log(`Loaded ${members.length} members for this chunk`);
101
-
102
- const membersToUpdate = members.filter(memberNeedsEmailNormalization);
103
- result.skipped = members.length - membersToUpdate.length;
104
-
105
- if (membersToUpdate.length === 0) {
106
- console.log('No members need updating in this batch');
107
- return result;
108
- }
109
-
110
- try {
111
- await bulkSaveMembers(membersToUpdate);
112
- result.successful += membersToUpdate.length;
113
- console.log(`✅ Successfully normalized ${membersToUpdate.length} members`);
114
- } catch (error) {
115
- console.error('❌ Error bulk saving members:', error);
116
- result.failed += membersToUpdate.length;
117
- result.failedIds.push(...membersToUpdate.map(member => member.memberId));
118
- result.errors.push({
119
- error: error.message,
120
- memberCount: membersToUpdate.length,
121
- });
122
- }
123
-
124
- return result;
125
- } catch (error) {
126
- console.error(`Error processing email normalization chunk ${chunkIndex}:`, error);
127
- throw error;
128
- }
129
- }
130
-
131
- module.exports = {
132
- scheduleNormalizeMemberEmails,
133
- normalizeMemberEmailsChunk,
134
- };
@@ -1,10 +0,0 @@
1
- module.exports = {
2
- ...require('./tasks-configs'),
3
- ...require('./consts'),
4
- ...require('./tasks-process-methods'),
5
- ...require('./migration-methods'),
6
- ...require('./url-migration-methods'),
7
- ...require('./address-primary-methods'),
8
- ...require('./url-space-fix-methods'),
9
- ...require('./daily-pull-check-methods'),
10
- };