bulltrackers-module 1.0.512 → 1.0.514
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.
|
@@ -232,10 +232,10 @@ async function handleComputationTask(message, config, dependencies) {
|
|
|
232
232
|
await db.doc(ledgerPath).update({ status: 'COMPLETED', completedAt: new Date() });
|
|
233
233
|
await recordRunAttempt(db, { date, computation, pass }, 'SUCCESS', null, metrics, triggerReason, resourceTier);
|
|
234
234
|
|
|
235
|
+
const { notifyComputationComplete, getComputationDisplayName } = require('../../generic-api/user-api/helpers/notifications/notification_helpers');
|
|
235
236
|
// Send notification if this was an on-demand computation
|
|
236
237
|
if (metadata?.onDemand && metadata?.requestId && metadata?.requestingUserCid) {
|
|
237
238
|
try {
|
|
238
|
-
const { notifyComputationComplete, getComputationDisplayName } = require('../../generic-api/user-api/helpers/notification_helpers');
|
|
239
239
|
await notifyComputationComplete(
|
|
240
240
|
dependencies.db,
|
|
241
241
|
dependencies.logger,
|
|
@@ -283,7 +283,6 @@ async function handleComputationTask(message, config, dependencies) {
|
|
|
283
283
|
// Send error notification if this was an on-demand computation
|
|
284
284
|
if (metadata?.onDemand && metadata?.requestId && metadata?.requestingUserCid) {
|
|
285
285
|
try {
|
|
286
|
-
const { notifyComputationComplete, getComputationDisplayName } = require('../../generic-api/user-api/helpers/notification_helpers');
|
|
287
286
|
await notifyComputationComplete(
|
|
288
287
|
db,
|
|
289
288
|
dependencies.logger,
|
|
@@ -74,25 +74,95 @@ async function requestUserSync(req, res, dependencies, config) {
|
|
|
74
74
|
// Determine user type (PI or signed-in user)
|
|
75
75
|
// Check if user is in rankings (PI) or has signed-in user data
|
|
76
76
|
const { checkIfUserIsPI } = require('../data_helpers');
|
|
77
|
-
|
|
77
|
+
let isPI = await checkIfUserIsPI(db, targetCidNum, config, logger);
|
|
78
|
+
|
|
79
|
+
// Fallback: If not found in rankings, check if they have PI data (portfolio, history, or social)
|
|
80
|
+
// This handles cases where a PI might not be in the latest rankings but has historical data
|
|
81
|
+
if (!isPI) {
|
|
82
|
+
try {
|
|
83
|
+
const today = new Date().toISOString().split('T')[0];
|
|
84
|
+
let hasPiData = false;
|
|
85
|
+
|
|
86
|
+
// Check if they have PI portfolio data (any date in last 7 days)
|
|
87
|
+
for (let i = 0; i <= 7; i++) {
|
|
88
|
+
const checkDate = new Date();
|
|
89
|
+
checkDate.setDate(checkDate.getDate() - i);
|
|
90
|
+
const dateStr = checkDate.toISOString().split('T')[0];
|
|
91
|
+
|
|
92
|
+
// Check portfolio data
|
|
93
|
+
const portfolioRef = db.collection('PopularInvestorPortfolioData')
|
|
94
|
+
.doc(dateStr)
|
|
95
|
+
.collection(String(targetCidNum))
|
|
96
|
+
.doc(String(targetCidNum));
|
|
97
|
+
const portfolioDoc = await portfolioRef.get();
|
|
98
|
+
|
|
99
|
+
if (portfolioDoc.exists) {
|
|
100
|
+
logger.log('INFO', `[requestUserSync] User ${targetCidNum} has PI portfolio data from ${dateStr}, treating as PI`);
|
|
101
|
+
hasPiData = true;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Check trade history data
|
|
106
|
+
const historyRef = db.collection('PopularInvestorTradeHistoryData')
|
|
107
|
+
.doc(dateStr)
|
|
108
|
+
.collection(String(targetCidNum))
|
|
109
|
+
.doc(String(targetCidNum));
|
|
110
|
+
const historyDoc = await historyRef.get();
|
|
111
|
+
|
|
112
|
+
if (historyDoc.exists) {
|
|
113
|
+
logger.log('INFO', `[requestUserSync] User ${targetCidNum} has PI trade history data from ${dateStr}, treating as PI`);
|
|
114
|
+
hasPiData = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Check social posts data
|
|
119
|
+
const socialRef = db.collection('PopularInvestorSocialPostData')
|
|
120
|
+
.doc(dateStr)
|
|
121
|
+
.collection(String(targetCidNum))
|
|
122
|
+
.doc(String(targetCidNum));
|
|
123
|
+
const socialDoc = await socialRef.get();
|
|
124
|
+
|
|
125
|
+
if (socialDoc.exists) {
|
|
126
|
+
logger.log('INFO', `[requestUserSync] User ${targetCidNum} has PI social posts data from ${dateStr}, treating as PI`);
|
|
127
|
+
hasPiData = true;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (hasPiData) {
|
|
133
|
+
isPI = { CustomerId: targetCidNum, UserName: null }; // Fake ranking entry
|
|
134
|
+
} else {
|
|
135
|
+
logger.log('INFO', `[requestUserSync] User ${targetCidNum} not found in rankings and no PI data found, treating as signed-in user`);
|
|
136
|
+
}
|
|
137
|
+
} catch (fallbackErr) {
|
|
138
|
+
logger.log('WARN', `[requestUserSync] Error checking PI data fallback for ${targetCidNum}:`, fallbackErr.message);
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
logger.log('INFO', `[requestUserSync] User ${targetCidNum} found in rankings as PI`);
|
|
142
|
+
}
|
|
78
143
|
|
|
79
144
|
// Get username - for PIs, get from rankings; for signed-in users, we'll need to fetch from their profile
|
|
80
145
|
let username = null;
|
|
81
146
|
if (isPI) {
|
|
82
|
-
// Get PI username from rankings
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
if (
|
|
95
|
-
|
|
147
|
+
// Get PI username from rankings (if available)
|
|
148
|
+
if (isPI.UserName || isPI.username) {
|
|
149
|
+
username = isPI.UserName || isPI.username;
|
|
150
|
+
} else {
|
|
151
|
+
// Try to get from rankings if we have a fake entry
|
|
152
|
+
const { findLatestRankingsDate } = require('../data_helpers');
|
|
153
|
+
const rankingsCollection = config.popularInvestorRankingsCollection || 'popular_investor_rankings';
|
|
154
|
+
const rankingsDate = await findLatestRankingsDate(db, rankingsCollection, 30);
|
|
155
|
+
|
|
156
|
+
if (rankingsDate) {
|
|
157
|
+
const rankingsRef = db.collection(rankingsCollection).doc(rankingsDate);
|
|
158
|
+
const rankingsDoc = await rankingsRef.get();
|
|
159
|
+
if (rankingsDoc.exists) {
|
|
160
|
+
const rankingsData = rankingsDoc.data();
|
|
161
|
+
const rankingsItems = rankingsData.Items || [];
|
|
162
|
+
const rankingEntry = rankingsItems.find(item => Number(item.CustomerId) === targetCidNum);
|
|
163
|
+
if (rankingEntry) {
|
|
164
|
+
username = rankingEntry.UserName || rankingEntry.username || null;
|
|
165
|
+
}
|
|
96
166
|
}
|
|
97
167
|
}
|
|
98
168
|
}
|
|
@@ -172,7 +242,8 @@ async function requestUserSync(req, res, dependencies, config) {
|
|
|
172
242
|
targetCid: targetCidNum, // Target specific user for optimization
|
|
173
243
|
requestedAt: now.toISOString(),
|
|
174
244
|
isImpersonating: isImpersonating || false,
|
|
175
|
-
requestingUserCid: Number(requestingUserCid) // Store for notifications
|
|
245
|
+
requestingUserCid: Number(requestingUserCid), // Store for notifications
|
|
246
|
+
userType: isPI ? 'POPULAR_INVESTOR' : 'SIGNED_IN_USER' // Explicitly set userType in metadata
|
|
176
247
|
}
|
|
177
248
|
};
|
|
178
249
|
|
|
@@ -40,9 +40,9 @@ async function storeSignedInUserPortfolio({ db, logger, collectionRegistry, cid,
|
|
|
40
40
|
if (!getCollectionPath) {
|
|
41
41
|
throw new Error('collectionRegistry.getCollectionPath is required');
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
// Path is already a document path: SignedInUsers/{cid}/portfolio/latest (4 segments)
|
|
44
|
+
const userLatestPath = getCollectionPath('signedInUsers', 'portfolio', { cid });
|
|
45
|
+
const userLatestRef = db.doc(userLatestPath);
|
|
46
46
|
|
|
47
47
|
await userLatestRef.set({
|
|
48
48
|
...portfolioData,
|
|
@@ -84,9 +84,9 @@ async function storeSignedInUserTradeHistory({ db, logger, collectionRegistry, c
|
|
|
84
84
|
if (!getCollectionPath) {
|
|
85
85
|
throw new Error('collectionRegistry.getCollectionPath is required');
|
|
86
86
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
// Path is already a document path: SignedInUsers/{cid}/tradeHistory/latest (4 segments)
|
|
88
|
+
const userLatestPath = getCollectionPath('signedInUsers', 'tradeHistory', { cid });
|
|
89
|
+
const userLatestRef = db.doc(userLatestPath);
|
|
90
90
|
|
|
91
91
|
await userLatestRef.set({
|
|
92
92
|
...historyData,
|