bulltrackers-module 1.0.409 → 1.0.411
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.
|
@@ -3,6 +3,26 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const { FieldValue } = require('@google-cloud/firestore');
|
|
6
|
+
const zlib = require('zlib');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Helper function to decompress computation results if they are stored as compressed byte strings
|
|
10
|
+
* @param {object} data - The raw Firestore document data
|
|
11
|
+
* @returns {object} The decompressed JSON object or original data if not compressed
|
|
12
|
+
*/
|
|
13
|
+
function tryDecompress(data) {
|
|
14
|
+
if (data && data._compressed === true && data.payload) {
|
|
15
|
+
try {
|
|
16
|
+
// Firestore returns Buffers automatically for Blob types
|
|
17
|
+
return JSON.parse(zlib.gunzipSync(data.payload).toString());
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.error('[DataHelpers] Decompression failed:', e);
|
|
20
|
+
// Return empty object on failure to avoid crashing
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
6
26
|
|
|
7
27
|
/**
|
|
8
28
|
* Helper function to find the latest available date for signed-in user portfolio data
|
|
@@ -65,10 +85,19 @@ async function findLatestComputationDate(db, insightsCollection, category, compu
|
|
|
65
85
|
const computationDoc = await computationRef.get();
|
|
66
86
|
|
|
67
87
|
if (computationDoc.exists) {
|
|
68
|
-
const
|
|
88
|
+
const rawData = computationDoc.data();
|
|
89
|
+
// Decompress if needed (handles byte string storage)
|
|
90
|
+
const computationData = tryDecompress(rawData);
|
|
69
91
|
// Check if user's CID exists in the computation result
|
|
70
|
-
|
|
92
|
+
const cidStr = String(userCid);
|
|
93
|
+
const hasCid = computationData && computationData[cidStr] !== undefined;
|
|
94
|
+
|
|
95
|
+
if (hasCid) {
|
|
71
96
|
return dateStr; // Found data for this date
|
|
97
|
+
} else if (computationData && typeof computationData === 'object') {
|
|
98
|
+
// Log debug info if document exists but CID not found
|
|
99
|
+
const sampleKeys = Object.keys(computationData).slice(0, 5);
|
|
100
|
+
console.log(`[findLatestComputationDate] Date ${dateStr}: Document exists but CID ${cidStr} not found. Sample keys:`, sampleKeys);
|
|
72
101
|
}
|
|
73
102
|
}
|
|
74
103
|
} catch (error) {
|
|
@@ -697,7 +726,9 @@ async function getUserComputations(req, res, dependencies, config) {
|
|
|
697
726
|
const doc = await docRef.get();
|
|
698
727
|
|
|
699
728
|
if (doc.exists) {
|
|
700
|
-
|
|
729
|
+
// Decompress if needed (handles byte string storage)
|
|
730
|
+
const rawData = doc.data();
|
|
731
|
+
const data = tryDecompress(rawData);
|
|
701
732
|
// Filter by user CID - computation results are stored as { cid: result }
|
|
702
733
|
const userResult = data[String(userCid)];
|
|
703
734
|
if (userResult) {
|
|
@@ -1390,13 +1421,45 @@ async function getPiProfile(req, res, dependencies, config) {
|
|
|
1390
1421
|
});
|
|
1391
1422
|
}
|
|
1392
1423
|
|
|
1393
|
-
|
|
1424
|
+
// Decompress if needed (handles byte string storage)
|
|
1425
|
+
const rawData = computationDoc.data();
|
|
1426
|
+
const wasCompressed = rawData && rawData._compressed === true;
|
|
1427
|
+
logger.log('INFO', `[getPiProfile] Document exists. Was compressed: ${wasCompressed}, CID being searched: ${cid}`);
|
|
1428
|
+
|
|
1429
|
+
const computationData = tryDecompress(rawData);
|
|
1430
|
+
|
|
1431
|
+
// Debug logging: Show full decompressed document structure
|
|
1432
|
+
logger.log('INFO', `[getPiProfile] Decompressed data structure:`, {
|
|
1433
|
+
hasData: !!computationData,
|
|
1434
|
+
dataType: typeof computationData,
|
|
1435
|
+
isArray: Array.isArray(computationData),
|
|
1436
|
+
keys: computationData && typeof computationData === 'object' ? Object.keys(computationData).slice(0, 50) : 'N/A', // First 50 keys
|
|
1437
|
+
totalKeys: computationData && typeof computationData === 'object' ? Object.keys(computationData).length : 0,
|
|
1438
|
+
searchingForCid: String(cid),
|
|
1439
|
+
cidExists: computationData && computationData[String(cid)] !== undefined,
|
|
1440
|
+
sampleCids: computationData && typeof computationData === 'object' ? Object.keys(computationData).slice(0, 10) : []
|
|
1441
|
+
});
|
|
1442
|
+
|
|
1443
|
+
// Log full decompressed data (will be large but needed for debugging)
|
|
1444
|
+
logger.log('INFO', `[getPiProfile] FULL DECOMPRESSED DOCUMENT CONTENTS:`, JSON.stringify(computationData, null, 2));
|
|
1445
|
+
|
|
1394
1446
|
const profileData = computationData[String(cid)];
|
|
1395
1447
|
|
|
1396
1448
|
if (!profileData) {
|
|
1449
|
+
// Additional debug info in error response
|
|
1450
|
+
const availableCids = computationData && typeof computationData === 'object' ? Object.keys(computationData).slice(0, 20) : [];
|
|
1451
|
+
logger.log('WARN', `[getPiProfile] CID ${cid} not found in computation data. Available CIDs (sample):`, availableCids);
|
|
1452
|
+
|
|
1397
1453
|
return res.status(404).json({
|
|
1398
1454
|
error: "Profile data not found",
|
|
1399
|
-
message: "No data for this Popular Investor in computation results"
|
|
1455
|
+
message: "No data for this Popular Investor in computation results",
|
|
1456
|
+
debug: {
|
|
1457
|
+
searchedCid: String(cid),
|
|
1458
|
+
wasCompressed: wasCompressed,
|
|
1459
|
+
totalKeysInDocument: computationData && typeof computationData === 'object' ? Object.keys(computationData).length : 0,
|
|
1460
|
+
sampleAvailableCids: availableCids,
|
|
1461
|
+
dataDate: latestDate
|
|
1462
|
+
}
|
|
1400
1463
|
});
|
|
1401
1464
|
}
|
|
1402
1465
|
|