bulltrackers-module 1.0.460 → 1.0.461

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.
@@ -62,9 +62,11 @@ async function findLatestComputationDate(db, insightsCollection, resultsSub, com
62
62
 
63
63
  const doc = await computationRef.get();
64
64
  if (doc.exists) {
65
+ console.log(`[findLatestComputationDate] Found computation ${computationName} in category ${category} for date ${dateStr}`);
65
66
  return dateStr;
66
67
  }
67
68
  }
69
+ console.log(`[findLatestComputationDate] No computation found for ${computationName} in category ${category} within ${maxDays} days`);
68
70
  return null;
69
71
  }
70
72
 
@@ -87,45 +89,110 @@ async function hasUserCopied(db, userCid, piCid, config) {
87
89
  }
88
90
  // devResult is null, meaning no dev override, continue with normal logic
89
91
 
90
- // === PRIMARY: Try to fetch from SignedInUserCopiedPIs computation ===
92
+ // === PRIMARY: Try to fetch from computation results ===
91
93
  const insightsCollection = config.unifiedInsightsCollection || 'unified_insights';
92
- const category = 'signed_in_user';
93
- const computationName = 'SignedInUserCopiedPIs';
94
94
  const resultsSub = config.resultsSubcollection || 'results';
95
95
  const compsSub = config.computationsSubcollection || 'computations';
96
96
 
97
- const computationDate = await findLatestComputationDate(
98
- db,
99
- insightsCollection,
100
- resultsSub,
101
- compsSub,
102
- category,
103
- computationName,
104
- userCidNum,
105
- 30
106
- );
97
+ // Try both computation names and categories
98
+ const computationConfigs = [
99
+ { category: 'signed_in_user', name: 'SignedInUserCopiedPIs', format: 'object' }, // Returns { current: [], past: [], all: [] }
100
+ { category: 'signed_in_user', name: 'SignedInUserCopiedList', format: 'array' }, // Returns array directly
101
+ { category: 'popular-investor', name: 'SignedInUserCopiedList', format: 'array' }, // Alternative location
102
+ ];
107
103
 
108
- if (computationDate) {
109
- const computationRef = db.collection(insightsCollection)
110
- .doc(computationDate)
111
- .collection(resultsSub)
112
- .doc(category)
113
- .collection(compsSub)
114
- .doc(computationName);
104
+ for (const configItem of computationConfigs) {
105
+ const computationDate = await findLatestComputationDate(
106
+ db,
107
+ insightsCollection,
108
+ resultsSub,
109
+ compsSub,
110
+ configItem.category,
111
+ configItem.name,
112
+ userCidNum,
113
+ 30
114
+ );
115
115
 
116
- const computationDoc = await computationRef.get();
117
-
118
- if (computationDoc.exists) {
119
- const rawData = computationDoc.data();
120
- const decompressed = tryDecompress(rawData);
116
+ if (computationDate) {
117
+ const computationRef = db.collection(insightsCollection)
118
+ .doc(computationDate)
119
+ .collection(resultsSub)
120
+ .doc(configItem.category)
121
+ .collection(compsSub)
122
+ .doc(configItem.name);
123
+
124
+ const computationDoc = await computationRef.get();
121
125
 
122
- // Check if user's data exists in computation results
123
- if (decompressed && decompressed[String(userCidNum)]) {
124
- const userData = decompressed[String(userCidNum)];
125
- // Check if PI is in current, past, or all arrays
126
- const allCopied = userData.all || [];
127
- if (allCopied.includes(piCidNum)) {
128
- return true;
126
+ if (computationDoc.exists) {
127
+ const rawData = computationDoc.data();
128
+
129
+ // Handle sharded data
130
+ let mergedData = null;
131
+ if (rawData._sharded === true && rawData._shardCount) {
132
+ // Data is in shards - read all shards and merge
133
+ const shardsCol = computationRef.collection('_shards');
134
+ const shardsSnapshot = await shardsCol.get();
135
+
136
+ if (!shardsSnapshot.empty) {
137
+ mergedData = {};
138
+ for (const shardDoc of shardsSnapshot.docs) {
139
+ const shardData = shardDoc.data();
140
+ // Merge shard data - each shard may contain different user IDs
141
+ for (const [key, value] of Object.entries(shardData)) {
142
+ if (mergedData[key]) {
143
+ // If key exists, merge arrays or objects
144
+ if (Array.isArray(mergedData[key]) && Array.isArray(value)) {
145
+ mergedData[key] = [...mergedData[key], ...value];
146
+ } else if (typeof mergedData[key] === 'object' && typeof value === 'object') {
147
+ mergedData[key] = { ...mergedData[key], ...value };
148
+ } else {
149
+ mergedData[key] = value;
150
+ }
151
+ } else {
152
+ mergedData[key] = value;
153
+ }
154
+ }
155
+ }
156
+ }
157
+ } else {
158
+ // Data is in main document - decompress if needed
159
+ const { tryDecompress } = require('./data_helpers');
160
+ mergedData = tryDecompress(rawData);
161
+
162
+ // Handle string decompression result
163
+ if (typeof mergedData === 'string') {
164
+ try {
165
+ mergedData = JSON.parse(mergedData);
166
+ } catch (e) {
167
+ console.error(`[hasUserCopied] Failed to parse decompressed string:`, e.message);
168
+ continue;
169
+ }
170
+ }
171
+ }
172
+
173
+ if (!mergedData) continue;
174
+
175
+ // Extract user data based on format
176
+ const userData = mergedData[String(userCidNum)];
177
+ if (!userData) continue;
178
+
179
+ if (configItem.format === 'object') {
180
+ // SignedInUserCopiedPIs format: { userId: { current: [], past: [], all: [] } }
181
+ if (userData.all && Array.isArray(userData.all)) {
182
+ if (userData.all.includes(piCidNum)) {
183
+ console.log(`[hasUserCopied] Found PI ${piCidNum} in SignedInUserCopiedPIs.all for user ${userCid} (date: ${computationDate}, category: ${configItem.category})`);
184
+ return true;
185
+ }
186
+ }
187
+ } else if (configItem.format === 'array') {
188
+ // SignedInUserCopiedList format: { userId: [{ cid: X, ... }, ...] }
189
+ if (Array.isArray(userData)) {
190
+ const hasCopied = userData.some(item => Number(item.cid) === piCidNum);
191
+ if (hasCopied) {
192
+ console.log(`[hasUserCopied] Found PI ${piCidNum} in SignedInUserCopiedList for user ${userCid} (date: ${computationDate}, category: ${configItem.category})`);
193
+ return true;
194
+ }
195
+ }
129
196
  }
130
197
  }
131
198
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.460",
3
+ "version": "1.0.461",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [