bulltrackers-module 1.0.698 → 1.0.700

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.
@@ -11,7 +11,13 @@ const INDEX_COLLECTION = process.env.ROOT_DATA_AVAILABILITY_COLLECTION || 'syste
11
11
  // CONFIGURATION: Dependency Mappings
12
12
  // =============================================================================
13
13
 
14
- // Dependencies that map directly to a single status flag
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' // <--- ADD THIS LINE
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
- // 1. Resolve Status Key
72
- if (SIMPLE_DEP_MAP[dep]) {
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;
@@ -216,6 +216,12 @@ async function fetchDependencies(date, calcs, config, deps, manifestLookup = {},
216
216
 
217
217
  /**
218
218
  * Fetches result series (Historical data) for lookbacks.
219
+ * @param {string} endDateStr - The end date for the series
220
+ * @param {string[]} calcNames - Original (case-sensitive) computation names
221
+ * @param {Object} manifestLookup - Map of normalizedName -> category
222
+ * @param {Object} config - Configuration object
223
+ * @param {Object} deps - Dependencies (db, logger)
224
+ * @param {number} lookbackDays - Number of days to look back
219
225
  */
220
226
  async function fetchResultSeries(endDateStr, calcNames, manifestLookup, config, deps, lookbackDays) {
221
227
  const { db, logger } = deps;
@@ -224,7 +230,7 @@ async function fetchResultSeries(endDateStr, calcNames, manifestLookup, config,
224
230
  // Initialize results structure
225
231
  calcNames.forEach(n => results[normalizeName(n)] = {});
226
232
 
227
- // Generate Date List
233
+ // Generate Date List (going backwards from endDate)
228
234
  const dates = [];
229
235
  const d = new Date(endDateStr);
230
236
  for (let i = 0; i < lookbackDays; i++) {
@@ -238,6 +244,7 @@ async function fetchResultSeries(endDateStr, calcNames, manifestLookup, config,
238
244
  for (const rawName of calcNames) {
239
245
  const norm = normalizeName(rawName);
240
246
  const category = manifestLookup[norm] || 'analytics';
247
+
241
248
  ops.push(async () => {
242
249
  const val = await fetchSingleResult(db, { ...config, logger }, dateStr, rawName, category);
243
250
  if (val && !isDataEmpty(val)) {
@@ -9,6 +9,16 @@ const { commitResults } = require('../persistence/ResultCommitter');
9
9
  const { fetchResultSeries } = require('../data/DependencyFetcher');
10
10
  const { getManifest } = require('../topology/ManifestLoader');
11
11
 
12
+ // [FIX] Load calculations package directly for manifest building during force runs
13
+ let _calculations = null;
14
+ function getCalculations() {
15
+ if (!_calculations) {
16
+ try { _calculations = require('aiden-shared-calculations-unified').calculations; }
17
+ catch (e) { _calculations = {}; }
18
+ }
19
+ return _calculations;
20
+ }
21
+
12
22
  class MetaExecutor {
13
23
 
14
24
  // =========================================================================
@@ -94,13 +104,17 @@ class MetaExecutor {
94
104
  const { logger } = deps;
95
105
  const calcs = [metadata]; // Treat single as list for helpers
96
106
 
107
+ // [FIX] Build manifestLookup using the actual calculations package (not config.calculationsDirectory)
108
+ const allManifests = getManifest([], getCalculations(), deps);
109
+ const manifestLookup = Object.fromEntries(allManifests.map(m => [normalizeName(m.name), m.category]));
110
+
97
111
  // 1. Load Data using Shared Helpers
98
112
  const [mappings, rankings, variableRoots, seriesData, piMasterList] = await Promise.all([
99
113
  loader.loadMappings(),
100
114
  loader.loadRankings(dateStr),
101
115
  loadVariableRootData(loader, dateStr, calcs, logger),
102
- loadSeriesData(loader, dateStr, calcs, {}, config, deps),
103
- loader.loadPIMasterList() // <--- ADDED LOAD
116
+ loadSeriesData(loader, dateStr, calcs, manifestLookup, config, deps),
117
+ loader.loadPIMasterList()
104
118
  ]);
105
119
 
106
120
  let rankingsYesterday = null;
@@ -211,9 +225,9 @@ async function loadVariableRootData(loader, dateStr, calcs, logger) {
211
225
  */
212
226
  async function loadSeriesData(loader, dateStr, calcs, manifestLookup, config, deps) {
213
227
  const rootRequests = {};
214
- const depRequests = {};
228
+ const depRequests = {}; // norm -> { days, originalName }
215
229
 
216
- // 1. Aggregate Lookback Depths
230
+ // 1. Aggregate Lookback Depths from dependencySeries config
217
231
  for (const c of calcs) {
218
232
  if (c.rootDataSeries) {
219
233
  Object.entries(c.rootDataSeries).forEach(([type, val]) => {
@@ -225,7 +239,9 @@ async function loadSeriesData(loader, dateStr, calcs, manifestLookup, config, de
225
239
  Object.entries(c.dependencySeries).forEach(([name, val]) => {
226
240
  const days = typeof val === 'object' ? val.lookback : val;
227
241
  const norm = normalizeName(name);
228
- depRequests[norm] = Math.max(depRequests[norm] || 0, days);
242
+ if (!depRequests[norm] || depRequests[norm].days < days) {
243
+ depRequests[norm] = { days, originalName: name };
244
+ }
229
245
  });
230
246
  }
231
247
  }
@@ -249,12 +265,14 @@ async function loadSeriesData(loader, dateStr, calcs, manifestLookup, config, de
249
265
  }
250
266
  });
251
267
 
252
- // 3. Fetch Dependency Series
253
- const depNames = Object.keys(depRequests);
254
- if (depNames.length > 0) {
255
- const maxDays = Math.max(...Object.values(depRequests));
256
- deps.logger.log('INFO', `[MetaExecutor] Loading up to ${maxDays}-day series for Dependencies: ${depNames.join(', ')}`);
257
- seriesData.results = await fetchResultSeries(dateStr, depNames, manifestLookup, config, deps, maxDays);
268
+ // 3. Fetch Dependency Series (category comes from manifestLookup)
269
+ const depEntries = Object.values(depRequests);
270
+ if (depEntries.length > 0) {
271
+ const depOriginalNames = depEntries.map(e => e.originalName);
272
+ const maxDays = Math.max(...depEntries.map(e => e.days));
273
+
274
+ deps.logger.log('INFO', `[MetaExecutor] Loading up to ${maxDays}-day series for Dependencies: ${depOriginalNames.join(', ')}`);
275
+ seriesData.results = await fetchResultSeries(dateStr, depOriginalNames, manifestLookup, config, deps, maxDays);
258
276
  }
259
277
 
260
278
  await Promise.all(rootPromises);
@@ -13,6 +13,16 @@ const mathLayer = require('../layers/index');
13
13
  const { performance } = require('perf_hooks');
14
14
  const v8 = require('v8');
15
15
 
16
+ // [FIX] Load calculations package directly for manifest building
17
+ let _calculations = null;
18
+ function getCalculations() {
19
+ if (!_calculations) {
20
+ try { _calculations = require('aiden-shared-calculations-unified').calculations; }
21
+ catch (e) { _calculations = {}; }
22
+ }
23
+ return _calculations;
24
+ }
25
+
16
26
  class StandardExecutor {
17
27
 
18
28
  // =========================================================================
@@ -383,14 +393,20 @@ async function loadGlobalRoots(loader, dateStr, calcs, deps) {
383
393
 
384
394
  async function loadSeriesData(loader, dateStr, calcs, config, deps) {
385
395
  const rootReqs = {};
386
- const depReqs = {};
396
+ const depReqs = {}; // norm -> { days, originalName, category }
387
397
 
388
398
  calcs.forEach(c => {
389
399
  if (c.manifest.rootDataSeries) {
390
400
  Object.entries(c.manifest.rootDataSeries).forEach(([k, v]) => rootReqs[k] = Math.max(rootReqs[k]||0, v.lookback||v));
391
401
  }
392
402
  if (c.manifest.dependencySeries) {
393
- Object.entries(c.manifest.dependencySeries).forEach(([k, v]) => depReqs[normalizeName(k)] = Math.max(depReqs[normalizeName(k)]||0, v.lookback||v));
403
+ Object.entries(c.manifest.dependencySeries).forEach(([k, v]) => {
404
+ const norm = normalizeName(k);
405
+ const days = typeof v === 'object' ? v.lookback : v;
406
+ if (!depReqs[norm] || depReqs[norm].days < days) {
407
+ depReqs[norm] = { days, originalName: k };
408
+ }
409
+ });
394
410
  }
395
411
  });
396
412
 
@@ -404,12 +420,17 @@ async function loadSeriesData(loader, dateStr, calcs, config, deps) {
404
420
  if (rootMap[key]) series.root[key] = (await loader.loadSeries(rootMap[key], dateStr, days)).data;
405
421
  }));
406
422
 
407
- const depNames = Object.keys(depReqs);
408
- if (depNames.length) {
409
- // Construct manifest lookup on the fly for fetched names
410
- const allManifests = getManifest(config.productLines, config.calculationsDirectory, deps);
423
+ // [FIX] Use getCalculations() to load ALL computations for proper category lookup
424
+ const depEntries = Object.values(depReqs);
425
+ if (depEntries.length) {
426
+ const depOriginalNames = depEntries.map(e => e.originalName);
427
+ const maxDays = Math.max(...depEntries.map(e => e.days));
428
+
429
+ // Build lookup from ALL computations (empty productLines = load all)
430
+ const allManifests = getManifest([], getCalculations(), deps);
411
431
  const lookup = Object.fromEntries(allManifests.map(m => [normalizeName(m.name), m.category]));
412
- series.results = await fetchResultSeries(dateStr, depNames, lookup, config, deps, Math.max(...Object.values(depReqs)));
432
+
433
+ series.results = await fetchResultSeries(dateStr, depOriginalNames, lookup, config, deps, maxDays);
413
434
  }
414
435
 
415
436
  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)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.698",
3
+ "version": "1.0.700",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [