bulltrackers-module 1.0.592 → 1.0.593
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.
- package/functions/old-generic-api/admin-api/index.js +895 -0
- package/functions/old-generic-api/helpers/api_helpers.js +457 -0
- package/functions/old-generic-api/index.js +204 -0
- package/functions/old-generic-api/user-api/helpers/alerts/alert_helpers.js +355 -0
- package/functions/old-generic-api/user-api/helpers/alerts/subscription_helpers.js +327 -0
- package/functions/old-generic-api/user-api/helpers/alerts/test_alert_helpers.js +212 -0
- package/functions/old-generic-api/user-api/helpers/collection_helpers.js +193 -0
- package/functions/old-generic-api/user-api/helpers/core/compression_helpers.js +68 -0
- package/functions/old-generic-api/user-api/helpers/core/data_lookup_helpers.js +256 -0
- package/functions/old-generic-api/user-api/helpers/core/path_resolution_helpers.js +640 -0
- package/functions/old-generic-api/user-api/helpers/core/user_status_helpers.js +195 -0
- package/functions/old-generic-api/user-api/helpers/data/computation_helpers.js +503 -0
- package/functions/old-generic-api/user-api/helpers/data/instrument_helpers.js +55 -0
- package/functions/old-generic-api/user-api/helpers/data/portfolio_helpers.js +245 -0
- package/functions/old-generic-api/user-api/helpers/data/social_helpers.js +174 -0
- package/functions/old-generic-api/user-api/helpers/data_helpers.js +87 -0
- package/functions/old-generic-api/user-api/helpers/dev/dev_helpers.js +336 -0
- package/functions/old-generic-api/user-api/helpers/fetch/on_demand_fetch_helpers.js +615 -0
- package/functions/old-generic-api/user-api/helpers/metrics/personalized_metrics_helpers.js +231 -0
- package/functions/old-generic-api/user-api/helpers/notifications/notification_helpers.js +641 -0
- package/functions/old-generic-api/user-api/helpers/profile/pi_profile_helpers.js +182 -0
- package/functions/old-generic-api/user-api/helpers/profile/profile_view_helpers.js +137 -0
- package/functions/old-generic-api/user-api/helpers/profile/user_profile_helpers.js +190 -0
- package/functions/old-generic-api/user-api/helpers/recommendations/recommendation_helpers.js +66 -0
- package/functions/old-generic-api/user-api/helpers/reviews/review_helpers.js +550 -0
- package/functions/old-generic-api/user-api/helpers/rootdata/rootdata_aggregation_helpers.js +378 -0
- package/functions/old-generic-api/user-api/helpers/search/pi_request_helpers.js +295 -0
- package/functions/old-generic-api/user-api/helpers/search/pi_search_helpers.js +162 -0
- package/functions/old-generic-api/user-api/helpers/sync/user_sync_helpers.js +677 -0
- package/functions/old-generic-api/user-api/helpers/verification/verification_helpers.js +323 -0
- package/functions/old-generic-api/user-api/helpers/watchlist/watchlist_analytics_helpers.js +96 -0
- package/functions/old-generic-api/user-api/helpers/watchlist/watchlist_data_helpers.js +141 -0
- package/functions/old-generic-api/user-api/helpers/watchlist/watchlist_generation_helpers.js +310 -0
- package/functions/old-generic-api/user-api/helpers/watchlist/watchlist_management_helpers.js +829 -0
- package/functions/old-generic-api/user-api/index.js +109 -0
- package/package.json +2 -2
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview User Status Helpers
|
|
3
|
+
* Functions to check user status (PI, signed-in, etc.)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { findLatestRankingsDate } = require('./data_lookup_helpers');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get Popular Investor master list from Firestore
|
|
10
|
+
* @param {Firestore} db - Firestore instance
|
|
11
|
+
* @param {object} collectionRegistry - Collection registry (optional)
|
|
12
|
+
* @param {object} logger - Logger instance (optional)
|
|
13
|
+
* @returns {Promise<object>} - Master list investors map { cid: { cid, username, firstSeenAt, lastSeenAt } }
|
|
14
|
+
*/
|
|
15
|
+
async function getPIMasterList(db, collectionRegistry = null, logger = null) {
|
|
16
|
+
try {
|
|
17
|
+
let masterListPath = 'system_state/popular_investor_master_list';
|
|
18
|
+
|
|
19
|
+
if (collectionRegistry && collectionRegistry.getCollectionPath) {
|
|
20
|
+
try {
|
|
21
|
+
masterListPath = collectionRegistry.getCollectionPath('system', 'popularInvestorMasterList', {});
|
|
22
|
+
} catch (err) {
|
|
23
|
+
if (logger) {
|
|
24
|
+
logger.log('WARN', `[getPIMasterList] Failed to get master list path from registry, using default: ${err.message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const masterListRef = db.doc(masterListPath);
|
|
30
|
+
const masterListDoc = await masterListRef.get();
|
|
31
|
+
|
|
32
|
+
if (!masterListDoc.exists) {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const masterListData = masterListDoc.data();
|
|
37
|
+
return masterListData.investors || {};
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (logger) {
|
|
40
|
+
logger.log('ERROR', `[getPIMasterList] Error loading master list: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get PI username from CID using master list
|
|
48
|
+
* @param {Firestore} db - Firestore instance
|
|
49
|
+
* @param {string|number} piCid - Popular Investor CID
|
|
50
|
+
* @param {object} collectionRegistry - Collection registry (optional)
|
|
51
|
+
* @param {object} logger - Logger instance (optional)
|
|
52
|
+
* @returns {Promise<string|null>} - Username or null if not found
|
|
53
|
+
*/
|
|
54
|
+
async function getPIUsernameFromMasterList(db, piCid, collectionRegistry = null, logger = null) {
|
|
55
|
+
try {
|
|
56
|
+
const investors = await getPIMasterList(db, collectionRegistry, logger);
|
|
57
|
+
const cidStr = String(piCid);
|
|
58
|
+
const investor = investors[cidStr];
|
|
59
|
+
|
|
60
|
+
if (investor && investor.username) {
|
|
61
|
+
return investor.username;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return null;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
if (logger) {
|
|
67
|
+
logger.log('ERROR', `[getPIUsernameFromMasterList] Error getting username for PI ${piCid}: ${error.message}`);
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get PI CID from username using master list
|
|
75
|
+
* @param {Firestore} db - Firestore instance
|
|
76
|
+
* @param {string} username - Popular Investor username
|
|
77
|
+
* @param {object} collectionRegistry - Collection registry (optional)
|
|
78
|
+
* @param {object} logger - Logger instance (optional)
|
|
79
|
+
* @returns {Promise<string|null>} - CID or null if not found
|
|
80
|
+
*/
|
|
81
|
+
async function getPICidFromMasterList(db, username, collectionRegistry = null, logger = null) {
|
|
82
|
+
try {
|
|
83
|
+
const investors = await getPIMasterList(db, collectionRegistry, logger);
|
|
84
|
+
const searchUsername = username.toLowerCase().trim();
|
|
85
|
+
|
|
86
|
+
for (const [cid, investor] of Object.entries(investors)) {
|
|
87
|
+
if (investor.username && investor.username.toLowerCase().trim() === searchUsername) {
|
|
88
|
+
return cid;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return null;
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (logger) {
|
|
95
|
+
logger.log('ERROR', `[getPICidFromMasterList] Error getting CID for username ${username}: ${error.message}`);
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Check if a CID is a Popular Investor using master list
|
|
103
|
+
* @param {Firestore} db - Firestore instance
|
|
104
|
+
* @param {string|number} cid - User CID
|
|
105
|
+
* @param {object} collectionRegistry - Collection registry (optional)
|
|
106
|
+
* @param {object} logger - Logger instance (optional)
|
|
107
|
+
* @returns {Promise<boolean>} - True if PI, false otherwise
|
|
108
|
+
*/
|
|
109
|
+
async function isPopularInvestor(db, cid, collectionRegistry = null, logger = null) {
|
|
110
|
+
try {
|
|
111
|
+
const investors = await getPIMasterList(db, collectionRegistry, logger);
|
|
112
|
+
const cidStr = String(cid);
|
|
113
|
+
return investors.hasOwnProperty(cidStr);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
if (logger) {
|
|
116
|
+
logger.log('ERROR', `[isPopularInvestor] Error checking if ${cid} is PI: ${error.message}`);
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Check if a signed-in user is also a Popular Investor
|
|
124
|
+
* Returns ranking entry if found, null otherwise
|
|
125
|
+
* Checks dev overrides first for pretendToBePI flag
|
|
126
|
+
* @param {Firestore} db - Firestore instance
|
|
127
|
+
* @param {string|number} userCid - User CID
|
|
128
|
+
* @param {object} config - Configuration object
|
|
129
|
+
* @param {object} logger - Logger instance (optional)
|
|
130
|
+
* @returns {Promise<object|null>} - Ranking entry or null
|
|
131
|
+
*/
|
|
132
|
+
async function checkIfUserIsPI(db, userCid, config, logger = null) {
|
|
133
|
+
try {
|
|
134
|
+
// Check dev override first (for developer accounts)
|
|
135
|
+
const { getDevOverride } = require('../dev/dev_helpers');
|
|
136
|
+
const devOverride = await getDevOverride(db, userCid, config, logger);
|
|
137
|
+
|
|
138
|
+
if (devOverride && devOverride.enabled && devOverride.pretendToBePI) {
|
|
139
|
+
// Generate fake ranking entry for dev testing
|
|
140
|
+
const fakeRankEntry = {
|
|
141
|
+
CustomerId: Number(userCid),
|
|
142
|
+
UserName: 'Dev Test PI',
|
|
143
|
+
AUMValue: 500000 + Math.floor(Math.random() * 1000000), // Random AUM between 500k-1.5M
|
|
144
|
+
Copiers: 150 + Math.floor(Math.random() * 200), // Random copiers between 150-350
|
|
145
|
+
RiskScore: 3 + Math.floor(Math.random() * 3), // Random risk score 3-5
|
|
146
|
+
Gain: 25 + Math.floor(Math.random() * 50), // Random gain 25-75%
|
|
147
|
+
WinRatio: 50 + Math.floor(Math.random() * 20), // Random win ratio 50-70%
|
|
148
|
+
Trades: 500 + Math.floor(Math.random() * 1000) // Random trades 500-1500
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
if (logger && logger.log) {
|
|
152
|
+
logger.log('INFO', `[checkIfUserIsPI] DEV OVERRIDE: User ${userCid} pretending to be PI with fake ranking data`);
|
|
153
|
+
} else {
|
|
154
|
+
console.log(`[checkIfUserIsPI] DEV OVERRIDE: User ${userCid} pretending to be PI with fake ranking data`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return fakeRankEntry;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Otherwise, check master list (single source of truth)
|
|
161
|
+
const collectionRegistry = config.collectionRegistry || null;
|
|
162
|
+
const isPI = await isPopularInvestor(db, userCid, collectionRegistry, logger);
|
|
163
|
+
|
|
164
|
+
if (!isPI) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Get username from master list
|
|
169
|
+
const username = await getPIUsernameFromMasterList(db, userCid, collectionRegistry, logger);
|
|
170
|
+
|
|
171
|
+
if (!username) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Return a ranking-like entry for compatibility (minimal data)
|
|
176
|
+
// Note: Full ranking data (AUM, copiers, etc.) is not in master list
|
|
177
|
+
// If full ranking data is needed, it should be fetched from rankings collection separately
|
|
178
|
+
return {
|
|
179
|
+
CustomerId: Number(userCid),
|
|
180
|
+
UserName: username
|
|
181
|
+
};
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error('[checkIfUserIsPI] Error checking if user is PI:', error);
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
module.exports = {
|
|
189
|
+
checkIfUserIsPI,
|
|
190
|
+
getPIMasterList,
|
|
191
|
+
getPIUsernameFromMasterList,
|
|
192
|
+
getPICidFromMasterList,
|
|
193
|
+
isPopularInvestor
|
|
194
|
+
};
|
|
195
|
+
|