bulltrackers-module 1.0.563 → 1.0.564

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.
@@ -3,9 +3,10 @@
3
3
  * Handles user portfolio data endpoints with migration support
4
4
  */
5
5
 
6
- const { findLatestPortfolioDate } = require('../core/data_lookup_helpers');
6
+ const { findLatestPortfolioDate, findLatestComputationDate } = require('../core/data_lookup_helpers');
7
7
  const { checkIfUserIsPI } = require('../core/user_status_helpers');
8
8
  const { getEffectiveCid, getDevOverride } = require('../dev/dev_helpers');
9
+ const { checkPiInComputationDate } = require('./computation_helpers');
9
10
 
10
11
  /**
11
12
  * GET /user/me/portfolio
@@ -119,7 +120,9 @@ async function getUserPortfolio(req, res, dependencies, config) {
119
120
 
120
121
  /**
121
122
  * GET /user/me/data-status
122
- * Checks if signed-in user's portfolio data has been fetched and stored.
123
+ * Checks if signed-in user's profile page computation is available.
124
+ * The profile page uses SignedInUserProfileMetrics computation, not raw portfolio/history data.
125
+ * If computation exists, the profile page can be rendered. If not, user should sync.
123
126
  */
124
127
  async function getUserDataStatus(req, res, dependencies, config) {
125
128
  const { db, logger } = dependencies;
@@ -130,146 +133,80 @@ async function getUserDataStatus(req, res, dependencies, config) {
130
133
  }
131
134
 
132
135
  try {
133
- const { signedInUsersCollection, signedInHistoryCollection } = config;
134
- const CANARY_BLOCK_ID = '19M';
135
-
136
136
  const today = new Date().toISOString().split('T')[0];
137
137
 
138
- logger.log('INFO', `[getUserDataStatus] Checking data for CID: ${userCid}, Date: ${today}, Collection: ${signedInUsersCollection}`);
139
-
140
- // Try to find latest available date for portfolio (with fallback)
141
- const portfolioDate = await findLatestPortfolioDate(db, signedInUsersCollection, userCid, 30);
142
- const portfolioExists = !!portfolioDate;
143
- const isPortfolioFallback = portfolioDate && portfolioDate !== today;
138
+ logger.log('INFO', `[getUserDataStatus] Checking computation for CID: ${userCid}, Date: ${today}`);
144
139
 
145
- if (portfolioDate && isPortfolioFallback) {
146
- logger.log('INFO', `[getUserDataStatus] Using fallback portfolio date ${portfolioDate} for user ${userCid} (today: ${today})`);
147
- }
148
-
149
- // Check history data with fallback
150
- // Check new root data path first: SignedInUsers/{cid}/tradeHistory/latest
151
- let historyExists = false;
152
- let historyDate = null;
153
- let isHistoryFallback = false;
140
+ // Check for dev override impersonation
141
+ const effectiveCid = await getEffectiveCid(db, userCid, config, logger);
154
142
 
155
- try {
156
- const latestHistoryRef = db.collection('SignedInUsers')
157
- .doc(String(userCid))
158
- .collection('tradeHistory')
159
- .doc('latest');
143
+ // Primary check: Does SignedInUserProfileMetrics computation exist for this user?
144
+ // This is what the profile page actually uses to render
145
+ const insightsCollection = config.unifiedInsightsCollection || 'unified_insights';
146
+ const resultsSub = config.resultsSubcollection || 'results';
147
+ const compsSub = config.computationsSubcollection || 'computations';
148
+ const category = 'popular-investor';
149
+ const computationName = 'SignedInUserProfileMetrics';
150
+
151
+ // Find latest computation date
152
+ const latestComputationDate = await findLatestComputationDate(
153
+ db,
154
+ insightsCollection,
155
+ resultsSub,
156
+ compsSub,
157
+ category,
158
+ computationName,
159
+ effectiveCid,
160
+ 30
161
+ );
162
+
163
+ let computationAvailable = false;
164
+ let computationDate = null;
165
+ let isComputationFallback = false;
166
+
167
+ if (latestComputationDate) {
168
+ // Check if this specific user exists in the computation
169
+ const { found } = await checkPiInComputationDate(
170
+ db,
171
+ insightsCollection,
172
+ resultsSub,
173
+ compsSub,
174
+ category,
175
+ computationName,
176
+ latestComputationDate,
177
+ String(effectiveCid),
178
+ logger
179
+ );
160
180
 
161
- const latestHistoryDoc = await latestHistoryRef.get();
162
- if (latestHistoryDoc.exists) {
163
- const data = latestHistoryDoc.data();
164
- if (data && data.date) {
165
- historyExists = true;
166
- historyDate = data.date;
167
- isHistoryFallback = data.date !== today;
168
- logger.log('INFO', `[getUserDataStatus] Found history data in latest snapshot: ${historyDate}`);
169
- }
170
- }
171
- } catch (error) {
172
- // Continue to other checks if this fails
173
- }
174
-
175
- // If not found in latest snapshot, check new root data path: SignedInUserTradeHistoryData/{date}/{cid}/{cid}
176
- if (!historyExists) {
177
- for (let i = 0; i <= 30; i++) {
178
- const checkDate = new Date();
179
- checkDate.setDate(checkDate.getDate() - i);
180
- const dateStr = checkDate.toISOString().split('T')[0];
181
+ if (found) {
182
+ computationAvailable = true;
183
+ computationDate = latestComputationDate;
184
+ isComputationFallback = latestComputationDate !== today;
181
185
 
182
- try {
183
- const rootHistoryRef = db.collection('SignedInUserTradeHistoryData')
184
- .doc(dateStr)
185
- .collection(String(userCid))
186
- .doc(String(userCid));
187
-
188
- const rootHistoryDoc = await rootHistoryRef.get();
189
- if (rootHistoryDoc.exists) {
190
- historyExists = true;
191
- historyDate = dateStr;
192
- isHistoryFallback = dateStr !== today;
193
- logger.log('INFO', `[getUserDataStatus] Found history data in root data collection: ${historyDate}`);
194
- break;
195
- }
196
- } catch (error) {
197
- continue;
198
- }
199
- }
200
- }
201
-
202
- // If still not found, check legacy path for backward compatibility
203
- if (!historyExists) {
204
- const historyCollection = signedInHistoryCollection || 'signed_in_user_history';
205
-
206
- // Check today first
207
- const todayHistoryRef = db.collection(historyCollection)
208
- .doc(CANARY_BLOCK_ID)
209
- .collection('snapshots')
210
- .doc(today)
211
- .collection('parts');
212
-
213
- const todayHistorySnapshot = await todayHistoryRef.get();
214
-
215
- if (!todayHistorySnapshot.empty) {
216
- for (const partDoc of todayHistorySnapshot.docs) {
217
- const partData = partDoc.data();
218
- if (partData && partData[String(userCid)]) {
219
- historyExists = true;
220
- historyDate = today;
221
- break;
222
- }
223
- }
224
- }
225
-
226
- // If not found today, search backwards
227
- if (!historyExists) {
228
- for (let i = 1; i <= 30; i++) {
229
- const checkDate = new Date();
230
- checkDate.setDate(checkDate.getDate() - i);
231
- const dateStr = checkDate.toISOString().split('T')[0];
232
-
233
- try {
234
- const historyPartsRef = db.collection(historyCollection)
235
- .doc(CANARY_BLOCK_ID)
236
- .collection('snapshots')
237
- .doc(dateStr)
238
- .collection('parts');
239
-
240
- const historyPartsSnapshot = await historyPartsRef.get();
241
-
242
- if (!historyPartsSnapshot.empty) {
243
- for (const partDoc of historyPartsSnapshot.docs) {
244
- const partData = partDoc.data();
245
- if (partData && partData[String(userCid)]) {
246
- historyExists = true;
247
- historyDate = dateStr;
248
- isHistoryFallback = true;
249
- logger.log('INFO', `[getUserDataStatus] Found history data in legacy fallback date ${dateStr}`);
250
- break;
251
- }
252
- }
253
- }
254
-
255
- if (historyExists) break;
256
- } catch (error) {
257
- continue;
258
- }
186
+ if (isComputationFallback) {
187
+ logger.log('INFO', `[getUserDataStatus] Using fallback computation date ${computationDate} for user ${userCid} (today: ${today})`);
188
+ } else {
189
+ logger.log('INFO', `[getUserDataStatus] Found computation for user ${userCid} on today's date`);
259
190
  }
191
+ } else {
192
+ logger.log('INFO', `[getUserDataStatus] Computation exists for date ${latestComputationDate} but user ${userCid} not found in it`);
260
193
  }
194
+ } else {
195
+ logger.log('INFO', `[getUserDataStatus] No computation found for user ${userCid} in last 30 days`);
261
196
  }
262
197
 
198
+ // For backward compatibility, keep portfolioAvailable and historyAvailable
199
+ // but they should match computationAvailable (computation is the source of truth)
263
200
  const result = {
264
- portfolioAvailable: portfolioExists,
265
- historyAvailable: historyExists,
266
- date: portfolioDate || today,
267
- portfolioDate: portfolioDate,
268
- historyDate: historyDate,
269
- isPortfolioFallback: isPortfolioFallback,
270
- isHistoryFallback: isHistoryFallback,
201
+ portfolioAvailable: computationAvailable, // Profile page uses computation, not raw portfolio
202
+ historyAvailable: computationAvailable, // Profile page uses computation, not raw history
203
+ computationAvailable: computationAvailable, // Explicit computation check
204
+ date: computationDate || today,
205
+ computationDate: computationDate,
206
+ isComputationFallback: isComputationFallback,
271
207
  requestedDate: today,
272
- userCid: String(userCid)
208
+ userCid: String(userCid),
209
+ effectiveCid: String(effectiveCid)
273
210
  };
274
211
 
275
212
  logger.log('INFO', `[getUserDataStatus] Result for CID ${userCid}:`, result);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.563",
3
+ "version": "1.0.564",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [