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.
- package/functions/alert-system/helpers/alert_helpers.js +6 -6
- package/functions/alert-system/index.js +1 -1
- package/functions/api-v2/helpers/data-fetchers/firestore.js +2218 -0
- package/functions/api-v2/helpers/task_engine_helper.js +51 -0
- package/functions/api-v2/index.js +36 -0
- package/functions/api-v2/middleware/identity_middleware.js +48 -0
- package/functions/api-v2/package.json +6 -0
- package/functions/api-v2/routes/alerts.js +168 -0
- package/functions/api-v2/routes/index.js +35 -0
- package/functions/api-v2/routes/notifications.js +38 -0
- package/functions/api-v2/routes/popular_investors.js +204 -0
- package/functions/api-v2/routes/profile.js +212 -0
- package/functions/api-v2/routes/reviews.js +72 -0
- package/functions/api-v2/routes/settings.js +71 -0
- package/functions/api-v2/routes/sync.js +132 -0
- package/functions/api-v2/routes/verification.js +47 -0
- package/functions/api-v2/routes/watchlists.js +148 -0
- package/functions/computation-system/helpers/computation_worker.js +1 -1
- package/functions/task-engine/helpers/popular_investor_helpers.js +2 -2
- package/index.js +6 -2
- package/package.json +3 -2
- package/functions/generic-api/user-api/ADDING_LEGACY_ROUTES_GUIDE.md +0 -345
- package/functions/generic-api/user-api/CODE_REORGANIZATION_PLAN.md +0 -320
- package/functions/generic-api/user-api/COMPLETE_REFACTORING_PLAN.md +0 -116
- package/functions/generic-api/user-api/FIRESTORE_PATHS_INVENTORY.md +0 -171
- package/functions/generic-api/user-api/FIRESTORE_PATH_MIGRATION_REFERENCE.md +0 -710
- package/functions/generic-api/user-api/FIRESTORE_PATH_VALIDATION.md +0 -109
- package/functions/generic-api/user-api/MIGRATION_PLAN.md +0 -499
- package/functions/generic-api/user-api/README_MIGRATION.md +0 -152
- package/functions/generic-api/user-api/REFACTORING_COMPLETE.md +0 -106
- package/functions/generic-api/user-api/REFACTORING_STATUS.md +0 -85
- package/functions/generic-api/user-api/VERIFICATION_MIGRATION_NOTES.md +0 -206
- package/functions/generic-api/user-api/helpers/ORGANIZATION_COMPLETE.md +0 -126
- /package/functions/{generic-api → old-generic-api}/admin-api/index.js +0 -0
- /package/functions/{generic-api → old-generic-api}/helpers/api_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/index.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/alerts/alert_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/alerts/subscription_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/alerts/test_alert_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/collection_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/core/compression_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/core/data_lookup_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/core/path_resolution_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/core/user_status_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/data/computation_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/data/instrument_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/data/portfolio_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/data/social_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/data_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/dev/dev_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/fetch/on_demand_fetch_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/metrics/personalized_metrics_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/notifications/notification_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/profile/pi_profile_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/profile/profile_view_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/profile/user_profile_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/recommendations/recommendation_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/reviews/review_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/rootdata/rootdata_aggregation_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/search/pi_request_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/search/pi_search_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/sync/user_sync_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/verification/verification_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/watchlist/watchlist_analytics_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/watchlist/watchlist_data_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/watchlist/watchlist_generation_helpers.js +0 -0
- /package/functions/{generic-api → old-generic-api}/user-api/helpers/watchlist/watchlist_management_helpers.js +0 -0
- /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.
|
|
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
|
-
|