bulltrackers-module 1.0.698 → 1.0.699
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.
- package/functions/computation-system/data/AvailabilityChecker.js +14 -4
- package/functions/computation-system/executors/MetaExecutor.js +12 -7
- package/functions/computation-system/executors/StandardExecutor.js +15 -5
- package/functions/computation-system/legacy/AvailabilityCheckerOld.js +6 -0
- package/package.json +1 -1
|
@@ -11,7 +11,13 @@ const INDEX_COLLECTION = process.env.ROOT_DATA_AVAILABILITY_COLLECTION || 'syste
|
|
|
11
11
|
// CONFIGURATION: Dependency Mappings
|
|
12
12
|
// =============================================================================
|
|
13
13
|
|
|
14
|
-
//
|
|
14
|
+
// Global dependencies that are NOT date-specific and are always considered available.
|
|
15
|
+
// These are stored at fixed paths and don't rely on daily availability index.
|
|
16
|
+
const GLOBAL_DEPS = new Set([
|
|
17
|
+
'piMasterList' // Stored at /system_state/popular_investor_master_list (global CID->username mapping)
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
// Dependencies that map directly to a single status flag (date-specific)
|
|
15
21
|
const SIMPLE_DEP_MAP = {
|
|
16
22
|
rankings: 'piRankings',
|
|
17
23
|
verification: 'signedInUserVerification',
|
|
@@ -21,7 +27,7 @@ const SIMPLE_DEP_MAP = {
|
|
|
21
27
|
pageViews: 'piPageViews',
|
|
22
28
|
watchlist: 'watchlistMembership',
|
|
23
29
|
alerts: 'piAlertHistory',
|
|
24
|
-
piMasterList: 'piMasterList' //
|
|
30
|
+
piMasterList: 'piMasterList' // Kept for normalizeStatus compatibility, but checked via GLOBAL_DEPS
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
// Dependencies that vary based on the userType of the calculation
|
|
@@ -68,8 +74,12 @@ function checkRootDependencies(calcManifest, rootDataStatus) {
|
|
|
68
74
|
let isAvailable = false;
|
|
69
75
|
let missingKey = dep;
|
|
70
76
|
|
|
71
|
-
//
|
|
72
|
-
if (
|
|
77
|
+
// 0. Check for Global Dependencies (always available, not date-specific)
|
|
78
|
+
if (GLOBAL_DEPS.has(dep)) {
|
|
79
|
+
isAvailable = true;
|
|
80
|
+
}
|
|
81
|
+
// 1. Resolve Status Key for date-specific dependencies
|
|
82
|
+
else if (SIMPLE_DEP_MAP[dep]) {
|
|
73
83
|
const key = SIMPLE_DEP_MAP[dep];
|
|
74
84
|
if (rootDataStatus[key]) isAvailable = true;
|
|
75
85
|
else missingKey = key;
|
|
@@ -211,7 +211,7 @@ async function loadVariableRootData(loader, dateStr, calcs, logger) {
|
|
|
211
211
|
*/
|
|
212
212
|
async function loadSeriesData(loader, dateStr, calcs, manifestLookup, config, deps) {
|
|
213
213
|
const rootRequests = {};
|
|
214
|
-
const depRequests = {};
|
|
214
|
+
const depRequests = {}; // norm -> { days, originalName }
|
|
215
215
|
|
|
216
216
|
// 1. Aggregate Lookback Depths
|
|
217
217
|
for (const c of calcs) {
|
|
@@ -225,7 +225,10 @@ async function loadSeriesData(loader, dateStr, calcs, manifestLookup, config, de
|
|
|
225
225
|
Object.entries(c.dependencySeries).forEach(([name, val]) => {
|
|
226
226
|
const days = typeof val === 'object' ? val.lookback : val;
|
|
227
227
|
const norm = normalizeName(name);
|
|
228
|
-
|
|
228
|
+
// [FIX] Track BOTH normalized name (for dedup) AND original name (for Firestore lookup)
|
|
229
|
+
if (!depRequests[norm] || depRequests[norm].days < days) {
|
|
230
|
+
depRequests[norm] = { days, originalName: name };
|
|
231
|
+
}
|
|
229
232
|
});
|
|
230
233
|
}
|
|
231
234
|
}
|
|
@@ -250,11 +253,13 @@ async function loadSeriesData(loader, dateStr, calcs, manifestLookup, config, de
|
|
|
250
253
|
});
|
|
251
254
|
|
|
252
255
|
// 3. Fetch Dependency Series
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
// [FIX] Use ORIGINAL names for Firestore document lookup (case-sensitive)
|
|
257
|
+
const depEntries = Object.values(depRequests);
|
|
258
|
+
if (depEntries.length > 0) {
|
|
259
|
+
const depOriginalNames = depEntries.map(e => e.originalName);
|
|
260
|
+
const maxDays = Math.max(...depEntries.map(e => e.days));
|
|
261
|
+
deps.logger.log('INFO', `[MetaExecutor] Loading up to ${maxDays}-day series for Dependencies: ${depOriginalNames.join(', ')}`);
|
|
262
|
+
seriesData.results = await fetchResultSeries(dateStr, depOriginalNames, manifestLookup, config, deps, maxDays);
|
|
258
263
|
}
|
|
259
264
|
|
|
260
265
|
await Promise.all(rootPromises);
|
|
@@ -383,14 +383,21 @@ async function loadGlobalRoots(loader, dateStr, calcs, deps) {
|
|
|
383
383
|
|
|
384
384
|
async function loadSeriesData(loader, dateStr, calcs, config, deps) {
|
|
385
385
|
const rootReqs = {};
|
|
386
|
-
const depReqs = {};
|
|
386
|
+
const depReqs = {}; // norm -> { days, originalName }
|
|
387
387
|
|
|
388
388
|
calcs.forEach(c => {
|
|
389
389
|
if (c.manifest.rootDataSeries) {
|
|
390
390
|
Object.entries(c.manifest.rootDataSeries).forEach(([k, v]) => rootReqs[k] = Math.max(rootReqs[k]||0, v.lookback||v));
|
|
391
391
|
}
|
|
392
392
|
if (c.manifest.dependencySeries) {
|
|
393
|
-
|
|
393
|
+
// [FIX] Track BOTH normalized name (for dedup) AND original name (for Firestore lookup)
|
|
394
|
+
Object.entries(c.manifest.dependencySeries).forEach(([k, v]) => {
|
|
395
|
+
const norm = normalizeName(k);
|
|
396
|
+
const days = v.lookback || v;
|
|
397
|
+
if (!depReqs[norm] || depReqs[norm].days < days) {
|
|
398
|
+
depReqs[norm] = { days, originalName: k };
|
|
399
|
+
}
|
|
400
|
+
});
|
|
394
401
|
}
|
|
395
402
|
});
|
|
396
403
|
|
|
@@ -404,12 +411,15 @@ async function loadSeriesData(loader, dateStr, calcs, config, deps) {
|
|
|
404
411
|
if (rootMap[key]) series.root[key] = (await loader.loadSeries(rootMap[key], dateStr, days)).data;
|
|
405
412
|
}));
|
|
406
413
|
|
|
407
|
-
|
|
408
|
-
|
|
414
|
+
// [FIX] Use ORIGINAL names for Firestore document lookup (case-sensitive)
|
|
415
|
+
const depEntries = Object.values(depReqs);
|
|
416
|
+
if (depEntries.length) {
|
|
417
|
+
const depOriginalNames = depEntries.map(e => e.originalName);
|
|
418
|
+
const maxDays = Math.max(...depEntries.map(e => e.days));
|
|
409
419
|
// Construct manifest lookup on the fly for fetched names
|
|
410
420
|
const allManifests = getManifest(config.productLines, config.calculationsDirectory, deps);
|
|
411
421
|
const lookup = Object.fromEntries(allManifests.map(m => [normalizeName(m.name), m.category]));
|
|
412
|
-
series.results = await fetchResultSeries(dateStr,
|
|
422
|
+
series.results = await fetchResultSeries(dateStr, depOriginalNames, lookup, config, deps, maxDays);
|
|
413
423
|
}
|
|
414
424
|
|
|
415
425
|
return series;
|
|
@@ -189,6 +189,12 @@ function checkRootDependencies(calcManifest, rootDataStatus) {
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
+
// [GLOBAL] piMasterList is always available (not date-specific)
|
|
193
|
+
// Stored at /system_state/popular_investor_master_list
|
|
194
|
+
else if (dep === 'piMasterList') {
|
|
195
|
+
isAvailable = true;
|
|
196
|
+
available.push('piMasterList');
|
|
197
|
+
}
|
|
192
198
|
}
|
|
193
199
|
|
|
194
200
|
// [NEW] Enforce Mandatory Roots (defined by computation)
|