bulltrackers-module 1.0.469 → 1.0.471

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.
@@ -235,12 +235,38 @@ exports.runRootDataIndexer = async (config, dependencies) => {
235
235
  // Path: {verifications} (Limit 1) - Checks if collection is non-empty generally
236
236
  const verificationsRef = db.collection(collections.verifications || 'user_verifications');
237
237
 
238
- // 4. Universal Social Check via Collection Group
239
- // Path: Collection Group 'posts' where 'fetchedAt' is within the day
240
- const universalSocialQuery = db.collectionGroup('posts')
241
- .where('fetchedAt', '>=', dayStart)
242
- .where('fetchedAt', '<=', dayEnd)
243
- .limit(50);
238
+ // 4. Social Data Checks - Use date tracking documents
239
+ // Single tracking documents at root level:
240
+ // - pi_social_posts/_dates -> fetchedDates.{date}
241
+ // - signed_in_users_social/_dates -> fetchedDates.{date}
242
+ // For generic social (daily_social_insights), check the collection directly
243
+ const [piSocialTrackingDoc, signedInSocialTrackingDoc, genericSocialSnap] = await Promise.all([
244
+ db.collection(PI_SOCIAL_COLL_NAME).doc('_dates').get(),
245
+ db.collection(SIGNED_IN_SOCIAL_COLL_NAME).doc('_dates').get(),
246
+ db.collectionGroup('posts')
247
+ .where('fetchedAt', '>=', dayStart)
248
+ .where('fetchedAt', '<=', dayEnd)
249
+ .limit(1)
250
+ .get()
251
+ ]);
252
+
253
+ // Check if date exists in tracking documents
254
+ let foundPISocial = false;
255
+ let foundSignedInSocial = false;
256
+
257
+ if (piSocialTrackingDoc.exists) {
258
+ const data = piSocialTrackingDoc.data();
259
+ if (data.fetchedDates && data.fetchedDates[dateStr] === true) {
260
+ foundPISocial = true;
261
+ }
262
+ }
263
+
264
+ if (signedInSocialTrackingDoc.exists) {
265
+ const data = signedInSocialTrackingDoc.data();
266
+ if (data.fetchedDates && data.fetchedDates[dateStr] === true) {
267
+ foundSignedInSocial = true;
268
+ }
269
+ }
244
270
 
245
271
  // --- Execute Checks ---
246
272
  const [
@@ -252,8 +278,7 @@ exports.runRootDataIndexer = async (config, dependencies) => {
252
278
  piDeepExists,
253
279
  piHistExists,
254
280
  signedInPortExists, signedInHistExists,
255
- verificationsQuery,
256
- universalSocialSnap
281
+ verificationsQuery
257
282
  ] = await Promise.all([
258
283
  checkAnyPartExists(normPortPartsRef),
259
284
  checkAnyPartExists(specPortPartsRef),
@@ -267,43 +292,12 @@ exports.runRootDataIndexer = async (config, dependencies) => {
267
292
  checkAnyPartExists(piHistoryPartsRef),
268
293
  checkAnyPartExists(signedInPortPartsRef),
269
294
  checkAnyPartExists(signedInHistPartsRef),
270
- verificationsRef.limit(1).get(),
271
- universalSocialQuery.get()
295
+ verificationsRef.limit(1).get()
272
296
  ]);
273
297
 
274
- // --- Evaluate Social Sources ---
275
- let foundPISocial = false;
276
- let foundSignedInSocial = false;
277
-
278
- if (!universalSocialSnap.empty) {
279
- logger.log('DEBUG', `[RootDataIndexer/${dateStr}] Found ${universalSocialSnap.docs.length} social posts in query`);
280
- universalSocialSnap.docs.forEach(doc => {
281
- const path = doc.ref.path;
282
- const data = doc.data();
283
- const fetchedAt = data.fetchedAt;
284
-
285
- // Use includes() to match collection name anywhere in path (more robust)
286
- // Path format: {collectionName}/{userId}/posts/{postId}
287
- // Firestore paths don't have leading slash, so check both with and without
288
- const piMatchPattern = `${PI_SOCIAL_COLL_NAME}/`;
289
- const signedInMatchPattern = `${SIGNED_IN_SOCIAL_COLL_NAME}/`;
290
-
291
- if (path.includes(piMatchPattern) || path.startsWith(piMatchPattern)) {
292
- foundPISocial = true;
293
- logger.log('DEBUG', `[RootDataIndexer/${dateStr}] ✓ Found PI social: ${path}`);
294
- }
295
- if (path.includes(signedInMatchPattern) || path.startsWith(signedInMatchPattern)) {
296
- foundSignedInSocial = true;
297
- const fetchedAtStr = fetchedAt ? (fetchedAt.toDate ? fetchedAt.toDate().toISOString() : String(fetchedAt)) : 'missing';
298
- logger.log('DEBUG', `[RootDataIndexer/${dateStr}] ✓ Found signed-in social: ${path}, fetchedAt: ${fetchedAtStr}`);
299
- } else if (!path.includes(piMatchPattern)) {
300
- // Log paths that don't match either pattern to help debug
301
- logger.log('DEBUG', `[RootDataIndexer/${dateStr}] ✗ Path doesn't match: ${path} (looking for: "${signedInMatchPattern}" or "${piMatchPattern}")`);
302
- }
303
- });
304
- } else {
305
- logger.log('DEBUG', `[RootDataIndexer/${dateStr}] No social posts found in query (dayStart: ${dayStart.toISOString()}, dayEnd: ${dayEnd.toISOString()})`);
306
- }
298
+ // Social data checks are done above using tracking documents
299
+ // foundPISocial and foundSignedInSocial are already set from the tracking document checks
300
+ logger.log('INFO', `[RootDataIndexer/${dateStr}] Social check results - PI: ${foundPISocial}, Signed-in: ${foundSignedInSocial}`);
307
301
 
308
302
  // --- Assign to Availability ---
309
303
  availability.details.normalPortfolio = normPortExists;
@@ -351,6 +351,30 @@ exports.handleSocialTask = async (message, context, config, dependencies) => {
351
351
  offset += take;
352
352
  }
353
353
 
354
+ // Write date tracking document after successful fetch
355
+ // Single document at root level: /signed_in_users_social/_dates and /pi_social_posts/_dates
356
+ // Contains a map of all dates that have been fetched
357
+ if (totalSaved > 0 && (type === 'SIGNED_IN_USER' || type === 'POPULAR_INVESTOR')) {
358
+ const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
359
+ let trackingCollectionPath;
360
+
361
+ if (type === 'SIGNED_IN_USER') {
362
+ trackingCollectionPath = config.signedInUserSocialCollection || 'signed_in_users_social';
363
+ } else {
364
+ trackingCollectionPath = config.piSocialCollectionName || 'pi_social_posts';
365
+ }
366
+
367
+ // Write to a single tracking document at the root of the collection
368
+ const trackingDocRef = db.collection(trackingCollectionPath).doc('_dates');
369
+ const trackingData = {
370
+ [`fetchedDates.${today}`]: true,
371
+ lastUpdated: FieldValue.serverTimestamp()
372
+ };
373
+
374
+ await trackingDocRef.set(trackingData, { merge: true });
375
+ logger.log('INFO', `[SocialTask/${taskId}] Updated date tracking for ${type}: ${today}`);
376
+ }
377
+
354
378
  logger.log('SUCCESS', `[SocialTask/${taskId}] Process complete for ${cid}. Total stored: ${totalSaved}/${MAX_POSTS_TO_STORE}`);
355
379
 
356
380
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.469",
3
+ "version": "1.0.471",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [