bulltrackers-module 1.0.263 → 1.0.265

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,14 +5,12 @@
5
5
  */
6
6
 
7
7
  const { FieldValue } = require('@google-cloud/firestore');
8
- const pLimit = require('p-limit');
8
+ const pLimit = require('p-limit');
9
9
 
10
10
  // Hardcoded verification blocks as per logic requirements
11
11
  const CANARY_BLOCK_ID = '19M';
12
- const CANARY_PART_ID = 'part_0';
13
-
14
- // [FIX] Hardcoded to 'shard_0' based on your confirmed data path (/asset_prices/shard_0)
15
- const PRICE_SHARD_ID = 'shard_0';
12
+ const CANARY_PART_ID = 'part_0';
13
+ const PRICE_SHARD_ID = 'shard_0';
16
14
 
17
15
  /**
18
16
  * Main pipe: pipe.maintenance.runRootDataIndexer
@@ -25,36 +23,21 @@ exports.runRootDataIndexer = async (config, dependencies) => {
25
23
  collections
26
24
  } = config;
27
25
 
28
- // [FIX] Hardcode the collection name to ignore any incorrect config values
29
26
  const PRICE_COLLECTION_NAME = 'asset_prices';
30
-
31
27
  logger.log('INFO', '[RootDataIndexer] Starting Root Data Availability Scan...');
32
-
33
- // 1. Pre-fetch Price Data Availability (Optimization)
34
28
  const priceAvailabilitySet = new Set();
35
-
36
- // --- DEBUGGING START ---
37
29
  logger.log('INFO', `[RootDataIndexer] DEBUG: Attempting to fetch price shard. Collection: "${PRICE_COLLECTION_NAME}", Doc ID: "${PRICE_SHARD_ID}"`);
38
- // --- DEBUGGING END ---
39
-
40
30
  try {
41
- // [FIX] Use the hardcoded collection name
42
31
  const priceShardRef = db.collection(PRICE_COLLECTION_NAME).doc(PRICE_SHARD_ID);
43
32
  const priceSnap = await priceShardRef.get();
44
-
45
33
  if (priceSnap.exists) {
46
- const data = priceSnap.data();
34
+ const data = priceSnap.data();
47
35
  const instruments = Object.values(data);
48
-
49
- // --- DEBUGGING START ---
50
36
  logger.log('INFO', `[RootDataIndexer] DEBUG: Shard document found. Contains ${instruments.length} instrument entries.`);
51
-
52
37
  if (instruments.length > 0) {
53
- // Log the structure of the first instrument found to verify schema match
54
38
  const sampleKey = Object.keys(data)[0];
55
39
  const sampleVal = data[sampleKey];
56
40
  logger.log('INFO', `[RootDataIndexer] DEBUG: Sample Instrument Data (ID: ${sampleKey}):`, sampleVal);
57
-
58
41
  if (!sampleVal.prices) {
59
42
  logger.log('WARN', `[RootDataIndexer] DEBUG: ⚠️ Sample instrument is MISSING the 'prices' field! Available fields: ${Object.keys(sampleVal).join(', ')}`);
60
43
  } else {
@@ -64,23 +47,10 @@ exports.runRootDataIndexer = async (config, dependencies) => {
64
47
  } else {
65
48
  logger.log('WARN', '[RootDataIndexer] DEBUG: Shard document exists but appears empty (0 instruments found).');
66
49
  }
67
- // --- DEBUGGING END ---
68
-
69
- // Iterate over all instruments in this shard to find any available dates
70
- Object.values(data).forEach(instrument => {
71
- if (instrument.prices) {
72
- Object.keys(instrument.prices).forEach(dateKey => {
73
- // Validate format YYYY-MM-DD
74
- if (/^\d{4}-\d{2}-\d{2}$/.test(dateKey)) {
75
- priceAvailabilitySet.add(dateKey);
76
- }
77
- });
78
- }
79
- });
50
+
51
+ Object.values(data).forEach(instrument => { if (instrument.prices) { Object.keys(instrument.prices).forEach(dateKey => { if (/^\d{4}-\d{2}-\d{2}$/.test(dateKey)) { priceAvailabilitySet.add(dateKey); } }); } });
80
52
  } else {
81
- // --- DEBUGGING START ---
82
53
  logger.log('ERROR', `[RootDataIndexer] DEBUG: 🛑 FATAL: Document "${PRICE_SHARD_ID}" does NOT exist in collection "${PRICE_COLLECTION_NAME}". Price availability will be false for all dates.`);
83
- // --- DEBUGGING END ---
84
54
  }
85
55
  logger.log('INFO', `[RootDataIndexer] Loaded price availability map. Found prices for ${priceAvailabilitySet.size} unique dates.`);
86
56
  } catch (e) {
@@ -89,18 +59,16 @@ exports.runRootDataIndexer = async (config, dependencies) => {
89
59
 
90
60
  // 2. Determine Date Range (Earliest -> Tomorrow)
91
61
  const start = new Date(earliestDate || '2023-01-01');
92
- const end = new Date();
62
+ const end = new Date();
93
63
  end.setDate(end.getDate() + 1); // Look ahead 1 day
94
64
 
95
65
  const datesToScan = [];
96
- for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
97
- datesToScan.push(d.toISOString().slice(0, 10));
98
- }
66
+ for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) { datesToScan.push(d.toISOString().slice(0, 10)); }
99
67
 
100
68
  logger.log('INFO', `[RootDataIndexer] Scanning ${datesToScan.length} dates from ${datesToScan[0]} to ${datesToScan[datesToScan.length-1]}`);
101
69
 
102
70
  // 3. Scan in Parallel
103
- const limit = pLimit(20); // Concurrent date checks
71
+ const limit = pLimit(20); // Concurrent date checks
104
72
  let updatesCount = 0;
105
73
 
106
74
  const promises = datesToScan.map(dateStr => limit(async () => {
@@ -111,17 +79,17 @@ exports.runRootDataIndexer = async (config, dependencies) => {
111
79
 
112
80
  // Defaults
113
81
  hasPortfolio: false,
114
- hasHistory: false,
115
- hasSocial: false,
116
- hasInsights: false,
117
- hasPrices: false,
82
+ hasHistory: false,
83
+ hasSocial: false,
84
+ hasInsights: false,
85
+ hasPrices: false,
118
86
 
119
87
  // Detailed breakdown
120
88
  details: {
121
- normalPortfolio: false,
89
+ normalPortfolio: false,
122
90
  speculatorPortfolio: false,
123
- normalHistory: false,
124
- speculatorHistory: false
91
+ normalHistory: false,
92
+ speculatorHistory: false
125
93
  }
126
94
  };
127
95
 
@@ -165,32 +133,35 @@ exports.runRootDataIndexer = async (config, dependencies) => {
165
133
 
166
134
  // --- EXECUTE CHECKS ---
167
135
  const [
168
- normPortSnap, specPortSnap,
169
- normHistSnap, specHistSnap,
170
- insightsSnap, socialQuerySnap
136
+ normPortSnap,
137
+ specPortSnap,
138
+ normHistSnap,
139
+ specHistSnap,
140
+ insightsSnap,
141
+ socialQuerySnap
171
142
  ] = await Promise.all([
172
- normPortRef.get(), specPortRef.get(),
173
- normHistRef.get(), specHistRef.get(),
143
+ normPortRef.get(),
144
+ specPortRef.get(),
145
+ normHistRef.get(),
146
+ specHistRef.get(),
174
147
  insightsRef.get(),
175
148
  socialPostsRef.limit(1).get()
176
149
  ]);
177
150
 
178
151
  // Evaluate Findings
179
- availability.details.normalPortfolio = normPortSnap.exists;
152
+ availability.details.normalPortfolio = normPortSnap.exists;
180
153
  availability.details.speculatorPortfolio = specPortSnap.exists;
181
- availability.hasPortfolio = normPortSnap.exists || specPortSnap.exists;
154
+ availability.hasPortfolio = normPortSnap.exists || specPortSnap.exists;
182
155
 
183
- availability.details.normalHistory = normHistSnap.exists;
184
- availability.details.speculatorHistory = specHistSnap.exists;
185
- availability.hasHistory = normHistSnap.exists || specHistSnap.exists;
156
+ availability.details.normalHistory = normHistSnap.exists;
157
+ availability.details.speculatorHistory = specHistSnap.exists;
158
+ availability.hasHistory = normHistSnap.exists || specHistSnap.exists;
186
159
 
187
- availability.hasInsights = insightsSnap.exists;
188
- availability.hasSocial = !socialQuerySnap.empty;
160
+ availability.hasInsights = insightsSnap.exists;
161
+ availability.hasSocial = !socialQuerySnap.empty;
189
162
 
190
- // G. Prices (From pre-loaded set)
191
- availability.hasPrices = priceAvailabilitySet.has(dateStr);
163
+ availability.hasPrices = priceAvailabilitySet.has(dateStr);
192
164
 
193
- // Write to Index
194
165
  await db.collection(availabilityCollection).doc(dateStr).set(availability);
195
166
  updatesCount++;
196
167
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.263",
3
+ "version": "1.0.265",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [