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.
- package/package.json +8 -1
- package/pages/Home.js +27 -55
- package/pages/index.js +0 -1
- package/public/Utils/personalDetailsUtils.js +5 -1
- package/public/Utils/sharedUtils.js +32 -0
- package/public/consts.js +0 -1
- package/.claude/worktrees/fix-save-button-disable/.husky/pre-commit +0 -19
- package/.claude/worktrees/fix-save-button-disable/.prettierignore +0 -7
- package/.claude/worktrees/fix-save-button-disable/.prettierrc.json +0 -16
- package/.claude/worktrees/fix-save-button-disable/README.md +0 -1
- package/.claude/worktrees/fix-save-button-disable/backend/README-member-contact-flows.md +0 -136
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/daily-pull-execution-check.test.js +0 -124
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/login-email-sync.test.js +0 -49
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/url-uniqueness.test.js +0 -194
- package/.claude/worktrees/fix-save-button-disable/backend/automations-methods.js +0 -13
- package/.claude/worktrees/fix-save-button-disable/backend/cms-data-methods.js +0 -251
- package/.claude/worktrees/fix-save-button-disable/backend/consts.js +0 -58
- package/.claude/worktrees/fix-save-button-disable/backend/contacts-methods.js +0 -67
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/bulk-process-methods.js +0 -222
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/consts.js +0 -39
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/index.js +0 -5
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/process-member-methods.js +0 -213
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/schedule-methods.js +0 -41
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/sync-to-cms-methods.js +0 -161
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/utils.js +0 -151
- package/.claude/worktrees/fix-save-button-disable/backend/data-hooks.js +0 -29
- package/.claude/worktrees/fix-save-button-disable/backend/dev-only-methods.js +0 -58
- package/.claude/worktrees/fix-save-button-disable/backend/elevated-modules.js +0 -18
- package/.claude/worktrees/fix-save-button-disable/backend/forms-methods.js +0 -52
- package/.claude/worktrees/fix-save-button-disable/backend/http-functions/httpFunctions.js +0 -86
- package/.claude/worktrees/fix-save-button-disable/backend/http-functions/index.js +0 -3
- package/.claude/worktrees/fix-save-button-disable/backend/http-functions/interests.js +0 -35
- package/.claude/worktrees/fix-save-button-disable/backend/index.js +0 -19
- package/.claude/worktrees/fix-save-button-disable/backend/jobs.js +0 -158
- package/.claude/worktrees/fix-save-button-disable/backend/login/generate-member-session-token.js +0 -27
- package/.claude/worktrees/fix-save-button-disable/backend/login/index.js +0 -8
- package/.claude/worktrees/fix-save-button-disable/backend/login/qa-login-methods.js +0 -54
- package/.claude/worktrees/fix-save-button-disable/backend/login/sso-methods.js +0 -159
- package/.claude/worktrees/fix-save-button-disable/backend/member-contact-orchestration.js +0 -111
- package/.claude/worktrees/fix-save-button-disable/backend/members-area-methods.js +0 -88
- package/.claude/worktrees/fix-save-button-disable/backend/members-data-methods.js +0 -789
- package/.claude/worktrees/fix-save-button-disable/backend/pac-api-methods.js +0 -54
- package/.claude/worktrees/fix-save-button-disable/backend/routers/index.js +0 -3
- package/.claude/worktrees/fix-save-button-disable/backend/routers/methods.js +0 -191
- package/.claude/worktrees/fix-save-button-disable/backend/routers/utils.js +0 -128
- package/.claude/worktrees/fix-save-button-disable/backend/search-filters-methods.js +0 -124
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-primary-methods.js +0 -256
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-visibility-methods.js +0 -160
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/consts.js +0 -34
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/daily-pull-check-methods.js +0 -78
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/email-normalize-methods.js +0 -134
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/index.js +0 -10
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/migration-methods.js +0 -46
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-configs.js +0 -251
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-helpers-methods.js +0 -433
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-process-methods.js +0 -606
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-migration-methods.js +0 -378
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-space-fix-methods.js +0 -174
- package/.claude/worktrees/fix-save-button-disable/backend/utils.js +0 -277
- package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
- package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-ids.js +0 -159
- package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-urls.js +0 -201
- package/.claude/worktrees/fix-save-button-disable/eslint.config.js +0 -120
- package/.claude/worktrees/fix-save-button-disable/index.js +0 -5
- package/.claude/worktrees/fix-save-button-disable/package-lock.json +0 -12160
- package/.claude/worktrees/fix-save-button-disable/package.json +0 -60
- package/.claude/worktrees/fix-save-button-disable/pages/ContactUs.js +0 -129
- package/.claude/worktrees/fix-save-button-disable/pages/Home.js +0 -779
- package/.claude/worktrees/fix-save-button-disable/pages/LearnMore.js +0 -27
- package/.claude/worktrees/fix-save-button-disable/pages/LoadingPage.js +0 -29
- package/.claude/worktrees/fix-save-button-disable/pages/Profile.js +0 -354
- package/.claude/worktrees/fix-save-button-disable/pages/QAPage.js +0 -39
- package/.claude/worktrees/fix-save-button-disable/pages/SaveAlerts.js +0 -13
- package/.claude/worktrees/fix-save-button-disable/pages/SelectBannerImages.js +0 -46
- package/.claude/worktrees/fix-save-button-disable/pages/deleteConfirm.js +0 -19
- package/.claude/worktrees/fix-save-button-disable/pages/index.js +0 -12
- package/.claude/worktrees/fix-save-button-disable/pages/personalDetails.js +0 -2486
- package/.claude/worktrees/fix-save-button-disable/public/Utils/homePage.js +0 -798
- package/.claude/worktrees/fix-save-button-disable/public/Utils/personalDetailsUtils.js +0 -25
- package/.claude/worktrees/fix-save-button-disable/public/Utils/sharedUtils.js +0 -235
- package/.claude/worktrees/fix-save-button-disable/public/consts.js +0 -113
- package/.claude/worktrees/fix-save-button-disable/public/index.js +0 -5
- package/.claude/worktrees/fix-save-button-disable/public/messages.js +0 -16
- package/.claude/worktrees/fix-save-button-disable/public/sso-auth-methods.js +0 -43
- package/.husky/pre-commit +0 -19
- package/.prettierignore +0 -7
- package/.prettierrc.json +0 -16
- package/backend/__tests__/daily-pull-execution-check.test.js +0 -124
- package/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
- package/backend/__tests__/login-email-sync.test.js +0 -49
- package/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
- package/backend/__tests__/url-uniqueness.test.js +0 -194
- package/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
- package/dev-only-scripts/find-duplicate-ids.js +0 -159
- package/dev-only-scripts/find-duplicate-urls.js +0 -201
- package/eslint.config.js +0 -120
- 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
|
-
};
|
package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-visibility-methods.js
DELETED
|
@@ -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
|
-
};
|