bulltrackers-module 1.0.591 → 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.
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 +3 -2
  22. package/functions/generic-api/user-api/ADDING_LEGACY_ROUTES_GUIDE.md +0 -345
  23. package/functions/generic-api/user-api/CODE_REORGANIZATION_PLAN.md +0 -320
  24. package/functions/generic-api/user-api/COMPLETE_REFACTORING_PLAN.md +0 -116
  25. package/functions/generic-api/user-api/FIRESTORE_PATHS_INVENTORY.md +0 -171
  26. package/functions/generic-api/user-api/FIRESTORE_PATH_MIGRATION_REFERENCE.md +0 -710
  27. package/functions/generic-api/user-api/FIRESTORE_PATH_VALIDATION.md +0 -109
  28. package/functions/generic-api/user-api/MIGRATION_PLAN.md +0 -499
  29. package/functions/generic-api/user-api/README_MIGRATION.md +0 -152
  30. package/functions/generic-api/user-api/REFACTORING_COMPLETE.md +0 -106
  31. package/functions/generic-api/user-api/REFACTORING_STATUS.md +0 -85
  32. package/functions/generic-api/user-api/VERIFICATION_MIGRATION_NOTES.md +0 -206
  33. package/functions/generic-api/user-api/helpers/ORGANIZATION_COMPLETE.md +0 -126
  34. /package/functions/{generic-api → old-generic-api}/admin-api/index.js +0 -0
  35. /package/functions/{generic-api → old-generic-api}/helpers/api_helpers.js +0 -0
  36. /package/functions/{generic-api → old-generic-api}/index.js +0 -0
  37. /package/functions/{generic-api → old-generic-api}/user-api/helpers/alerts/alert_helpers.js +0 -0
  38. /package/functions/{generic-api → old-generic-api}/user-api/helpers/alerts/subscription_helpers.js +0 -0
  39. /package/functions/{generic-api → old-generic-api}/user-api/helpers/alerts/test_alert_helpers.js +0 -0
  40. /package/functions/{generic-api → old-generic-api}/user-api/helpers/collection_helpers.js +0 -0
  41. /package/functions/{generic-api → old-generic-api}/user-api/helpers/core/compression_helpers.js +0 -0
  42. /package/functions/{generic-api → old-generic-api}/user-api/helpers/core/data_lookup_helpers.js +0 -0
  43. /package/functions/{generic-api → old-generic-api}/user-api/helpers/core/path_resolution_helpers.js +0 -0
  44. /package/functions/{generic-api → old-generic-api}/user-api/helpers/core/user_status_helpers.js +0 -0
  45. /package/functions/{generic-api → old-generic-api}/user-api/helpers/data/computation_helpers.js +0 -0
  46. /package/functions/{generic-api → old-generic-api}/user-api/helpers/data/instrument_helpers.js +0 -0
  47. /package/functions/{generic-api → old-generic-api}/user-api/helpers/data/portfolio_helpers.js +0 -0
  48. /package/functions/{generic-api → old-generic-api}/user-api/helpers/data/social_helpers.js +0 -0
  49. /package/functions/{generic-api → old-generic-api}/user-api/helpers/data_helpers.js +0 -0
  50. /package/functions/{generic-api → old-generic-api}/user-api/helpers/dev/dev_helpers.js +0 -0
  51. /package/functions/{generic-api → old-generic-api}/user-api/helpers/fetch/on_demand_fetch_helpers.js +0 -0
  52. /package/functions/{generic-api → old-generic-api}/user-api/helpers/metrics/personalized_metrics_helpers.js +0 -0
  53. /package/functions/{generic-api → old-generic-api}/user-api/helpers/notifications/notification_helpers.js +0 -0
  54. /package/functions/{generic-api → old-generic-api}/user-api/helpers/profile/pi_profile_helpers.js +0 -0
  55. /package/functions/{generic-api → old-generic-api}/user-api/helpers/profile/profile_view_helpers.js +0 -0
  56. /package/functions/{generic-api → old-generic-api}/user-api/helpers/profile/user_profile_helpers.js +0 -0
  57. /package/functions/{generic-api → old-generic-api}/user-api/helpers/recommendations/recommendation_helpers.js +0 -0
  58. /package/functions/{generic-api → old-generic-api}/user-api/helpers/reviews/review_helpers.js +0 -0
  59. /package/functions/{generic-api → old-generic-api}/user-api/helpers/rootdata/rootdata_aggregation_helpers.js +0 -0
  60. /package/functions/{generic-api → old-generic-api}/user-api/helpers/search/pi_request_helpers.js +0 -0
  61. /package/functions/{generic-api → old-generic-api}/user-api/helpers/search/pi_search_helpers.js +0 -0
  62. /package/functions/{generic-api → old-generic-api}/user-api/helpers/sync/user_sync_helpers.js +0 -0
  63. /package/functions/{generic-api → old-generic-api}/user-api/helpers/verification/verification_helpers.js +0 -0
  64. /package/functions/{generic-api → old-generic-api}/user-api/helpers/watchlist/watchlist_analytics_helpers.js +0 -0
  65. /package/functions/{generic-api → old-generic-api}/user-api/helpers/watchlist/watchlist_data_helpers.js +0 -0
  66. /package/functions/{generic-api → old-generic-api}/user-api/helpers/watchlist/watchlist_generation_helpers.js +0 -0
  67. /package/functions/{generic-api → old-generic-api}/user-api/helpers/watchlist/watchlist_management_helpers.js +0 -0
  68. /package/functions/{generic-api → old-generic-api}/user-api/index.js +0 -0
@@ -7,7 +7,7 @@
7
7
  const crypto = require('crypto');
8
8
  const { shouldTryProxy, recordProxyOutcome, getFailureCount, getMaxFailures } = require('../utils/proxy_circuit_breaker');
9
9
  const { FieldValue } = require('@google-cloud/firestore');
10
- const { notifyTaskEngineComplete, notifyTaskEngineProgress, notifyPIDataRefreshed } = require('../../generic-api/user-api/helpers/notifications/notification_helpers');
10
+ const { notifyTaskEngineComplete, notifyTaskEngineProgress, notifyPIDataRefreshed } = require('../../old-generic-api/user-api/helpers/notifications/notification_helpers');
11
11
  const { conditionallyRunRootDataIndexer } = require('./root_data_indexer_helpers');
12
12
 
13
13
  const {
@@ -405,7 +405,7 @@ async function finalizeOnDemandRequest(deps, config, taskData, isPI, success, to
405
405
  // 2. Trigger Computations (only if root data indexer completed successfully)
406
406
  if (indexerCompleted && pubsub && config.computationSystem) {
407
407
  const { triggerComputationWithDependencies } = require('../../computation-system/helpers/on_demand_helpers');
408
- const { checkIfUserIsPI } = require('../../generic-api/user-api/helpers/core/user_status_helpers');
408
+ const { checkIfUserIsPI } = require('../../old-generic-api/user-api/helpers/core/user_status_helpers');
409
409
 
410
410
  // Use userType from metadata if available, otherwise fall back to isPI
411
411
  const userType = metadata?.userType || (isPI ? 'POPULAR_INVESTOR' : 'SIGNED_IN_USER');
package/index.js CHANGED
@@ -47,8 +47,11 @@ const dataLoader = require('./functions
47
47
  const computationUtils = require('./functions/computation-system/utils/utils');
48
48
 
49
49
  // API
50
- const { createApiApp } = require('./functions/generic-api/index');
51
- const apiHelpers = require('./functions/generic-api/helpers/api_helpers');
50
+ const { createApiApp } = require('./functions/old-generic-api/index');
51
+ const apiHelpers = require('./functions/old-generic-api/helpers/api_helpers');
52
+
53
+ // API v2 (CommonJS)
54
+ const { createApiV2App } = require('./functions/api-v2/index');
52
55
 
53
56
  // Maintenance & Data Acquisition
54
57
  const { runCleanup } = require('./functions/speculator-cleanup-orchestrator/helpers/cleanup_helpers');
@@ -115,6 +118,7 @@ const computationSystem = {
115
118
 
116
119
  const api = {
117
120
  createApiApp,
121
+ createApiV2App, // New API v2 entry point
118
122
  helpers: apiHelpers,
119
123
  };
120
124
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.591",
3
+ "version": "1.0.593",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -9,7 +9,8 @@
9
9
  "functions/task-engine/",
10
10
  "functions/core/",
11
11
  "functions/computation-system/",
12
- "functions/generic-api/",
12
+ "functions/old-generic-api/",
13
+ "functions/api-v2/",
13
14
  "functions/dispatcher/",
14
15
  "functions/invalid-speculator-handler/",
15
16
  "functions/speculator-cleanup-orchestrator/",
@@ -1,345 +0,0 @@
1
- # Adding New Legacy Routes for Auto-Migration
2
-
3
- ## How Easy Is It?
4
-
5
- **Answer: Very Easy!** Adding a new legacy route requires updating **just 1 location** in most cases!
6
-
7
- **Even Easier:** The system now automatically reads legacy paths from the collection registry, so you typically only need to add one line to the registry!
8
-
9
- ---
10
-
11
- ## Quick Overview
12
-
13
- The auto-migration system works by:
14
- 1. **Trying new path first** - Reads from the new CID-based path
15
- 2. **Falling back to legacy** - If not found, tries legacy path(s) from registry
16
- 3. **Auto-migrating** - If found in legacy, automatically migrates to new path
17
-
18
- To add a new legacy route, you typically only need to:
19
- 1. **`collection_registry.js`** - Add to `legacyPaths` array (that's it!)
20
-
21
- **Only if you need complex conditional logic:**
22
- 2. **`path_resolution_helpers.js`** - Add to `legacyPathMap` object (fallback)
23
-
24
- ---
25
-
26
- ## Step-by-Step Guide
27
-
28
- ### ✅ EASIEST WAY: Just Add to Collection Registry (Recommended)
29
-
30
- **File:** `Backend/Entrypoints/BullTrackers/Backend/Core/config/collection_registry.js`
31
-
32
- **Location:** Find your collection definition and add to `legacyPaths` array
33
-
34
- **Example:**
35
- ```javascript
36
- notifications: {
37
- path: 'SignedInUsers/{cid}/notifications',
38
- description: 'User notifications',
39
- dynamicSegments: ['{cid}'],
40
- status: 'active',
41
- legacyPaths: [
42
- 'user_notifications/{firebaseUid}/notifications', // Existing
43
- 'user_notifications/{userCid}/notifications', // Existing
44
- 'old_notifications/{userId}/items' // NEW - Just add here!
45
- ]
46
- }
47
- ```
48
-
49
- **That's it!** The system automatically uses the first legacy path from the registry. No other changes needed!
50
-
51
- **How it works:**
52
- - `readWithMigration()` automatically passes `category` and `subcategory` to `getLegacyPath()`
53
- - `getLegacyPath()` first tries to get legacy paths from the registry
54
- - If found, it automatically resolves dynamic segments and returns the path
55
- - No need to update `path_resolution_helpers.js`!
56
-
57
- ---
58
-
59
- ### Alternative: Add to Legacy Path Map (For Complex Logic)
60
-
61
- **Only needed if:** You need conditional logic or special handling that can't be expressed in a simple path template.
62
-
63
- **File:** `Backend/Entrypoints/BullTrackers/Backend/Core/bulltrackers-module/functions/generic-api/user-api/helpers/core/path_resolution_helpers.js`
64
-
65
- **Location:** Inside `getLegacyPath()` function, add to `legacyPathMap` object
66
-
67
- **Example:**
68
- ```javascript
69
- function getLegacyPath(dataType, userCid, config = {}, params = {}) {
70
- // ... registry lookup happens first ...
71
-
72
- // Fallback to hardcoded map (only if registry doesn't have it)
73
- const legacyPathMap = {
74
- // ... existing mappings ...
75
-
76
- // NEW - Add your new data type here (only if you need complex logic)
77
- newDataType: params.someCondition
78
- ? `old_collection/${userId}/items/${params.someParam}`
79
- : `old_collection/${userId}/items`
80
- };
81
-
82
- return legacyPathMap[dataType] || null;
83
- }
84
- ```
85
-
86
- **Note:** This is only needed for complex conditional logic. For simple paths, just use the registry!
87
-
88
- ---
89
-
90
- ## Real-World Example
91
-
92
- Let's say you want to add support for a legacy "user preferences" collection:
93
-
94
- ### Step 1: Update Collection Registry
95
-
96
- ```javascript
97
- // In collection_registry.js
98
- signedInUsers: {
99
- // ... other collections ...
100
-
101
- preferences: {
102
- path: 'SignedInUsers/{cid}/preferences/data',
103
- description: 'User preferences (single document)',
104
- dynamicSegments: ['{cid}'],
105
- status: 'active',
106
- legacyPaths: [
107
- 'user_preferences/{userCid}', // Add this
108
- 'old_prefs/{userId}/settings' // And this if multiple legacy formats exist
109
- ]
110
- }
111
- }
112
- ```
113
-
114
- ### Step 2: (Optional) Update Path Resolution Helper
115
-
116
- **Only needed if:** You need conditional logic that can't be expressed in a simple path template.
117
-
118
- ```javascript
119
- // In path_resolution_helpers.js
120
- // This is only needed for complex conditional logic
121
- // The registry lookup happens first, so this is just a fallback
122
- ```
123
-
124
- ### Step 3: Use It in Your API
125
-
126
- ```javascript
127
- // In your API helper file
128
- const { readWithMigration } = require('./helpers/core/path_resolution_helpers');
129
-
130
- async function getUserPreferences(req, res, dependencies, config) {
131
- const { db, logger } = dependencies;
132
- const { userCid } = req.query;
133
-
134
- const result = await readWithMigration(
135
- db,
136
- 'signedInUsers', // category
137
- 'preferences', // subcategory
138
- { cid: userCid }, // params
139
- {
140
- isCollection: false, // It's a document
141
- dataType: 'preferences', // This triggers legacy path lookup
142
- config: config,
143
- logger: logger
144
- }
145
- );
146
-
147
- if (!result) {
148
- return res.status(404).json({ error: "Preferences not found" });
149
- }
150
-
151
- // result.data contains the preferences
152
- // result.source tells you if it came from 'new' or 'legacy'
153
- // result.migrated tells you if it was auto-migrated
154
-
155
- return res.status(200).json({
156
- preferences: result.data,
157
- source: result.source,
158
- migrated: result.migrated || false
159
- });
160
- }
161
- ```
162
-
163
- **That's it!** The auto-migration happens automatically.
164
-
165
- ---
166
-
167
- ## Advanced: Multiple Legacy Formats
168
-
169
- If you have multiple legacy formats for the same data type:
170
-
171
- ### Option 1: Try Multiple Legacy Paths (Recommended)
172
-
173
- Update `getLegacyPath()` to return an array or try multiple paths:
174
-
175
- ```javascript
176
- function getLegacyPath(dataType, userCid, config = {}, params = {}) {
177
- const cid = String(userCid);
178
-
179
- const legacyPathMap = {
180
- // ... existing ...
181
-
182
- preferences: [
183
- `user_preferences/${cid}`, // Try first
184
- `old_prefs/${cid}/settings`, // Try second
185
- `legacy_preferences/${cid}/data` // Try third
186
- ]
187
- };
188
-
189
- const path = legacyPathMap[dataType];
190
- return Array.isArray(path) ? path[0] : path; // Return first for now
191
- }
192
- ```
193
-
194
- Then update `readWithMigration()` to try all paths in the array (this would require a small code change).
195
-
196
- ### Option 2: Use Conditional Logic
197
-
198
- ```javascript
199
- const legacyPathMap = {
200
- preferences: params.useOldFormat
201
- ? `old_prefs/${userId}/settings`
202
- : `user_preferences/${cid}`
203
- };
204
- ```
205
-
206
- ---
207
-
208
- ## Dynamic Segment Resolution
209
-
210
- The system automatically resolves common dynamic segments:
211
-
212
- - `{cid}` → User CID
213
- - `{userCid}` → User CID
214
- - `{firebaseUid}` → Firebase UID (from params)
215
- - `{username}` → Username (from params)
216
- - `{date}` → Date (from params)
217
- - `{requestId}` → Request ID (from params or documentId)
218
- - `{piCid}` → PI CID (from params)
219
- - `{postId}` → Post ID (from params or documentId)
220
- - `{watchlistId}` → Watchlist ID (from params)
221
- - `{version}` → Version (from params)
222
- - `{viewId}` → View ID (from params or documentId)
223
- - `{reviewId}` → Review ID (from params or documentId)
224
- - `{timestamp}` → Timestamp (from params or auto-generated)
225
-
226
- **Just use these placeholders in your legacy path string!**
227
-
228
- ---
229
-
230
- ## Testing Your New Legacy Route
231
-
232
- 1. **Create test data in legacy path:**
233
- ```javascript
234
- await db.collection('user_preferences').doc('29312236').set({
235
- theme: 'dark',
236
- notifications: true
237
- });
238
- ```
239
-
240
- 2. **Call your API:**
241
- ```javascript
242
- GET /user/me/preferences?userCid=29312236
243
- ```
244
-
245
- 3. **Check the response:**
246
- ```json
247
- {
248
- "preferences": { "theme": "dark", "notifications": true },
249
- "source": "legacy",
250
- "migrated": true
251
- }
252
- ```
253
-
254
- 4. **Verify migration:**
255
- ```javascript
256
- const newDoc = await db.collection('SignedInUsers/29312236/preferences/data').get();
257
- // Should exist with _migratedAt and _migratedFrom fields
258
- ```
259
-
260
- ---
261
-
262
- ## Common Patterns
263
-
264
- ### Pattern 1: Simple CID-based Legacy Path
265
- ```javascript
266
- legacyPaths: ['old_collection/{userCid}']
267
- legacyPathMap: { newDataType: `old_collection/${cid}` }
268
- ```
269
-
270
- ### Pattern 2: Firebase UID-based Legacy Path
271
- ```javascript
272
- legacyPaths: ['old_collection/{firebaseUid}']
273
- legacyPathMap: {
274
- newDataType: firebaseUid
275
- ? `old_collection/${firebaseUid}`
276
- : `old_collection/${cid}`
277
- }
278
- ```
279
-
280
- ### Pattern 3: Nested Legacy Path
281
- ```javascript
282
- legacyPaths: ['old_collection/{userCid}/subcollection/{itemId}']
283
- legacyPathMap: {
284
- newDataType: `old_collection/${cid}/subcollection/${params.itemId || '{itemId}'}`
285
- }
286
- ```
287
-
288
- ### Pattern 4: Date-based Legacy Path
289
- ```javascript
290
- legacyPaths: ['old_collection/{date}/{userCid}']
291
- legacyPathMap: {
292
- newDataType: `old_collection/${params.date || '{date}'}/${cid}`
293
- }
294
- ```
295
-
296
- ---
297
-
298
- ## Troubleshooting
299
-
300
- ### Legacy Path Not Found?
301
-
302
- 1. **Check `dataType` parameter** - Must match key in `legacyPathMap`
303
- 2. **Check `params`** - Ensure all required dynamic segments are provided
304
- 3. **Check path resolution** - Use logger to see what path is being tried
305
-
306
- ### Migration Not Happening?
307
-
308
- 1. **Check if new path exists** - Migration only happens if new path is available
309
- 2. **Check logger** - Look for migration success/error messages
310
- 3. **Check permissions** - Ensure write permissions to new path
311
-
312
- ### Multiple Legacy Formats?
313
-
314
- 1. **Add all to `legacyPaths` array** in registry
315
- 2. **Use conditional logic** in `getLegacyPath()` to choose which to try first
316
- 3. **Or modify `readWithMigration()`** to try multiple legacy paths sequentially
317
-
318
- ---
319
-
320
- ## Summary
321
-
322
- **Adding a new legacy route is as simple as:**
323
-
324
- ### ✅ EASIEST (Recommended):
325
- 1. ✅ Add one line to `legacyPaths` array in `collection_registry.js`
326
- 2. ✅ Use `readWithMigration()` in your API code (pass `category` and `subcategory`)
327
-
328
- **Total time: ~30 seconds per legacy route!**
329
-
330
- ### Alternative (For Complex Logic):
331
- 1. ✅ Add one line to `legacyPaths` array in `collection_registry.js` (optional, for documentation)
332
- 2. ✅ Add one line to `legacyPathMap` in `path_resolution_helpers.js` (if you need conditional logic)
333
- 3. ✅ Use `readWithMigration()` in your API code
334
-
335
- **Total time: ~2 minutes per legacy route!**
336
-
337
- The system handles:
338
- - ✅ Path resolution
339
- - ✅ Fallback logic
340
- - ✅ Auto-migration
341
- - ✅ Error handling
342
- - ✅ Logging
343
-
344
- You just need to define the paths! 🎉
345
-