bulltrackers-module 1.0.462 → 1.0.463
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.
|
@@ -213,6 +213,30 @@ async function updateWatchlist(req, res, dependencies, config) {
|
|
|
213
213
|
return res.status(403).json({ error: "You can only modify your own watchlists" });
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
+
// Check if this is a copied watchlist
|
|
217
|
+
const isCopiedWatchlist = existingData.copiedFrom && existingData.copiedFromCreator;
|
|
218
|
+
const wasModified = existingData.hasBeenModified || false;
|
|
219
|
+
|
|
220
|
+
// Determine if meaningful changes are being made (not just name)
|
|
221
|
+
let hasMeaningfulChanges = wasModified;
|
|
222
|
+
if (items !== undefined && existingData.type === 'static') {
|
|
223
|
+
// Check if items actually changed
|
|
224
|
+
const itemsChanged = JSON.stringify(items) !== JSON.stringify(existingData.items || []);
|
|
225
|
+
hasMeaningfulChanges = hasMeaningfulChanges || itemsChanged;
|
|
226
|
+
}
|
|
227
|
+
if (dynamicConfig !== undefined && existingData.type === 'dynamic') {
|
|
228
|
+
// Check if dynamicConfig actually changed
|
|
229
|
+
const configChanged = JSON.stringify(dynamicConfig) !== JSON.stringify(existingData.dynamicConfig || {});
|
|
230
|
+
hasMeaningfulChanges = hasMeaningfulChanges || configChanged;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// If trying to make a copied watchlist public, check if meaningful changes were made
|
|
234
|
+
if (visibility === 'public' && isCopiedWatchlist && !hasMeaningfulChanges) {
|
|
235
|
+
return res.status(400).json({
|
|
236
|
+
error: "Cannot publish copied watchlist without making meaningful changes. Please modify the watchlist items, thresholds, or parameters before publishing."
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
216
240
|
const updates = {
|
|
217
241
|
updatedAt: FieldValue.serverTimestamp()
|
|
218
242
|
};
|
|
@@ -221,6 +245,11 @@ async function updateWatchlist(req, res, dependencies, config) {
|
|
|
221
245
|
updates.name = name.trim();
|
|
222
246
|
}
|
|
223
247
|
|
|
248
|
+
// Track if watchlist has been modified (for copied watchlists)
|
|
249
|
+
if (isCopiedWatchlist && hasMeaningfulChanges) {
|
|
250
|
+
updates.hasBeenModified = true;
|
|
251
|
+
}
|
|
252
|
+
|
|
224
253
|
if (visibility !== undefined) {
|
|
225
254
|
if (visibility !== 'public' && visibility !== 'private') {
|
|
226
255
|
return res.status(400).json({ error: "Visibility must be 'public' or 'private'" });
|
|
@@ -235,7 +264,7 @@ async function updateWatchlist(req, res, dependencies, config) {
|
|
|
235
264
|
createdBy: existingData.createdBy,
|
|
236
265
|
name: updates.name || existingData.name,
|
|
237
266
|
type: existingData.type,
|
|
238
|
-
description: dynamicConfig?.description || '',
|
|
267
|
+
description: (dynamicConfig?.description || existingData.dynamicConfig?.description || ''),
|
|
239
268
|
copyCount: existingData.copyCount || 0,
|
|
240
269
|
createdAt: existingData.createdAt,
|
|
241
270
|
updatedAt: FieldValue.serverTimestamp()
|
|
@@ -345,6 +374,8 @@ async function copyWatchlist(req, res, dependencies, config) {
|
|
|
345
374
|
return res.status(400).json({ error: "Missing userCid or watchlist id" });
|
|
346
375
|
}
|
|
347
376
|
|
|
377
|
+
const userCidNum = Number(userCid);
|
|
378
|
+
|
|
348
379
|
try {
|
|
349
380
|
// First, try to find in public watchlists
|
|
350
381
|
const publicRef = db.collection('public_watchlists').doc(id);
|
|
@@ -355,10 +386,11 @@ async function copyWatchlist(req, res, dependencies, config) {
|
|
|
355
386
|
}
|
|
356
387
|
|
|
357
388
|
const publicData = publicDoc.data();
|
|
389
|
+
const originalCreatorCid = Number(publicData.createdBy);
|
|
358
390
|
|
|
359
391
|
// Find the original watchlist
|
|
360
392
|
const originalRef = db.collection(config.watchlistsCollection || 'watchlists')
|
|
361
|
-
.doc(String(
|
|
393
|
+
.doc(String(originalCreatorCid))
|
|
362
394
|
.collection('lists')
|
|
363
395
|
.doc(id);
|
|
364
396
|
|
|
@@ -370,15 +402,52 @@ async function copyWatchlist(req, res, dependencies, config) {
|
|
|
370
402
|
|
|
371
403
|
const originalData = originalDoc.data();
|
|
372
404
|
|
|
405
|
+
// Check if user is copying their own watchlist
|
|
406
|
+
const isCopyingOwn = originalCreatorCid === userCidNum;
|
|
407
|
+
|
|
408
|
+
// If copying own watchlist, find existing copies to determine number
|
|
409
|
+
let copyNumber = 1;
|
|
410
|
+
let newName = name;
|
|
411
|
+
|
|
412
|
+
if (isCopyingOwn) {
|
|
413
|
+
// Get all watchlists by this user to find existing copies
|
|
414
|
+
const userWatchlistsRef = db.collection(config.watchlistsCollection || 'watchlists')
|
|
415
|
+
.doc(String(userCidNum))
|
|
416
|
+
.collection('lists');
|
|
417
|
+
|
|
418
|
+
const userWatchlistsSnapshot = await userWatchlistsRef.get();
|
|
419
|
+
const baseName = originalData.name.replace(/\s*#\d+$/, ''); // Remove existing #N suffix
|
|
420
|
+
|
|
421
|
+
// Count existing copies (including original)
|
|
422
|
+
const existingCopies = [];
|
|
423
|
+
userWatchlistsSnapshot.forEach(doc => {
|
|
424
|
+
const data = doc.data();
|
|
425
|
+
const docName = data.name.replace(/\s*#\d+$/, '');
|
|
426
|
+
if (docName === baseName || docName === originalData.name) {
|
|
427
|
+
existingCopies.push(data);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
// Determine next copy number
|
|
432
|
+
copyNumber = existingCopies.length + 1;
|
|
433
|
+
newName = name || `${baseName} #${copyNumber}`;
|
|
434
|
+
} else {
|
|
435
|
+
// Copying someone else's watchlist
|
|
436
|
+
newName = name || `${originalData.name} (Copy)`;
|
|
437
|
+
}
|
|
438
|
+
|
|
373
439
|
// Create new watchlist for the copying user
|
|
374
440
|
const newWatchlistId = generateWatchlistId();
|
|
375
441
|
const watchlistData = {
|
|
376
442
|
...originalData,
|
|
377
443
|
id: newWatchlistId,
|
|
378
|
-
name:
|
|
379
|
-
createdBy:
|
|
444
|
+
name: newName,
|
|
445
|
+
createdBy: userCidNum,
|
|
380
446
|
visibility: 'private', // Copied watchlists are always private
|
|
381
447
|
copiedFrom: id,
|
|
448
|
+
copiedFromCreator: originalCreatorCid,
|
|
449
|
+
originalName: originalData.name, // Store original name for comparison
|
|
450
|
+
hasBeenModified: false, // Track if user made meaningful changes
|
|
382
451
|
createdAt: FieldValue.serverTimestamp(),
|
|
383
452
|
updatedAt: FieldValue.serverTimestamp(),
|
|
384
453
|
isAutoGenerated: false
|
|
@@ -388,19 +457,21 @@ async function copyWatchlist(req, res, dependencies, config) {
|
|
|
388
457
|
delete watchlistData.copyCount;
|
|
389
458
|
|
|
390
459
|
const newWatchlistRef = db.collection(config.watchlistsCollection || 'watchlists')
|
|
391
|
-
.doc(String(
|
|
460
|
+
.doc(String(userCidNum))
|
|
392
461
|
.collection('lists')
|
|
393
462
|
.doc(newWatchlistId);
|
|
394
463
|
|
|
395
464
|
await newWatchlistRef.set(watchlistData);
|
|
396
465
|
|
|
397
|
-
// Increment copy count on original
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
466
|
+
// Increment copy count on original (only if copying someone else's)
|
|
467
|
+
if (!isCopyingOwn) {
|
|
468
|
+
await publicRef.update({
|
|
469
|
+
copyCount: FieldValue.increment(1),
|
|
470
|
+
updatedAt: FieldValue.serverTimestamp()
|
|
471
|
+
});
|
|
472
|
+
}
|
|
402
473
|
|
|
403
|
-
logger.log('SUCCESS', `[copyWatchlist] User ${userCid} copied watchlist ${id} as ${newWatchlistId}`);
|
|
474
|
+
logger.log('SUCCESS', `[copyWatchlist] User ${userCid} copied watchlist ${id} as ${newWatchlistId}${isCopyingOwn ? ' (own watchlist)' : ''}`);
|
|
404
475
|
|
|
405
476
|
return res.status(201).json({
|
|
406
477
|
success: true,
|