abmp-npm 1.10.5 → 1.10.7
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/backend/daily-pull/process-member-methods.js +1 -0
- package/backend/daily-pull/utils.js +1 -1
- package/backend/members-data-methods.js +3 -1
- package/backend/tasks/consts.js +4 -0
- package/backend/tasks/migration-methods.js +20 -0
- package/backend/tasks/tasks-configs.js +35 -1
- package/backend/tasks/url-migration-methods.js +376 -0
- package/backend/utils.js +2 -0
- package/package.json +2 -2
- package/pages/Profile.js +12 -12
|
@@ -84,7 +84,7 @@ const validateCoreMemberData = inputMemberData => {
|
|
|
84
84
|
return true;
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
-
const containsNonEnglish = str => /[^a-zA-Z0-9]/.test(str); // if it contains any non-english characters, test1 is allowed,
|
|
87
|
+
const containsNonEnglish = str => /[^a-zA-Z0-9-]/.test(str); // if it contains any non-english characters or invalid URL chars, test1 is allowed, hyphens are allowed
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Creates a full name from first and last name components
|
|
@@ -132,7 +132,9 @@ async function getMemberBySlug({
|
|
|
132
132
|
}
|
|
133
133
|
query = query.limit(1000);
|
|
134
134
|
const searchResult = await searchAllItems(query);
|
|
135
|
-
const membersList = searchResult.filter(
|
|
135
|
+
const membersList = searchResult.filter(
|
|
136
|
+
item => item.url && item.url.toLowerCase().includes(slug.toLowerCase())
|
|
137
|
+
); //replacement for contains - case insensitive
|
|
136
138
|
let matchingMembers = membersList.filter(
|
|
137
139
|
item => item.url && item.url.toLowerCase() === slug.toLowerCase()
|
|
138
140
|
);
|
package/backend/tasks/consts.js
CHANGED
|
@@ -12,6 +12,10 @@ const TASKS_NAMES = {
|
|
|
12
12
|
syncMemberLoginEmails: 'syncMemberLoginEmails',
|
|
13
13
|
scheduleContactFormEmailMigration: 'scheduleContactFormEmailMigration',
|
|
14
14
|
migrateContactFormEmails: 'migrateContactFormEmails',
|
|
15
|
+
scheduleMigrateExistingUrls: 'scheduleMigrateExistingUrls',
|
|
16
|
+
migrateUrlsChunk: 'migrateUrlsChunk',
|
|
17
|
+
scheduleGenerateMissingUrls: 'scheduleGenerateMissingUrls',
|
|
18
|
+
generateUrlsChunk: 'generateUrlsChunk',
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
module.exports = {
|
|
@@ -20,7 +20,27 @@ function scheduleExternalProfileImageMigration() {
|
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
// Schedule URL migration from backup collection
|
|
24
|
+
function scheduleUrlMigration() {
|
|
25
|
+
return taskManager().schedule({
|
|
26
|
+
name: TASKS_NAMES.scheduleMigrateExistingUrls,
|
|
27
|
+
data: {},
|
|
28
|
+
type: 'scheduled',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Schedule URL generation for members without URLs
|
|
33
|
+
function scheduleUrlGeneration() {
|
|
34
|
+
return taskManager().schedule({
|
|
35
|
+
name: TASKS_NAMES.scheduleGenerateMissingUrls,
|
|
36
|
+
data: {},
|
|
37
|
+
type: 'scheduled',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
module.exports = {
|
|
24
42
|
scheduleConvertHtmlToRichContent,
|
|
25
43
|
scheduleExternalProfileImageMigration,
|
|
44
|
+
scheduleUrlMigration,
|
|
45
|
+
scheduleUrlGeneration,
|
|
26
46
|
};
|
|
@@ -17,6 +17,12 @@ const {
|
|
|
17
17
|
scheduleEmailSync,
|
|
18
18
|
syncMemberLoginEmails,
|
|
19
19
|
} = require('./tasks-process-methods');
|
|
20
|
+
const {
|
|
21
|
+
scheduleMigrateExistingUrls,
|
|
22
|
+
migrateUrlsChunk,
|
|
23
|
+
scheduleGenerateMissingUrls,
|
|
24
|
+
generateUrlsChunk,
|
|
25
|
+
} = require('./url-migration-methods');
|
|
20
26
|
|
|
21
27
|
const getDailyMembersDataSyncChildTasks = () => {
|
|
22
28
|
// 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
|
|
@@ -89,7 +95,7 @@ const TASKS = {
|
|
|
89
95
|
getIdentifier: () => 'SHOULD_NEVER_SKIP',
|
|
90
96
|
process: updateSiteMapS3,
|
|
91
97
|
shouldSkipCheck: () => false,
|
|
92
|
-
estimatedDurationSec:
|
|
98
|
+
estimatedDurationSec: 90,
|
|
93
99
|
},
|
|
94
100
|
[TASKS_NAMES.scheduleContactFormEmailMigration]: {
|
|
95
101
|
name: TASKS_NAMES.scheduleContactFormEmailMigration,
|
|
@@ -119,6 +125,34 @@ const TASKS = {
|
|
|
119
125
|
shouldSkipCheck: () => false,
|
|
120
126
|
estimatedDurationSec: 45,
|
|
121
127
|
},
|
|
128
|
+
[TASKS_NAMES.scheduleMigrateExistingUrls]: {
|
|
129
|
+
name: TASKS_NAMES.scheduleMigrateExistingUrls,
|
|
130
|
+
getIdentifier: () => 'SHOULD_NEVER_SKIP',
|
|
131
|
+
process: scheduleMigrateExistingUrls,
|
|
132
|
+
shouldSkipCheck: () => false,
|
|
133
|
+
estimatedDurationSec: 160,
|
|
134
|
+
},
|
|
135
|
+
[TASKS_NAMES.migrateUrlsChunk]: {
|
|
136
|
+
name: TASKS_NAMES.migrateUrlsChunk,
|
|
137
|
+
getIdentifier: task => `chunk-${task.data.chunkIndex}`,
|
|
138
|
+
process: migrateUrlsChunk,
|
|
139
|
+
shouldSkipCheck: () => false,
|
|
140
|
+
estimatedDurationSec: 80,
|
|
141
|
+
},
|
|
142
|
+
[TASKS_NAMES.scheduleGenerateMissingUrls]: {
|
|
143
|
+
name: TASKS_NAMES.scheduleGenerateMissingUrls,
|
|
144
|
+
getIdentifier: () => 'SHOULD_NEVER_SKIP',
|
|
145
|
+
process: scheduleGenerateMissingUrls,
|
|
146
|
+
shouldSkipCheck: () => false,
|
|
147
|
+
estimatedDurationSec: 160,
|
|
148
|
+
},
|
|
149
|
+
[TASKS_NAMES.generateUrlsChunk]: {
|
|
150
|
+
name: TASKS_NAMES.generateUrlsChunk,
|
|
151
|
+
getIdentifier: task => `chunk-${task.data.chunkIndex}`,
|
|
152
|
+
process: generateUrlsChunk,
|
|
153
|
+
shouldSkipCheck: () => false,
|
|
154
|
+
estimatedDurationSec: 80,
|
|
155
|
+
},
|
|
122
156
|
};
|
|
123
157
|
|
|
124
158
|
module.exports = { TASKS };
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
const { taskManager } = require('psdev-task-manager');
|
|
2
|
+
|
|
3
|
+
const { COLLECTIONS } = require('../../public/consts');
|
|
4
|
+
const { ensureUniqueUrl } = require('../daily-pull/process-member-methods');
|
|
5
|
+
const { wixData } = require('../elevated-modules');
|
|
6
|
+
// const { bulkSaveMembers } = require('../members-data-methods');
|
|
7
|
+
const { queryAllItems, chunkArray } = require('../utils');
|
|
8
|
+
|
|
9
|
+
const { TASKS_NAMES } = require('./consts');
|
|
10
|
+
|
|
11
|
+
const COLLECTION_WITH_URLS = 'MembersDataWithUrls';
|
|
12
|
+
const CHUNK_SIZE = 5000; // 5k members per task
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Step 1: Migrate existing URLs from backup collection
|
|
16
|
+
* Queries backup collection and schedules tasks with memberIds and URLs
|
|
17
|
+
*/
|
|
18
|
+
async function scheduleMigrateExistingUrls() {
|
|
19
|
+
console.log('=== Scheduling Step 1: Migrate Existing URLs ===');
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const membersQuery = await wixData.query(COLLECTION_WITH_URLS);
|
|
23
|
+
const startTime = Date.now();
|
|
24
|
+
const membersWithUrls = await queryAllItems(membersQuery);
|
|
25
|
+
const endTime = Date.now();
|
|
26
|
+
console.log(`QueryAllItems time: ${endTime - startTime}ms`);
|
|
27
|
+
|
|
28
|
+
const validMembers = membersWithUrls.filter(member => member.memberId && member.url);
|
|
29
|
+
console.log(`${validMembers.length} members have valid memberId and URL`);
|
|
30
|
+
|
|
31
|
+
if (validMembers.length === 0) {
|
|
32
|
+
console.log('No members to migrate URLs for');
|
|
33
|
+
return {
|
|
34
|
+
success: true,
|
|
35
|
+
message: 'No members need URL migration',
|
|
36
|
+
totalMembers: 0,
|
|
37
|
+
tasksScheduled: 0,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const migrationData = validMembers.map(member => ({
|
|
42
|
+
memberId: member.memberId,
|
|
43
|
+
url: member.url,
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
const chunks = chunkArray(migrationData, CHUNK_SIZE);
|
|
47
|
+
|
|
48
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
49
|
+
const chunk = chunks[i];
|
|
50
|
+
const task = {
|
|
51
|
+
name: TASKS_NAMES.migrateUrlsChunk,
|
|
52
|
+
data: {
|
|
53
|
+
urlData: chunk,
|
|
54
|
+
chunkIndex: i,
|
|
55
|
+
totalChunks: chunks.length,
|
|
56
|
+
},
|
|
57
|
+
type: 'scheduled',
|
|
58
|
+
};
|
|
59
|
+
await taskManager().schedule(task);
|
|
60
|
+
console.log(`Scheduled migration task ${i + 1}/${chunks.length} (${chunk.length} members)`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const result = {
|
|
64
|
+
success: true,
|
|
65
|
+
message: `Scheduled ${chunks.length} tasks for ${validMembers.length} members`,
|
|
66
|
+
totalMembers: validMembers.length,
|
|
67
|
+
tasksScheduled: chunks.length,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
console.log('=== Migration Scheduling Complete ===');
|
|
71
|
+
console.log(JSON.stringify(result, null, 2));
|
|
72
|
+
|
|
73
|
+
return result;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error('Error scheduling URL migration:', error);
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Process a chunk of URL migrations (called by task manager)
|
|
82
|
+
* Fetches members by memberId and updates with URLs using bulkSave
|
|
83
|
+
*/
|
|
84
|
+
async function migrateUrlsChunk(data) {
|
|
85
|
+
const { urlData, chunkIndex, totalChunks } = data;
|
|
86
|
+
console.log(
|
|
87
|
+
`Processing migration chunk ${chunkIndex + 1}/${totalChunks} (${urlData.length} members)`
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const result = {
|
|
91
|
+
successful: 0,
|
|
92
|
+
failed: 0,
|
|
93
|
+
skipped: 0,
|
|
94
|
+
errors: [],
|
|
95
|
+
skippedIds: [],
|
|
96
|
+
failedIds: [],
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
const memberIds = urlData.map(({ memberId }) => memberId);
|
|
101
|
+
|
|
102
|
+
console.log(`Fetching ${memberIds.length} members from database...`);
|
|
103
|
+
const query = await wixData.query(COLLECTIONS.MEMBERS_DATA).hasSome('memberId', memberIds);
|
|
104
|
+
const members = await queryAllItems(query);
|
|
105
|
+
console.log(`Found ${members.length} members in database`);
|
|
106
|
+
|
|
107
|
+
const memberMap = new Map();
|
|
108
|
+
members.forEach(member => {
|
|
109
|
+
if (member.memberId) {
|
|
110
|
+
memberMap.set(member.memberId, member);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const membersToUpdate = [];
|
|
115
|
+
for (const { memberId, url } of urlData) {
|
|
116
|
+
const member = memberMap.get(memberId);
|
|
117
|
+
|
|
118
|
+
if (!member) {
|
|
119
|
+
console.log(`Member with memberId ${memberId} not found - skipping`);
|
|
120
|
+
result.skipped++;
|
|
121
|
+
result.skippedIds.push(memberId);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (member.url === url) {
|
|
126
|
+
console.log(`Member ${member._id} already has URL ${url} - skipping`);
|
|
127
|
+
result.skipped++;
|
|
128
|
+
result.skippedIds.push(memberId);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
membersToUpdate.push({
|
|
133
|
+
...member,
|
|
134
|
+
url: url,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (membersToUpdate.length === 0) {
|
|
139
|
+
console.log('No members need updating in this batch');
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
console.log(
|
|
144
|
+
`Started updating ${membersToUpdate.length} members with URLs in chunk ${chunkIndex}`
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
// keep bulk save as comment for now, since we are just testing the query and update logic
|
|
149
|
+
// await bulkSaveMembers(membersToUpdate);
|
|
150
|
+
result.successful += membersToUpdate.length;
|
|
151
|
+
console.log(`✅ Successfully updated ${membersToUpdate.length} members`);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error(`❌ Error bulk saving members:`, error);
|
|
154
|
+
result.failed += membersToUpdate.length;
|
|
155
|
+
// Add all member IDs to failedIds
|
|
156
|
+
result.failedIds.push(...membersToUpdate.map(m => m.memberId));
|
|
157
|
+
result.errors.push({
|
|
158
|
+
error: error.message,
|
|
159
|
+
memberCount: membersToUpdate.length,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
console.log(
|
|
164
|
+
`Chunk ${chunkIndex + 1} complete: ${result.successful} success, ${result.failed} failed, ${result.skipped} skipped`
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// Log failed and skipped IDs if any
|
|
168
|
+
if (result.failedIds.length > 0) {
|
|
169
|
+
console.log(`❌ Failed memberIds (${result.failedIds.length}):`, result.failedIds);
|
|
170
|
+
}
|
|
171
|
+
if (result.skippedIds.length > 0) {
|
|
172
|
+
console.log(`⏭️ Skipped memberIds (${result.skippedIds.length}):`, result.skippedIds);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return result;
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error(`Error processing migration chunk ${chunkIndex}:`, error);
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Step 2: Generate URLs for members without URLs
|
|
184
|
+
* Queries members without URLs and schedules generation tasks
|
|
185
|
+
*/
|
|
186
|
+
async function scheduleGenerateMissingUrls() {
|
|
187
|
+
console.log('=== Scheduling Step 2: Generate Missing URLs ===');
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
const membersQuery = await wixData.query(COLLECTIONS.MEMBERS_DATA).isEmpty('url');
|
|
191
|
+
const membersToUpdate = await queryAllItems(membersQuery);
|
|
192
|
+
|
|
193
|
+
console.log(`Found ${membersToUpdate.length} members without URLs`);
|
|
194
|
+
|
|
195
|
+
if (membersToUpdate.length === 0) {
|
|
196
|
+
console.log('No members need URL generation');
|
|
197
|
+
return {
|
|
198
|
+
success: true,
|
|
199
|
+
message: 'No members need URL generation',
|
|
200
|
+
totalMembers: 0,
|
|
201
|
+
tasksScheduled: 0,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const chunks = chunkArray(membersToUpdate, CHUNK_SIZE);
|
|
206
|
+
|
|
207
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
208
|
+
const chunk = chunks[i];
|
|
209
|
+
const task = {
|
|
210
|
+
name: TASKS_NAMES.generateUrlsChunk,
|
|
211
|
+
data: {
|
|
212
|
+
memberIds: chunk.map(m => m._id),
|
|
213
|
+
chunkIndex: i,
|
|
214
|
+
totalChunks: chunks.length,
|
|
215
|
+
},
|
|
216
|
+
type: 'scheduled',
|
|
217
|
+
};
|
|
218
|
+
await taskManager().schedule(task);
|
|
219
|
+
console.log(`Scheduled generation task ${i + 1}/${chunks.length} (${chunk.length} members)`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const result = {
|
|
223
|
+
success: true,
|
|
224
|
+
message: `Scheduled ${chunks.length} tasks for ${membersToUpdate.length} members`,
|
|
225
|
+
totalMembers: membersToUpdate.length,
|
|
226
|
+
tasksScheduled: chunks.length,
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
console.log('=== Generation Scheduling Complete ===');
|
|
230
|
+
console.log(JSON.stringify(result, null, 2));
|
|
231
|
+
|
|
232
|
+
return result;
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error('Error scheduling URL generation:', error);
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Process a chunk of URL generation (called by task manager)
|
|
241
|
+
* Fetches members, generates URLs, and bulk saves
|
|
242
|
+
*/
|
|
243
|
+
async function generateUrlsChunk(data) {
|
|
244
|
+
const { memberIds, chunkIndex, totalChunks } = data;
|
|
245
|
+
console.log(
|
|
246
|
+
`Processing generation chunk ${chunkIndex + 1}/${totalChunks} (${memberIds.length} members)`
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
const result = {
|
|
250
|
+
successful: 0,
|
|
251
|
+
failed: 0,
|
|
252
|
+
skipped: 0,
|
|
253
|
+
errors: [],
|
|
254
|
+
skippedIds: [],
|
|
255
|
+
failedIds: [],
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
// Fetch all members at once using hasSome
|
|
260
|
+
console.log(`Fetching ${memberIds.length} members from database...`);
|
|
261
|
+
const members = await queryAllItems(
|
|
262
|
+
wixData.query(COLLECTIONS.MEMBERS_DATA).hasSome('_id', memberIds)
|
|
263
|
+
);
|
|
264
|
+
console.log(`Found ${members.length} members in database`);
|
|
265
|
+
|
|
266
|
+
// Create a map of _id -> member for quick lookup
|
|
267
|
+
const memberMap = new Map();
|
|
268
|
+
members.forEach(member => {
|
|
269
|
+
memberMap.set(member._id, member);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Process each member and generate URLs
|
|
273
|
+
const membersToUpdate = [];
|
|
274
|
+
for (const memberId of memberIds) {
|
|
275
|
+
const member = memberMap.get(memberId);
|
|
276
|
+
|
|
277
|
+
if (!member) {
|
|
278
|
+
console.log(`Member ${memberId} not found - skipping`);
|
|
279
|
+
result.skipped++;
|
|
280
|
+
result.skippedIds.push(memberId);
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (member.url) {
|
|
285
|
+
console.log(`Member ${memberId} already has URL - skipping`);
|
|
286
|
+
result.skipped++;
|
|
287
|
+
result.skippedIds.push(memberId);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const name = member.fullName || `${member.firstName || ''} ${member.lastName || ''}`.trim();
|
|
292
|
+
|
|
293
|
+
if (!name) {
|
|
294
|
+
console.error(`Member ${memberId} has no name data - skipping`);
|
|
295
|
+
result.failed++;
|
|
296
|
+
result.failedIds.push(memberId);
|
|
297
|
+
result.errors.push({
|
|
298
|
+
memberId,
|
|
299
|
+
error: 'No name data available',
|
|
300
|
+
});
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
const uniqueUrl = await ensureUniqueUrl({
|
|
306
|
+
url: '',
|
|
307
|
+
memberId: member._id,
|
|
308
|
+
fullName: name,
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
console.log(`✅ Generated URL for member ${memberId}: ${uniqueUrl}`);
|
|
312
|
+
membersToUpdate.push({
|
|
313
|
+
...member,
|
|
314
|
+
url: uniqueUrl,
|
|
315
|
+
});
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error(`❌ Failed to generate URL for member ${memberId}:`, error);
|
|
318
|
+
result.failed++;
|
|
319
|
+
result.failedIds.push(memberId);
|
|
320
|
+
result.errors.push({
|
|
321
|
+
memberId,
|
|
322
|
+
error: error.message || 'Unknown error',
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (membersToUpdate.length === 0) {
|
|
328
|
+
console.log('No members need updating in this batch');
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
console.log(
|
|
333
|
+
`Started updating ${membersToUpdate.length} members with generated URLs in chunk ${chunkIndex}`
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
try {
|
|
337
|
+
// keep bulk save as comment for now, since we are just testing the query and update logic
|
|
338
|
+
// await bulkSaveMembers(membersToUpdate);
|
|
339
|
+
result.successful += membersToUpdate.length;
|
|
340
|
+
console.log(`✅ Successfully updated ${membersToUpdate.length} members`);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
console.error(`❌ Error bulk saving members:`, error);
|
|
343
|
+
result.failed += membersToUpdate.length;
|
|
344
|
+
// Add all member _ids to failedIds
|
|
345
|
+
result.failedIds.push(...membersToUpdate.map(m => m._id));
|
|
346
|
+
result.errors.push({
|
|
347
|
+
error: error.message,
|
|
348
|
+
memberCount: membersToUpdate.length,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
console.log(
|
|
353
|
+
`Chunk ${chunkIndex + 1} complete: ${result.successful} success, ${result.failed} failed, ${result.skipped} skipped`
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
// Log failed and skipped IDs if any
|
|
357
|
+
if (result.failedIds.length > 0) {
|
|
358
|
+
console.log(`❌ Failed memberIds (${result.failedIds.length}):`, result.failedIds);
|
|
359
|
+
}
|
|
360
|
+
if (result.skippedIds.length > 0) {
|
|
361
|
+
console.log(`⏭️ Skipped memberIds (${result.skippedIds.length}):`, result.skippedIds);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return result;
|
|
365
|
+
} catch (error) {
|
|
366
|
+
console.error(`Error processing generation chunk ${chunkIndex}:`, error);
|
|
367
|
+
throw error;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
module.exports = {
|
|
372
|
+
scheduleMigrateExistingUrls,
|
|
373
|
+
migrateUrlsChunk,
|
|
374
|
+
scheduleGenerateMissingUrls,
|
|
375
|
+
generateUrlsChunk,
|
|
376
|
+
};
|
package/backend/utils.js
CHANGED
|
@@ -111,8 +111,10 @@ const getAllItems = async querySearchResult => {
|
|
|
111
111
|
let oldResults = querySearchResult;
|
|
112
112
|
console.log(`found items: ${oldResults.items.length}`);
|
|
113
113
|
const allItems = oldResults.items;
|
|
114
|
+
console.log(`total pages: ${oldResults.totalPages}`);
|
|
114
115
|
while (oldResults.hasNext()) {
|
|
115
116
|
oldResults = await oldResults.next();
|
|
117
|
+
console.log(`next page: ${oldResults.currentPage}`);
|
|
116
118
|
allItems.push(...oldResults.items);
|
|
117
119
|
}
|
|
118
120
|
console.log(`all items count : ${allItems.length}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "abmp-npm",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.7",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"check-cycles": "madge --circular .",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@wix/automations": "^1.0.261",
|
|
33
33
|
"@wix/crm": "^1.0.1061",
|
|
34
|
-
"@wix/data": "^1.0.
|
|
34
|
+
"@wix/data": "^1.0.349",
|
|
35
35
|
"@wix/essentials": "^0.1.28",
|
|
36
36
|
"@wix/identity": "^1.0.178",
|
|
37
37
|
"@wix/media": "^1.0.213",
|
package/pages/Profile.js
CHANGED
|
@@ -62,8 +62,8 @@ async function profileOnReady({ $w: _$w }) {
|
|
|
62
62
|
_$w('#moreAdressesRepeater').data = profileData.processedAddresses;
|
|
63
63
|
|
|
64
64
|
if (profileData.processedAddresses.length > 0) {
|
|
65
|
-
_$w('#moreLocationButton').
|
|
66
|
-
_$w('#addressTitle').
|
|
65
|
+
_$w('#moreLocationButton').expand();
|
|
66
|
+
_$w('#addressTitle').collapse();
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
_$w('#moreAdressesRepeater').onItemReady(($item, itemData) => {
|
|
@@ -81,9 +81,9 @@ async function profileOnReady({ $w: _$w }) {
|
|
|
81
81
|
const $container = _$w(containerId);
|
|
82
82
|
|
|
83
83
|
$button.onClick(() => {
|
|
84
|
-
const
|
|
85
|
-
$container[
|
|
86
|
-
$button.label =
|
|
84
|
+
const isCollapsed = $container.collapsed;
|
|
85
|
+
$container[isCollapsed ? 'expand' : 'collapse']();
|
|
86
|
+
$button.label = isCollapsed ? 'Less Locations -' : 'More Locations +';
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -104,7 +104,7 @@ async function profileOnReady({ $w: _$w }) {
|
|
|
104
104
|
|
|
105
105
|
function bindStudentBadge() {
|
|
106
106
|
if (profileData.shouldHaveStudentBadge) {
|
|
107
|
-
_$w('#studentContainer, #studentContainerMobile').
|
|
107
|
+
_$w('#studentContainer, #studentContainerMobile').expand();
|
|
108
108
|
} else {
|
|
109
109
|
_$w('#studentContainer, #studentContainerMobile').delete();
|
|
110
110
|
}
|
|
@@ -201,7 +201,7 @@ async function profileOnReady({ $w: _$w }) {
|
|
|
201
201
|
function bindBusinessName() {
|
|
202
202
|
if (profileData.businessName) {
|
|
203
203
|
_$w('#businessName').text = profileData.businessName;
|
|
204
|
-
_$w('#businessName').
|
|
204
|
+
_$w('#businessName').expand();
|
|
205
205
|
} else {
|
|
206
206
|
_$w('#businessName').delete();
|
|
207
207
|
}
|
|
@@ -265,7 +265,7 @@ async function profileOnReady({ $w: _$w }) {
|
|
|
265
265
|
function setupTestimonialsIfAvailable() {
|
|
266
266
|
if (profileData.testimonials.length > 0) {
|
|
267
267
|
setupTestimonialsPagination(profileData.testimonials);
|
|
268
|
-
_$w('#testimonialsSection').
|
|
268
|
+
_$w('#testimonialsSection').expand();
|
|
269
269
|
} else {
|
|
270
270
|
_$w('#testimonialsSection').delete();
|
|
271
271
|
}
|
|
@@ -332,15 +332,15 @@ async function profileOnReady({ $w: _$w }) {
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
function updateTestimonialNavigation(end, totalLength) {
|
|
335
|
-
_$w('#prevTestimonialBtn').
|
|
336
|
-
_$w('#nextTestimonialBtn').
|
|
335
|
+
_$w('#prevTestimonialBtn').hide();
|
|
336
|
+
_$w('#nextTestimonialBtn').hide();
|
|
337
337
|
|
|
338
338
|
if (currentTestimonialPage > 0) {
|
|
339
|
-
_$w('#prevTestimonialBtn').
|
|
339
|
+
_$w('#prevTestimonialBtn').show();
|
|
340
340
|
}
|
|
341
341
|
|
|
342
342
|
if (end < totalLength) {
|
|
343
|
-
_$w('#nextTestimonialBtn').
|
|
343
|
+
_$w('#nextTestimonialBtn').show();
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
346
|
}
|