bulltrackers-module 1.0.537 → 1.0.538
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.
|
@@ -5,17 +5,62 @@
|
|
|
5
5
|
|
|
6
6
|
const { FieldValue } = require('@google-cloud/firestore');
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Get the detail field name for a data type
|
|
10
|
+
* @param {string} dataType - Data type identifier
|
|
11
|
+
* @returns {string} - Detail field name in the index document
|
|
12
|
+
*/
|
|
13
|
+
function getDetailFieldName(dataType) {
|
|
14
|
+
const dataTypeMap = {
|
|
15
|
+
'signedInUserPortfolio': 'signedInUserPortfolio',
|
|
16
|
+
'signedInUserHistory': 'signedInUserHistory',
|
|
17
|
+
'signedInUserSocial': 'signedInSocial',
|
|
18
|
+
'piPortfolios': 'piPortfolios',
|
|
19
|
+
'piHistory': 'piHistory',
|
|
20
|
+
'piSocial': 'piSocial',
|
|
21
|
+
'normalPortfolios': 'normalPortfolio',
|
|
22
|
+
'normalHistory': 'normalHistory',
|
|
23
|
+
'speculatorPortfolios': 'speculatorPortfolio',
|
|
24
|
+
'speculatorHistory': 'speculatorHistory'
|
|
25
|
+
};
|
|
26
|
+
return dataTypeMap[dataType] || dataType;
|
|
27
|
+
}
|
|
28
|
+
|
|
8
29
|
/**
|
|
9
30
|
* Check if root data is already indexed for a specific date
|
|
10
31
|
* @param {Firestore} db - Firestore instance
|
|
11
32
|
* @param {string} dateStr - Date string (YYYY-MM-DD)
|
|
12
33
|
* @param {string} availabilityCollection - Collection name for root data index
|
|
13
|
-
* @
|
|
34
|
+
* @param {Array<string>} dataTypesRun - Optional array of data types to verify are indexed (e.g., ['signedInUserPortfolio', 'piSocial'])
|
|
35
|
+
* @returns {Promise<boolean>} - True if already indexed (and all requested data types are indexed if provided)
|
|
14
36
|
*/
|
|
15
|
-
async function isRootDataIndexed(db, dateStr, availabilityCollection = 'system_root_data_index') {
|
|
37
|
+
async function isRootDataIndexed(db, dateStr, availabilityCollection = 'system_root_data_index', dataTypesRun = []) {
|
|
16
38
|
try {
|
|
17
39
|
const indexDoc = await db.collection(availabilityCollection).doc(dateStr).get();
|
|
18
|
-
|
|
40
|
+
if (!indexDoc.exists) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// If specific data types were requested, verify they are actually indexed
|
|
45
|
+
if (dataTypesRun && dataTypesRun.length > 0) {
|
|
46
|
+
const indexData = indexDoc.data();
|
|
47
|
+
const details = indexData?.details || {};
|
|
48
|
+
|
|
49
|
+
// Check if all requested data types are indexed (have true values)
|
|
50
|
+
// If any are false or missing, return false (needs indexing)
|
|
51
|
+
for (const dataType of dataTypesRun) {
|
|
52
|
+
const detailField = getDetailFieldName(dataType);
|
|
53
|
+
if (details[detailField] !== true) {
|
|
54
|
+
// At least one requested data type is not indexed
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// All requested data types are indexed as true
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// No specific data types requested - just check if document exists
|
|
63
|
+
return true;
|
|
19
64
|
} catch (error) {
|
|
20
65
|
// If we can't check, assume not indexed to be safe
|
|
21
66
|
return false;
|
|
@@ -39,11 +84,43 @@ async function conditionallyRunRootDataIndexer({ db, logger, dateStr, rootDataIn
|
|
|
39
84
|
const { runRootDataIndexer } = require('../../root-data-indexer/index');
|
|
40
85
|
const availabilityCollection = rootDataIndexerConfig?.availabilityCollection || 'system_root_data_index';
|
|
41
86
|
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
87
|
+
// IMPORTANT: Only index data types that were successfully stored (dataTypesRun contains only successful operations)
|
|
88
|
+
// If a write failed, it won't be in dataTypesRun, so we won't try to index it
|
|
89
|
+
// However, we still run the indexer to check/update the types that did succeed
|
|
90
|
+
|
|
91
|
+
// Check if already indexed (verify specific data types if provided)
|
|
92
|
+
// Only check the data types that were actually run - if they're all already true, skip indexing (never overwrite true values)
|
|
93
|
+
if (dataTypesRun.length > 0) {
|
|
94
|
+
const alreadyIndexed = await isRootDataIndexed(db, dateStr, availabilityCollection, dataTypesRun);
|
|
95
|
+
if (alreadyIndexed) {
|
|
96
|
+
logger.log('INFO', `[RootDataIndexer] All requested data types (${dataTypesRun.join(', ')}) are already indexed as true for ${dateStr}, skipping (never overwrite true values)`);
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// If document exists but data types aren't indexed, log it
|
|
101
|
+
try {
|
|
102
|
+
const indexDoc = await db.collection(availabilityCollection).doc(dateStr).get();
|
|
103
|
+
if (indexDoc.exists) {
|
|
104
|
+
const indexData = indexDoc.data();
|
|
105
|
+
const details = indexData?.details || {};
|
|
106
|
+
const missingTypes = dataTypesRun.filter(dt => {
|
|
107
|
+
const detailField = getDetailFieldName(dt);
|
|
108
|
+
return details[detailField] !== true;
|
|
109
|
+
});
|
|
110
|
+
if (missingTypes.length > 0) {
|
|
111
|
+
logger.log('INFO', `[RootDataIndexer] Index document exists for ${dateStr} but data types (${missingTypes.join(', ')}) are not indexed. Re-indexing...`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} catch (e) {
|
|
115
|
+
// Ignore errors checking document
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
// No specific data types - check if document exists (legacy behavior)
|
|
119
|
+
const alreadyIndexed = await isRootDataIndexed(db, dateStr, availabilityCollection, []);
|
|
120
|
+
if (alreadyIndexed) {
|
|
121
|
+
logger.log('INFO', `[RootDataIndexer] Root data already indexed for ${dateStr}, skipping`);
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
47
124
|
}
|
|
48
125
|
|
|
49
126
|
// Use Firestore transaction to ensure only one instance runs the indexer
|