bulltrackers-module 1.0.591 → 1.0.592

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.
Files changed (68) hide show
  1. package/functions/alert-system/helpers/alert_helpers.js +6 -6
  2. package/functions/alert-system/index.js +1 -1
  3. package/functions/api-v2/helpers/data-fetchers/firestore.js +2218 -0
  4. package/functions/api-v2/helpers/task_engine_helper.js +51 -0
  5. package/functions/api-v2/index.js +36 -0
  6. package/functions/api-v2/middleware/identity_middleware.js +48 -0
  7. package/functions/api-v2/package.json +6 -0
  8. package/functions/api-v2/routes/alerts.js +168 -0
  9. package/functions/api-v2/routes/index.js +35 -0
  10. package/functions/api-v2/routes/notifications.js +38 -0
  11. package/functions/api-v2/routes/popular_investors.js +204 -0
  12. package/functions/api-v2/routes/profile.js +212 -0
  13. package/functions/api-v2/routes/reviews.js +72 -0
  14. package/functions/api-v2/routes/settings.js +71 -0
  15. package/functions/api-v2/routes/sync.js +132 -0
  16. package/functions/api-v2/routes/verification.js +47 -0
  17. package/functions/api-v2/routes/watchlists.js +148 -0
  18. package/functions/computation-system/helpers/computation_worker.js +1 -1
  19. package/functions/task-engine/helpers/popular_investor_helpers.js +2 -2
  20. package/index.js +6 -2
  21. package/package.json +2 -1
  22. package/functions/generic-api/admin-api/index.js +0 -895
  23. package/functions/generic-api/helpers/api_helpers.js +0 -457
  24. package/functions/generic-api/index.js +0 -204
  25. package/functions/generic-api/user-api/ADDING_LEGACY_ROUTES_GUIDE.md +0 -345
  26. package/functions/generic-api/user-api/CODE_REORGANIZATION_PLAN.md +0 -320
  27. package/functions/generic-api/user-api/COMPLETE_REFACTORING_PLAN.md +0 -116
  28. package/functions/generic-api/user-api/FIRESTORE_PATHS_INVENTORY.md +0 -171
  29. package/functions/generic-api/user-api/FIRESTORE_PATH_MIGRATION_REFERENCE.md +0 -710
  30. package/functions/generic-api/user-api/FIRESTORE_PATH_VALIDATION.md +0 -109
  31. package/functions/generic-api/user-api/MIGRATION_PLAN.md +0 -499
  32. package/functions/generic-api/user-api/README_MIGRATION.md +0 -152
  33. package/functions/generic-api/user-api/REFACTORING_COMPLETE.md +0 -106
  34. package/functions/generic-api/user-api/REFACTORING_STATUS.md +0 -85
  35. package/functions/generic-api/user-api/VERIFICATION_MIGRATION_NOTES.md +0 -206
  36. package/functions/generic-api/user-api/helpers/ORGANIZATION_COMPLETE.md +0 -126
  37. package/functions/generic-api/user-api/helpers/alerts/alert_helpers.js +0 -355
  38. package/functions/generic-api/user-api/helpers/alerts/subscription_helpers.js +0 -327
  39. package/functions/generic-api/user-api/helpers/alerts/test_alert_helpers.js +0 -212
  40. package/functions/generic-api/user-api/helpers/collection_helpers.js +0 -193
  41. package/functions/generic-api/user-api/helpers/core/compression_helpers.js +0 -68
  42. package/functions/generic-api/user-api/helpers/core/data_lookup_helpers.js +0 -256
  43. package/functions/generic-api/user-api/helpers/core/path_resolution_helpers.js +0 -640
  44. package/functions/generic-api/user-api/helpers/core/user_status_helpers.js +0 -195
  45. package/functions/generic-api/user-api/helpers/data/computation_helpers.js +0 -503
  46. package/functions/generic-api/user-api/helpers/data/instrument_helpers.js +0 -55
  47. package/functions/generic-api/user-api/helpers/data/portfolio_helpers.js +0 -245
  48. package/functions/generic-api/user-api/helpers/data/social_helpers.js +0 -174
  49. package/functions/generic-api/user-api/helpers/data_helpers.js +0 -87
  50. package/functions/generic-api/user-api/helpers/dev/dev_helpers.js +0 -336
  51. package/functions/generic-api/user-api/helpers/fetch/on_demand_fetch_helpers.js +0 -615
  52. package/functions/generic-api/user-api/helpers/metrics/personalized_metrics_helpers.js +0 -231
  53. package/functions/generic-api/user-api/helpers/notifications/notification_helpers.js +0 -641
  54. package/functions/generic-api/user-api/helpers/profile/pi_profile_helpers.js +0 -182
  55. package/functions/generic-api/user-api/helpers/profile/profile_view_helpers.js +0 -137
  56. package/functions/generic-api/user-api/helpers/profile/user_profile_helpers.js +0 -190
  57. package/functions/generic-api/user-api/helpers/recommendations/recommendation_helpers.js +0 -66
  58. package/functions/generic-api/user-api/helpers/reviews/review_helpers.js +0 -550
  59. package/functions/generic-api/user-api/helpers/rootdata/rootdata_aggregation_helpers.js +0 -378
  60. package/functions/generic-api/user-api/helpers/search/pi_request_helpers.js +0 -295
  61. package/functions/generic-api/user-api/helpers/search/pi_search_helpers.js +0 -162
  62. package/functions/generic-api/user-api/helpers/sync/user_sync_helpers.js +0 -677
  63. package/functions/generic-api/user-api/helpers/verification/verification_helpers.js +0 -323
  64. package/functions/generic-api/user-api/helpers/watchlist/watchlist_analytics_helpers.js +0 -96
  65. package/functions/generic-api/user-api/helpers/watchlist/watchlist_data_helpers.js +0 -141
  66. package/functions/generic-api/user-api/helpers/watchlist/watchlist_generation_helpers.js +0 -310
  67. package/functions/generic-api/user-api/helpers/watchlist/watchlist_management_helpers.js +0 -829
  68. package/functions/generic-api/user-api/index.js +0 -109
@@ -1,336 +0,0 @@
1
- /**
2
- * @fileoverview Developer Mode Helpers
3
- * Allows specific developer accounts to override copied PI data for testing
4
- * SECURITY: Only works for whitelisted developer CIDs
5
- */
6
-
7
- const { FieldValue } = require('@google-cloud/firestore');
8
-
9
- // Whitelist of developer account CIDs that can use dev mode
10
- const DEVELOPER_CIDS = [
11
- 29312236 // Aiden Hawkins - marau2021
12
- ];
13
-
14
- /**
15
- * Check if a user CID is a developer account
16
- */
17
- function isDeveloperAccount(userCid) {
18
- return DEVELOPER_CIDS.includes(Number(userCid));
19
- }
20
-
21
- /**
22
- * Get developer override data for a user
23
- * Auto-creates default document if it doesn't exist (for developer accounts only)
24
- * Returns null if not a developerg,
25
- */
26
- async function getDevOverride(db, userCid, config, logger = null) {
27
- if (!isDeveloperAccount(userCid)) {
28
- return null;
29
- }
30
-
31
- try {
32
- const devOverridesCollection = config.devOverridesCollection || 'dev_overrides';
33
- const overrideRef = db.collection(devOverridesCollection).doc(String(userCid));
34
- const overrideDoc = await overrideRef.get();
35
-
36
- // Auto-create default document if it doesn't exist
37
- if (!overrideDoc.exists) {
38
- const defaultData = {
39
- userCid: Number(userCid),
40
- enabled: false,
41
- fakeCopiedPIs: [],
42
- pretendToBePI: false,
43
- impersonateCid: null, // CID to impersonate/view as
44
- pretendSubscribedToAllAlerts: false, // Pretend to be subscribed to all alert types for all PIs
45
- createdAt: FieldValue.serverTimestamp(),
46
- lastUpdated: FieldValue.serverTimestamp()
47
- };
48
-
49
- await overrideRef.set(defaultData);
50
-
51
- const logMsg = `[getDevOverride] Auto-created default dev override document for developer account ${userCid}`;
52
- if (logger && logger.log) {
53
- logger.log('INFO', logMsg);
54
- } else {
55
- console.log(logMsg);
56
- }
57
-
58
- // Return the default (disabled) override
59
- return {
60
- enabled: false,
61
- fakeCopiedPIs: [],
62
- pretendToBePI: false,
63
- impersonateCid: null,
64
- pretendSubscribedToAllAlerts: false,
65
- lastUpdated: null,
66
- wasAutoCreated: true
67
- };
68
- }
69
-
70
- const data = overrideDoc.data();
71
-
72
- // Return override data (even if disabled, so caller knows it exists)
73
- return {
74
- enabled: data.enabled === true,
75
- fakeCopiedPIs: data.fakeCopiedPIs || [],
76
- pretendToBePI: data.pretendToBePI === true,
77
- impersonateCid: data.impersonateCid ? Number(data.impersonateCid) : null,
78
- pretendSubscribedToAllAlerts: data.pretendSubscribedToAllAlerts === true,
79
- lastUpdated: data.lastUpdated,
80
- wasAutoCreated: false
81
- };
82
- } catch (error) {
83
- console.error('[getDevOverride] Error fetching/creating dev override:', error);
84
- return null;
85
- }
86
- }
87
-
88
- /**
89
- * Get the list of copied PIs for a user, with dev override support
90
- * Returns { copiedPIs: Array, isDevOverride: boolean, dataSource: string }
91
- */
92
- async function getCopiedPIsWithDevOverride(db, userCid, config, logger) {
93
- const userCidNum = Number(userCid);
94
-
95
- // Check for dev override first (this will auto-create default if needed)
96
- const devOverride = await getDevOverride(db, userCid, config, logger);
97
-
98
- if (devOverride && devOverride.enabled && devOverride.fakeCopiedPIs.length > 0) {
99
- if (logger && logger.log) {
100
- logger.log('INFO', `[getCopiedPIsWithDevOverride] Using DEV OVERRIDE for user ${userCid}: ${devOverride.fakeCopiedPIs.length} fake copied PIs`);
101
- } else {
102
- console.log(`[getCopiedPIsWithDevOverride] Using DEV OVERRIDE for user ${userCid}: ${devOverride.fakeCopiedPIs.length} fake copied PIs`);
103
- }
104
-
105
- return {
106
- copiedPIs: devOverride.fakeCopiedPIs.map(cid => ({
107
- cid: Number(cid),
108
- username: 'Dev Override' // Will be resolved from rankings later
109
- })),
110
- isDevOverride: true,
111
- dataSource: 'dev_override'
112
- };
113
- }
114
-
115
- // Otherwise, use normal logic (computation or portfolio)
116
- // This will be handled by the calling function
117
- return {
118
- copiedPIs: [],
119
- isDevOverride: false,
120
- dataSource: 'normal'
121
- };
122
- }
123
-
124
- /**
125
- * Check if a user has copied a specific PI, with dev override support
126
- */
127
- async function hasUserCopiedWithDevOverride(db, userCid, piCid, config, logger) {
128
- const userCidNum = Number(userCid);
129
- const piCidNum = Number(piCid);
130
-
131
- // Check for dev override first (this will auto-create default if needed)
132
- const devOverride = await getDevOverride(db, userCid, config, logger);
133
-
134
- if (devOverride && devOverride.enabled) {
135
- const hasCopied = devOverride.fakeCopiedPIs.includes(piCidNum);
136
- if (hasCopied) {
137
- if (logger && logger.log) {
138
- logger.log('INFO', `[hasUserCopiedWithDevOverride] DEV OVERRIDE: User ${userCid} "copies" PI ${piCid}`);
139
- } else {
140
- console.log(`[hasUserCopiedWithDevOverride] DEV OVERRIDE: User ${userCid} "copies" PI ${piCid}`);
141
- }
142
- return true;
143
- }
144
- // If dev override is enabled but PI not in list, return false (don't check real data)
145
- if (logger && logger.log) {
146
- logger.log('INFO', `[hasUserCopiedWithDevOverride] DEV OVERRIDE: User ${userCid} does NOT "copy" PI ${piCid} (override enabled, PI not in fake list)`);
147
- } else {
148
- console.log(`[hasUserCopiedWithDevOverride] DEV OVERRIDE: User ${userCid} does NOT "copy" PI ${piCid} (override enabled, PI not in fake list)`);
149
- }
150
- return false;
151
- }
152
-
153
- // Otherwise, use normal logic (will be handled by calling function)
154
- return null; // null means "not a dev override, use normal logic"
155
- }
156
-
157
- /**
158
- * Create or update dev override for a developer account
159
- * SECURITY: Only works for whitelisted developer CIDs
160
- */
161
- async function setDevOverride(req, res, dependencies, config) {
162
- const { db, logger } = dependencies;
163
- const { userCid, enabled, fakeCopiedPIs, pretendToBePI, impersonateCid, pretendSubscribedToAllAlerts } = req.body;
164
-
165
- if (!userCid) {
166
- return res.status(400).json({ error: "Missing userCid" });
167
- }
168
-
169
- // SECURITY CHECK: Only allow whitelisted developer accounts
170
- if (!isDeveloperAccount(userCid)) {
171
- logger.log('WARN', `[setDevOverride] Unauthorized attempt to set dev override for user ${userCid}`);
172
- return res.status(403).json({
173
- error: "Forbidden",
174
- message: "Developer mode is only available for authorized developer accounts"
175
- });
176
- }
177
-
178
- // Validate fakeCopiedPIs (only required if enabled is true)
179
- if (enabled && (!Array.isArray(fakeCopiedPIs) || fakeCopiedPIs.length === 0)) {
180
- return res.status(400).json({
181
- error: "Invalid request",
182
- message: "When enabled, fakeCopiedPIs must be a non-empty array"
183
- });
184
- }
185
-
186
- // Validate impersonateCid if provided
187
- if (impersonateCid !== undefined && impersonateCid !== null) {
188
- const parsedCid = Number(impersonateCid);
189
- if (isNaN(parsedCid) || parsedCid <= 0) {
190
- return res.status(400).json({
191
- error: "Invalid request",
192
- message: "impersonateCid must be a positive number, or null to disable impersonation"
193
- });
194
- }
195
- }
196
-
197
- // Ensure all CIDs are numbers
198
- const validatedPIs = enabled ? fakeCopiedPIs.map(cid => Number(cid)).filter(cid => !isNaN(cid) && cid > 0) : [];
199
-
200
- try {
201
- const devOverridesCollection = config.devOverridesCollection || 'dev_overrides';
202
- const overrideRef = db.collection(devOverridesCollection).doc(String(userCid));
203
-
204
- // Get existing override to preserve values not being updated
205
- const existingDoc = await overrideRef.get();
206
- const existingData = existingDoc.exists ? existingDoc.data() : {};
207
-
208
- const overrideData = {
209
- userCid: Number(userCid),
210
- enabled: enabled !== undefined ? (enabled === true) : (existingData.enabled || false),
211
- fakeCopiedPIs: enabled !== undefined ? validatedPIs : (existingData.fakeCopiedPIs || []),
212
- pretendToBePI: pretendToBePI !== undefined ? (pretendToBePI === true) : (existingData.pretendToBePI || false),
213
- impersonateCid: impersonateCid !== undefined ? (impersonateCid ? Number(impersonateCid) : null) : (existingData.impersonateCid || null),
214
- pretendSubscribedToAllAlerts: pretendSubscribedToAllAlerts !== undefined ? (pretendSubscribedToAllAlerts === true) : (existingData.pretendSubscribedToAllAlerts || false),
215
- lastUpdated: FieldValue.serverTimestamp()
216
- };
217
-
218
- await overrideRef.set(overrideData, { merge: true });
219
-
220
- const logParts = [
221
- `enabled=${overrideData.enabled}`,
222
- `pretendToBePI=${overrideData.pretendToBePI}`,
223
- `impersonateCid=${overrideData.impersonateCid || 'null'}`,
224
- `pretendSubscribedToAllAlerts=${overrideData.pretendSubscribedToAllAlerts}`,
225
- `${validatedPIs.length} fake PIs`
226
- ];
227
- logger.log('SUCCESS', `[setDevOverride] Updated dev override for user ${userCid}: ${logParts.join(', ')}`);
228
-
229
- return res.status(200).json({
230
- success: true,
231
- message: "Developer override updated",
232
- override: overrideData
233
- });
234
-
235
- } catch (error) {
236
- logger.log('ERROR', `[setDevOverride] Error updating dev override:`, error);
237
- return res.status(500).json({ error: error.message });
238
- }
239
- }
240
-
241
- /**
242
- * Get current dev override status for a developer account
243
- */
244
- async function getDevOverrideStatus(req, res, dependencies, config) {
245
- const { db, logger } = dependencies;
246
- const { userCid } = req.query;
247
-
248
- if (!userCid) {
249
- return res.status(400).json({ error: "Missing userCid" });
250
- }
251
-
252
- // SECURITY CHECK: Only allow whitelisted developer accounts
253
- if (!isDeveloperAccount(userCid)) {
254
- return res.status(403).json({
255
- error: "Forbidden",
256
- message: "Developer mode is only available for authorized developer accounts"
257
- });
258
- }
259
-
260
- try {
261
- // This will auto-create default document if it doesn't exist
262
- const devOverride = await getDevOverride(db, userCid, config, logger);
263
-
264
- if (!devOverride) {
265
- // Should not happen for developer accounts, but handle gracefully
266
- return res.status(200).json({
267
- enabled: false,
268
- fakeCopiedPIs: [],
269
- message: "No dev override configured"
270
- });
271
- }
272
-
273
- return res.status(200).json({
274
- enabled: devOverride.enabled,
275
- fakeCopiedPIs: devOverride.fakeCopiedPIs,
276
- pretendToBePI: devOverride.pretendToBePI || false,
277
- impersonateCid: devOverride.impersonateCid || null,
278
- pretendSubscribedToAllAlerts: devOverride.pretendSubscribedToAllAlerts || false,
279
- lastUpdated: devOverride.lastUpdated,
280
- wasAutoCreated: devOverride.wasAutoCreated || false
281
- });
282
-
283
- } catch (error) {
284
- logger.log('ERROR', `[getDevOverrideStatus] Error fetching dev override:`, error);
285
- return res.status(500).json({ error: error.message });
286
- }
287
- }
288
-
289
- /**
290
- * Get the effective CID to use for a developer account
291
- * Returns impersonateCid if set, otherwise returns the actual userCid
292
- * Only works for developer accounts
293
- *
294
- * Note: If pretendToBePI is false, impersonation will not be used for PI-related checks
295
- * to prevent unintended impersonation when the user doesn't want to pretend to be a PI
296
- */
297
- async function getEffectiveCid(db, userCid, config, logger = null) {
298
- if (!isDeveloperAccount(userCid)) {
299
- return Number(userCid); // Not a developer, return actual CID
300
- }
301
-
302
- const devOverride = await getDevOverride(db, userCid, config, logger);
303
- // Only use impersonation if dev override is enabled AND impersonateCid is set
304
- // BUT: If pretendToBePI is explicitly false, don't use impersonation (user doesn't want to be treated as PI)
305
- if (devOverride && devOverride.enabled && devOverride.impersonateCid) {
306
- // Check if user explicitly doesn't want to pretend to be a PI
307
- // If pretendToBePI is false, don't use impersonation (respects user intent)
308
- if (devOverride.pretendToBePI === false) {
309
- if (logger && logger.log) {
310
- logger.log('INFO', `[getEffectiveCid] DEV OVERRIDE: User ${userCid} has impersonateCid set but pretendToBePI=false, using actual CID ${userCid} instead`);
311
- } else {
312
- console.log(`[getEffectiveCid] DEV OVERRIDE: User ${userCid} has impersonateCid set but pretendToBePI=false, using actual CID ${userCid} instead`);
313
- }
314
- return Number(userCid);
315
- }
316
-
317
- if (logger && logger.log) {
318
- logger.log('INFO', `[getEffectiveCid] DEV OVERRIDE: User ${userCid} impersonating CID ${devOverride.impersonateCid}`);
319
- } else {
320
- console.log(`[getEffectiveCid] DEV OVERRIDE: User ${userCid} impersonating CID ${devOverride.impersonateCid}`);
321
- }
322
- return Number(devOverride.impersonateCid);
323
- }
324
-
325
- return Number(userCid);
326
- }
327
-
328
- module.exports = {
329
- isDeveloperAccount,
330
- getDevOverride,
331
- getCopiedPIsWithDevOverride,
332
- hasUserCopiedWithDevOverride,
333
- setDevOverride,
334
- getDevOverrideStatus,
335
- getEffectiveCid
336
- };