bulltrackers-module 1.0.176 → 1.0.177

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.
@@ -147,28 +147,17 @@ class ComputationExecutor {
147
147
  */
148
148
  async executePerUser(calcInstance, metadata, dateStr, portfolioData, yesterdayPortfolioData, historyData, computedDeps, prevDeps) {
149
149
  const { logger } = this.deps;
150
-
151
- // Fix for the 'all' userType discrepancy:
152
- const targetUserType = metadata.userType; // 'all', 'normal', or 'speculator'
153
-
150
+ const targetUserType = metadata.userType;
154
151
  const mappings = await this.loader.loadMappings();
155
152
  const insights = metadata.rootDataDependencies?.includes('insights') ? { today: await this.loader.loadInsights(dateStr) } : null;
156
-
157
153
  for (const [userId, todayPortfolio] of Object.entries(portfolioData)) {
158
- // 1. Get Yesterday's Portfolio (if available)
159
154
  const yesterdayPortfolio = yesterdayPortfolioData ? yesterdayPortfolioData[userId] : null;
160
-
161
- // 2. Get Today's Trading History (if available)
162
155
  const todayHistory = historyData ? historyData[userId] : null;
163
-
164
156
  const actualUserType = todayPortfolio.PublicPositions ? SCHEMAS.USER_TYPES.SPECULATOR : SCHEMAS.USER_TYPES.NORMAL;
165
-
166
- // Filtering Logic
167
157
  if (targetUserType !== 'all') {
168
158
  const mappedTarget = (targetUserType === 'speculator') ? SCHEMAS.USER_TYPES.SPECULATOR : SCHEMAS.USER_TYPES.NORMAL;
169
159
  if (mappedTarget !== actualUserType) continue;
170
160
  }
171
-
172
161
  const context = ContextBuilder.buildPerUserContext({
173
162
  todayPortfolio, yesterdayPortfolio,
174
163
  todayHistory,
@@ -177,7 +166,6 @@ class ComputationExecutor {
177
166
  previousComputedDependencies: prevDeps,
178
167
  config: this.config, deps: this.deps
179
168
  });
180
-
181
169
  try { await calcInstance.process(context); }
182
170
  catch (e) { logger.log('WARN', `Calc ${metadata.name} failed for user ${userId}: ${e.message}`); }
183
171
  }
@@ -187,14 +175,12 @@ class ComputationExecutor {
187
175
  const mappings = await this.loader.loadMappings();
188
176
  const insights = metadata.rootDataDependencies?.includes('insights') ? { today: await this.loader.loadInsights(dateStr) } : null;
189
177
  const social = metadata.rootDataDependencies?.includes('social') ? { today: await this.loader.loadSocial(dateStr) } : null;
190
-
191
178
  const context = ContextBuilder.buildMetaContext({
192
179
  dateStr, metadata, mappings, insights, socialData: social,
193
180
  computedDependencies: computedDeps,
194
181
  previousComputedDependencies: prevDeps,
195
182
  config: this.config, deps: this.deps
196
183
  });
197
-
198
184
  return await calcInstance.process(context);
199
185
  }
200
186
  }
@@ -11,15 +11,6 @@
11
11
  * It has removed all logic for deprecated folder structures (e.g., /historical/).
12
12
  */
13
13
 
14
- const fs = require('fs');
15
- //Hacky solution to force tmp writes TODO : This Tmp write is really dodgy, not ideal but works, consider less hacky solutions to writing to filesystem
16
- process.env.TMPDIR = '/tmp';
17
- process.env.TMP = '/tmp';
18
- process.env.TEMP = '/tmp';
19
- const os = require('os');
20
-
21
- const path = require('path');
22
-
23
14
  /* --------------------------------------------------
24
15
  * Pretty Console Helpers
25
16
  * -------------------------------------------------- */
@@ -54,7 +45,7 @@ function suggestClosest(name, candidates, n = 3) {
54
45
  return dp[m][n];
55
46
  };
56
47
  const scores = candidates.map(c => [c, levenshtein(name, c)]);
57
- scores.sort((a, b) => a[1] - b[1]);
48
+ scores.sort((a, b) => a[1] - b[1]);
58
49
  return scores.slice(0, n).map(s => s[0]);
59
50
  }
60
51
 
@@ -206,17 +197,20 @@ function buildManifest(productLinesToRun = [], calculations) {
206
197
  const sortedManifest = [];
207
198
  const queue = [];
208
199
  let maxPass = 0;
200
+
209
201
  for (const [name, degree] of filteredInDegree) { if (degree === 0) { queue.push(name); filteredManifestMap.get(name).pass = 1; maxPass = 1; } }
210
202
  queue.sort();
211
203
  while (queue.length) {
212
204
  const currentName = queue.shift();
213
205
  const currentEntry = filteredManifestMap.get(currentName);
214
206
  sortedManifest.push(currentEntry);
207
+
215
208
  for (const neighborName of (filteredReverseAdjacency.get(currentName) || [])) { const newDegree = filteredInDegree.get(neighborName) - 1; filteredInDegree.set(neighborName, newDegree);
216
209
  const neighborEntry = filteredManifestMap.get(neighborName);
217
210
  if (neighborEntry.pass <= currentEntry.pass) { neighborEntry.pass = currentEntry.pass + 1; if (neighborEntry.pass > maxPass) maxPass = neighborEntry.pass; }
218
211
  if (newDegree === 0) { queue.push(neighborName); } }
219
212
  queue.sort(); }
213
+
220
214
  if (sortedManifest.length !== filteredManifestMap.size) {
221
215
  log.divider('Circular Dependency Detected');
222
216
  const cycles = findCycles(filteredManifestMap, adjacency);
@@ -62,8 +62,6 @@ async function runComputationPass(config, dependencies, computationManifest) {
62
62
  // Process a single date and RETURN updates (do not write)
63
63
  const processDate = async (dateStr) => {
64
64
  const dateToProcess = new Date(dateStr + 'T00:00:00Z');
65
-
66
- // Filter using in-memory status
67
65
  const standardToRun = standardCalcs.filter(c => shouldRun(c, dateStr));
68
66
  const metaToRun = metaCalcs.filter(c => shouldRun(c, dateStr));
69
67
 
@@ -84,21 +82,17 @@ async function runComputationPass(config, dependencies, computationManifest) {
84
82
  try {
85
83
  const calcsRunning = [...finalStandardToRun, ...finalMetaToRun];
86
84
  const existingResults = await fetchExistingResults(dateStr, calcsRunning, computationManifest, config, dependencies, false);
87
-
88
- const prevDate = new Date(dateToProcess); prevDate.setUTCDate(prevDate.getUTCDate() - 1);
89
- const prevDateStr = prevDate.toISOString().slice(0, 10);
85
+ const prevDate = new Date(dateToProcess); prevDate.setUTCDate(prevDate.getUTCDate() - 1);
86
+ const prevDateStr = prevDate.toISOString().slice(0, 10);
90
87
  const previousResults = await fetchExistingResults(prevDateStr, calcsRunning, computationManifest, config, dependencies, true);
91
-
92
88
  if (finalStandardToRun.length) {
93
89
  const updates = await runStandardComputationPass(dateToProcess, finalStandardToRun, `Pass ${passToRun} (Std)`, config, dependencies, rootData, existingResults, previousResults, true); // skipStatusWrite=true
94
90
  Object.assign(dateUpdates, updates);
95
91
  }
96
-
97
92
  if (finalMetaToRun.length) {
98
93
  const updates = await runMetaComputationPass(dateToProcess, finalMetaToRun, `Pass ${passToRun} (Meta)`, config, dependencies, existingResults, previousResults, rootData, true); // skipStatusWrite=true
99
94
  Object.assign(dateUpdates, updates);
100
95
  }
101
-
102
96
  } catch (err) {
103
97
  logger.log('ERROR', `[PassRunner] FAILED Pass ${passToRun} for ${dateStr}`, { errorMessage: err.message });
104
98
  // Mark failures
@@ -3,6 +3,7 @@
3
3
  * (REFACTORED: Removed all concurrency from `handleUpdate` and `lookupUsernames`)
4
4
  * (REFACTORED: Added node-fetch fallback for all API calls)
5
5
  * (REFACTORED: Added verbose, user-centric logging for all operations)
6
+ * (FIXED: Corrected variable name 'instId' to 'instrumentId' in final timestamp loops)
6
7
  */
7
8
 
8
9
  const { FieldValue } = require('@google-cloud/firestore');
@@ -174,9 +175,12 @@ async function handleUpdate(task, taskId, { logger, headerManager, proxyManager,
174
175
  }
175
176
 
176
177
  // --- 5. Handle Private Users & Timestamps ---
178
+ // FIXED: Corrected variable naming here from 'instId' to 'instrumentId'
177
179
  if (isPrivate) {
178
180
  logger.log('WARN', `[handleUpdate/${userId}] Removing private user from updates.`);
179
- for (const instrumentId of instrumentsToProcess) { await batchManager.deleteFromTimestampBatch(userId, userType, instId); }
181
+ for (const instrumentId of instrumentsToProcess) {
182
+ await batchManager.deleteFromTimestampBatch(userId, userType, instrumentId);
183
+ }
180
184
  const blockCountsRef = db.doc(config.FIRESTORE_DOC_SPECULATOR_BLOCK_COUNTS);
181
185
  for (const instrumentId of instrumentsToProcess) {
182
186
  const incrementField = `counts.${instrumentId}_${Math.floor(userId/1e6)*1e6}`;
@@ -186,7 +190,11 @@ async function handleUpdate(task, taskId, { logger, headerManager, proxyManager,
186
190
  }
187
191
 
188
192
  // If not private, update all timestamps
189
- for (const instrumentId of instrumentsToProcess) { await batchManager.updateUserTimestamp(userId, userType, instId); }
193
+ // FIXED: Corrected variable naming here from 'instId' to 'instrumentId'
194
+ for (const instrumentId of instrumentsToProcess) {
195
+ await batchManager.updateUserTimestamp(userId, userType, instrumentId);
196
+ }
197
+
190
198
  if (userType === 'speculator') { await batchManager.addSpeculatorTimestampFix(userId, String(Math.floor(userId/1e6)*1e6)); }
191
199
 
192
200
  logger.log('INFO', `[handleUpdate/${userId}] Update task finished successfully.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.176",
3
+ "version": "1.0.177",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [