bulltrackers-module 1.0.440 → 1.0.441
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.
|
@@ -275,17 +275,52 @@ async function getPiFetchStatus(req, res, dependencies, config) {
|
|
|
275
275
|
|
|
276
276
|
if (!requestsSnapshot.empty) {
|
|
277
277
|
const latestRequest = requestsSnapshot.docs[0].data();
|
|
278
|
-
|
|
278
|
+
let status = latestRequest.status || 'queued';
|
|
279
|
+
|
|
280
|
+
// If status is 'indexing' or 'computing', check if computation results are now available
|
|
281
|
+
if (status === 'indexing' || status === 'computing') {
|
|
282
|
+
// Re-check if computation results exist
|
|
283
|
+
const checkDate = new Date();
|
|
284
|
+
for (let i = 0; i < 2; i++) { // Check today and yesterday
|
|
285
|
+
const dateStr = new Date(checkDate);
|
|
286
|
+
dateStr.setDate(checkDate.getDate() - i);
|
|
287
|
+
const dateStrFormatted = dateStr.toISOString().split('T')[0];
|
|
288
|
+
|
|
289
|
+
const docRef = db.collection(insightsCollection)
|
|
290
|
+
.doc(dateStrFormatted)
|
|
291
|
+
.collection(resultsSub)
|
|
292
|
+
.doc('popular-investor')
|
|
293
|
+
.collection(compsSub)
|
|
294
|
+
.doc('PopularInvestorProfileMetrics');
|
|
295
|
+
|
|
296
|
+
const doc = await docRef.get();
|
|
297
|
+
if (doc.exists) {
|
|
298
|
+
const { tryDecompress } = require('./data_helpers');
|
|
299
|
+
const data = tryDecompress(doc.data());
|
|
300
|
+
|
|
301
|
+
if (data && data[String(piCidNum)]) {
|
|
302
|
+
// Computation completed! Update status
|
|
303
|
+
status = 'completed';
|
|
304
|
+
await requestsSnapshot.docs[0].ref.update({
|
|
305
|
+
status: 'completed',
|
|
306
|
+
completedAt: require('@google-cloud/firestore').FieldValue.serverTimestamp(),
|
|
307
|
+
updatedAt: require('@google-cloud/firestore').FieldValue.serverTimestamp()
|
|
308
|
+
});
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
279
314
|
|
|
280
315
|
const response = {
|
|
281
316
|
success: true,
|
|
282
|
-
dataAvailable:
|
|
317
|
+
dataAvailable: status === 'completed',
|
|
283
318
|
status,
|
|
284
319
|
requestId: latestRequest.requestId,
|
|
285
320
|
startedAt: latestRequest.startedAt?.toDate?.()?.toISOString() || null,
|
|
286
321
|
createdAt: latestRequest.createdAt?.toDate?.()?.toISOString() || null,
|
|
287
322
|
estimatedCompletion: latestRequest.startedAt
|
|
288
|
-
? new Date(new Date(latestRequest.startedAt.toDate()).getTime() +
|
|
323
|
+
? new Date(new Date(latestRequest.startedAt.toDate()).getTime() + 10 * 60 * 1000).toISOString() // 10 min for computation
|
|
289
324
|
: null
|
|
290
325
|
};
|
|
291
326
|
|
|
@@ -295,6 +330,12 @@ async function getPiFetchStatus(req, res, dependencies, config) {
|
|
|
295
330
|
response.failedAt = latestRequest.failedAt?.toDate?.()?.toISOString() || null;
|
|
296
331
|
}
|
|
297
332
|
|
|
333
|
+
// Include raw data status if computing
|
|
334
|
+
if (status === 'computing') {
|
|
335
|
+
response.rawDataStoredAt = latestRequest.rawDataStoredAt?.toDate?.()?.toISOString() || null;
|
|
336
|
+
response.message = 'Raw data stored, computation in progress...';
|
|
337
|
+
}
|
|
338
|
+
|
|
298
339
|
return res.status(200).json(response);
|
|
299
340
|
}
|
|
300
341
|
|
|
@@ -19,7 +19,7 @@ const { shouldTryProxy, recordProxyOutcome, getFailureCount, getMaxFailures } =
|
|
|
19
19
|
* @param {object} dependencies - db, logger, proxyManager, batchManager, headerManager.
|
|
20
20
|
*/
|
|
21
21
|
async function handlePopularInvestorUpdate(taskData, config, dependencies) {
|
|
22
|
-
const { logger, proxyManager, batchManager, headerManager, db } = dependencies;
|
|
22
|
+
const { logger, proxyManager, batchManager, headerManager, db, pubsub } = dependencies;
|
|
23
23
|
|
|
24
24
|
// Validate taskData exists and has required fields
|
|
25
25
|
if (!taskData) {
|
|
@@ -299,7 +299,7 @@ async function handlePopularInvestorUpdate(taskData, config, dependencies) {
|
|
|
299
299
|
|
|
300
300
|
logger.log('SUCCESS', `[PI Update] Completed full update for ${username}`);
|
|
301
301
|
|
|
302
|
-
// Update request status
|
|
302
|
+
// Update request status and trigger computation if this is an on-demand request
|
|
303
303
|
if (requestId && source === 'on_demand' && db) {
|
|
304
304
|
try {
|
|
305
305
|
const requestRef = db.collection('pi_fetch_requests')
|
|
@@ -307,13 +307,82 @@ async function handlePopularInvestorUpdate(taskData, config, dependencies) {
|
|
|
307
307
|
.collection('requests')
|
|
308
308
|
.doc(requestId);
|
|
309
309
|
|
|
310
|
+
// Update status to indicate raw data is stored, indexing and computation will be triggered
|
|
310
311
|
await requestRef.update({
|
|
311
|
-
status: '
|
|
312
|
-
|
|
312
|
+
status: 'indexing',
|
|
313
|
+
rawDataStoredAt: require('@google-cloud/firestore').FieldValue.serverTimestamp(),
|
|
313
314
|
updatedAt: require('@google-cloud/firestore').FieldValue.serverTimestamp()
|
|
314
315
|
});
|
|
316
|
+
|
|
317
|
+
// CRITICAL: Trigger root data indexer FIRST so computation system knows data exists
|
|
318
|
+
try {
|
|
319
|
+
const { runRootDataIndexer } = require('../../root-data-indexer/index');
|
|
320
|
+
const indexerConfig = {
|
|
321
|
+
availabilityCollection: config.rootDataIndexer?.availabilityCollection || 'system_root_data_index',
|
|
322
|
+
earliestDate: config.rootDataIndexer?.earliestDate || '2025-08-01',
|
|
323
|
+
collections: config.rootDataIndexer?.collections || {},
|
|
324
|
+
targetDate: today // Index only today's date for speed
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
logger.log('INFO', `[PI Update] Triggering root data indexer for date ${today} before computation...`);
|
|
328
|
+
await runRootDataIndexer(indexerConfig, dependencies);
|
|
329
|
+
logger.log('INFO', `[PI Update] Root data indexer completed for date ${today}`);
|
|
330
|
+
|
|
331
|
+
// Update status to indicate indexing is done, computation is being triggered
|
|
332
|
+
await requestRef.update({
|
|
333
|
+
status: 'computing',
|
|
334
|
+
indexedAt: require('@google-cloud/firestore').FieldValue.serverTimestamp(),
|
|
335
|
+
updatedAt: require('@google-cloud/firestore').FieldValue.serverTimestamp()
|
|
336
|
+
});
|
|
337
|
+
} catch (indexerError) {
|
|
338
|
+
logger.log('ERROR', `[PI Update] Failed to run root data indexer for ${today}`, indexerError);
|
|
339
|
+
// Continue anyway - computation might still work if index already exists
|
|
340
|
+
// But update status to indicate we tried
|
|
341
|
+
await requestRef.update({
|
|
342
|
+
status: 'computing',
|
|
343
|
+
indexerError: indexerError.message,
|
|
344
|
+
updatedAt: require('@google-cloud/firestore').FieldValue.serverTimestamp()
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Trigger computation for PopularInvestorProfileMetrics
|
|
349
|
+
const { pubsub } = dependencies;
|
|
350
|
+
if (pubsub) {
|
|
351
|
+
const computationTopic = config.computationSystem?.computationTopicStandard || 'computation-tasks';
|
|
352
|
+
const topic = pubsub.topic(computationTopic);
|
|
353
|
+
const crypto = require('crypto');
|
|
354
|
+
|
|
355
|
+
const computationMessage = {
|
|
356
|
+
action: 'RUN_COMPUTATION_DATE',
|
|
357
|
+
computation: 'PopularInvestorProfileMetrics',
|
|
358
|
+
date: today,
|
|
359
|
+
pass: '1', // Standard pass
|
|
360
|
+
dispatchId: crypto.randomUUID(),
|
|
361
|
+
triggerReason: 'on_demand_pi_fetch',
|
|
362
|
+
resources: 'standard',
|
|
363
|
+
metadata: {
|
|
364
|
+
onDemand: true,
|
|
365
|
+
requestId: requestId,
|
|
366
|
+
piCid: cid,
|
|
367
|
+
piUsername: username
|
|
368
|
+
},
|
|
369
|
+
traceContext: {
|
|
370
|
+
traceId: crypto.randomBytes(16).toString('hex'),
|
|
371
|
+
spanId: crypto.randomBytes(8).toString('hex'),
|
|
372
|
+
sampled: true
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
await topic.publishMessage({
|
|
377
|
+
data: Buffer.from(JSON.stringify(computationMessage))
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
logger.log('INFO', `[PI Update] Triggered computation PopularInvestorProfileMetrics for PI ${cid} (${username}) for date ${today}`);
|
|
381
|
+
} else {
|
|
382
|
+
logger.log('WARN', `[PI Update] PubSub not available, cannot trigger computation`);
|
|
383
|
+
}
|
|
315
384
|
} catch (err) {
|
|
316
|
-
logger.log('WARN', `[PI Update] Failed to update request status
|
|
385
|
+
logger.log('WARN', `[PI Update] Failed to update request status or trigger computation for ${requestId}`, err);
|
|
317
386
|
}
|
|
318
387
|
}
|
|
319
388
|
|