bulltrackers-module 1.0.423 → 1.0.424

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.
@@ -567,20 +567,30 @@ async function getUserPortfolio(req, res, dependencies, config) {
567
567
  }
568
568
 
569
569
  try {
570
+ // Check for dev override impersonation
571
+ const { getEffectiveCid, getDevOverride } = require('./dev_helpers');
572
+ const effectiveCid = await getEffectiveCid(db, userCid, config, logger);
573
+ const devOverride = await getDevOverride(db, userCid, config, logger);
574
+ const isImpersonating = devOverride && devOverride.impersonateCid && effectiveCid !== Number(userCid);
575
+
570
576
  const { signedInUsersCollection } = config;
571
577
  const CANARY_BLOCK_ID = '19M';
572
578
  const today = new Date().toISOString().split('T')[0];
573
579
 
574
- // Try to find latest available date (starts with today, falls back if needed)
575
- const dataDate = await findLatestPortfolioDate(db, signedInUsersCollection, userCid, 30);
580
+ // Use effective CID for portfolio lookup
581
+ const dataDate = await findLatestPortfolioDate(db, signedInUsersCollection, effectiveCid, 30);
576
582
 
577
583
  if (!dataDate) {
578
- return res.status(404).json({ error: "Portfolio data not found for this user (checked last 30 days)" });
584
+ return res.status(404).json({
585
+ error: "Portfolio data not found for this user (checked last 30 days)",
586
+ effectiveCid: effectiveCid,
587
+ isImpersonating: isImpersonating || false
588
+ });
579
589
  }
580
590
 
581
591
  const isFallback = dataDate !== today;
582
592
  if (isFallback) {
583
- logger.log('INFO', `[getUserPortfolio] Using fallback date ${dataDate} for user ${userCid} (today: ${today})`);
593
+ logger.log('INFO', `[getUserPortfolio] Using fallback date ${dataDate} for effective CID ${effectiveCid} (today: ${today})`);
584
594
  }
585
595
 
586
596
  // Fetch portfolio from signed_in_users/19M/snapshots/{date}/parts/part_X
@@ -594,11 +604,11 @@ async function getUserPortfolio(req, res, dependencies, config) {
594
604
 
595
605
  let portfolioData = null;
596
606
 
597
- // Search through all parts to find the user's portfolio
607
+ // Search through all parts to find the user's portfolio (use effective CID)
598
608
  for (const partDoc of partsSnapshot.docs) {
599
609
  const partData = partDoc.data();
600
- if (partData && partData[String(userCid)]) {
601
- portfolioData = partData[String(userCid)];
610
+ if (partData && partData[String(effectiveCid)]) {
611
+ portfolioData = partData[String(effectiveCid)];
602
612
  break;
603
613
  }
604
614
  }
@@ -773,6 +783,12 @@ async function getUserComputations(req, res, dependencies, config) {
773
783
  }
774
784
 
775
785
  try {
786
+ // Check for dev override impersonation
787
+ const { getEffectiveCid, getDevOverride } = require('./dev_helpers');
788
+ const effectiveCid = await getEffectiveCid(db, userCid, config, logger);
789
+ const devOverride = await getDevOverride(db, userCid, config, logger);
790
+ const isImpersonating = devOverride && devOverride.impersonateCid && effectiveCid !== Number(userCid);
791
+
776
792
  const insightsCollection = config.unifiedInsightsCollection || 'unified_insights';
777
793
  const resultsSub = config.resultsSubcollection || 'results';
778
794
  const compsSub = config.computationsSubcollection || 'computations';
@@ -789,14 +805,13 @@ async function getUserComputations(req, res, dependencies, config) {
789
805
  return res.status(400).json({ error: "Please specify at least one computation name" });
790
806
  }
791
807
 
792
- // Check for dev override (for developer accounts)
793
- const { getDevOverride } = require('./dev_helpers');
794
- const devOverride = await getDevOverride(db, userCid, config, logger);
808
+ // Check for dev override (for developer accounts) - use actual userCid for override check
795
809
  const isDevOverrideActive = devOverride && devOverride.enabled && devOverride.fakeCopiedPIs.length > 0;
796
810
 
797
811
  let datesToCheck = [today];
798
812
 
799
813
  // If mode is 'latest', try to find the latest available date for the first computation
814
+ // Use effectiveCid for computation lookup
800
815
  if (mode === 'latest') {
801
816
  const firstCompName = computationNames[0];
802
817
  const latestDate = await findLatestComputationDate(
@@ -806,25 +821,27 @@ async function getUserComputations(req, res, dependencies, config) {
806
821
  compsSub,
807
822
  category,
808
823
  firstCompName,
809
- userCid,
824
+ effectiveCid,
810
825
  30
811
826
  );
812
827
 
813
828
  if (latestDate) {
814
829
  datesToCheck = [latestDate];
815
830
  if (latestDate !== today) {
816
- logger.log('INFO', `[getUserComputations] Using fallback date ${latestDate} for user ${userCid} (today: ${today})`);
831
+ logger.log('INFO', `[getUserComputations] Using fallback date ${latestDate} for effective CID ${effectiveCid} (today: ${today})`);
817
832
  }
818
833
  } else {
819
834
  // No data found, return empty
820
835
  return res.status(200).json({
821
836
  status: 'success',
822
- userCid: String(userCid),
837
+ userCid: String(effectiveCid),
823
838
  mode,
824
839
  computations: computationNames,
825
840
  data: {},
826
841
  isFallback: false,
827
- requestedDate: today
842
+ requestedDate: today,
843
+ isImpersonating: isImpersonating || false,
844
+ actualCid: Number(userCid)
828
845
  });
829
846
  }
830
847
  } else if (mode === 'series') {
@@ -861,9 +878,10 @@ async function getUserComputations(req, res, dependencies, config) {
861
878
  const rawData = doc.data();
862
879
  const data = tryDecompress(rawData);
863
880
  // Filter by user CID - computation results are stored as { cid: result }
864
- let userResult = data[String(userCid)];
881
+ // Use effectiveCid for lookup
882
+ let userResult = data[String(effectiveCid)];
865
883
 
866
- // Apply dev override for computations that include copied PIs
884
+ // Apply dev override for computations that include copied PIs (use actual userCid for override check)
867
885
  if (isDevOverrideActive && (compName === 'SignedInUserProfileMetrics' || compName === 'SignedInUserCopiedPIs')) {
868
886
  if (compName === 'SignedInUserCopiedPIs') {
869
887
  // Override the copied PIs list
@@ -923,13 +941,15 @@ async function getUserComputations(req, res, dependencies, config) {
923
941
 
924
942
  return res.status(200).json({
925
943
  status: 'success',
926
- userCid: String(userCid),
944
+ userCid: String(effectiveCid),
927
945
  mode,
928
946
  computations: computationNames,
929
947
  data: cleanedResults,
930
948
  isFallback: isFallback,
931
949
  requestedDate: today,
932
- devOverrideActive: isDevOverrideActive
950
+ devOverrideActive: isDevOverrideActive,
951
+ isImpersonating: isImpersonating || false,
952
+ actualCid: Number(userCid)
933
953
  });
934
954
 
935
955
  } catch (error) {
@@ -1001,7 +1021,8 @@ async function autoGenerateWatchlist(req, res, dependencies, config) {
1001
1021
 
1002
1022
  if (computationDoc.exists) {
1003
1023
  const computationData = computationDoc.data();
1004
- const userResult = computationData[String(userCid)];
1024
+ // Use effectiveCid for lookup
1025
+ const userResult = computationData[String(effectiveCid)];
1005
1026
 
1006
1027
  if (userResult && userResult.current && userResult.current.length > 0) {
1007
1028
  // Convert computation result to our format
@@ -1742,6 +1763,7 @@ async function getPiProfile(req, res, dependencies, config) {
1742
1763
  /**
1743
1764
  * GET /user/me/is-popular-investor
1744
1765
  * Check if signed-in user is also a Popular Investor
1766
+ * Supports dev override impersonation
1745
1767
  */
1746
1768
  async function checkIfUserIsPopularInvestor(req, res, dependencies, config) {
1747
1769
  const { db, logger } = dependencies;
@@ -1752,18 +1774,25 @@ async function checkIfUserIsPopularInvestor(req, res, dependencies, config) {
1752
1774
  }
1753
1775
 
1754
1776
  try {
1755
- const rankEntry = await checkIfUserIsPI(db, userCid, config, logger);
1777
+ // Check for dev override impersonation
1778
+ const { getEffectiveCid, getDevOverride } = require('./dev_helpers');
1779
+ const effectiveCid = await getEffectiveCid(db, userCid, config, logger);
1780
+ const devOverride = await getDevOverride(db, userCid, config, logger);
1781
+ const isImpersonating = devOverride && devOverride.impersonateCid && effectiveCid !== Number(userCid);
1782
+
1783
+ // Use effective CID (impersonated or actual) to check PI status
1784
+ const rankEntry = await checkIfUserIsPI(db, effectiveCid, config, logger);
1756
1785
 
1757
1786
  if (!rankEntry) {
1758
1787
  return res.status(200).json({
1759
1788
  isPopularInvestor: false,
1760
- rankingData: null
1789
+ rankingData: null,
1790
+ isImpersonating: isImpersonating || false,
1791
+ effectiveCid: effectiveCid
1761
1792
  });
1762
1793
  }
1763
1794
 
1764
- // Check if this is a dev override
1765
- const { getDevOverride } = require('./dev_helpers');
1766
- const devOverride = await getDevOverride(db, userCid, config, logger);
1795
+ // Check if this is a dev override (pretendToBePI)
1767
1796
  const isDevOverride = devOverride && devOverride.pretendToBePI;
1768
1797
 
1769
1798
  // Return ranking data
@@ -1779,7 +1808,10 @@ async function checkIfUserIsPopularInvestor(req, res, dependencies, config) {
1779
1808
  winRatio: rankEntry.WinRatio || 0,
1780
1809
  trades: rankEntry.Trades || 0
1781
1810
  },
1782
- isDevOverride: isDevOverride || false
1811
+ isDevOverride: isDevOverride || false,
1812
+ isImpersonating: isImpersonating || false,
1813
+ effectiveCid: effectiveCid,
1814
+ actualCid: Number(userCid)
1783
1815
  });
1784
1816
 
1785
1817
  } catch (error) {
@@ -2084,34 +2116,42 @@ async function getSignedInUserPIPersonalizedMetrics(req, res, dependencies, conf
2084
2116
  }
2085
2117
 
2086
2118
  try {
2087
- // First, verify user is a PI (checks dev override)
2088
- const rankEntry = await checkIfUserIsPI(db, userCid, config, logger);
2119
+ // Check for dev override impersonation
2120
+ const { getEffectiveCid, getDevOverride } = require('./dev_helpers');
2121
+ const effectiveCid = await getEffectiveCid(db, userCid, config, logger);
2122
+ const devOverride = await getDevOverride(db, userCid, config, logger);
2123
+ const isImpersonating = devOverride && devOverride.impersonateCid && effectiveCid !== Number(userCid);
2124
+
2125
+ // Use effective CID (impersonated or actual) to check PI status
2126
+ const rankEntry = await checkIfUserIsPI(db, effectiveCid, config, logger);
2089
2127
  if (!rankEntry) {
2090
2128
  return res.status(404).json({
2091
2129
  error: "Not a Popular Investor",
2092
- message: "This endpoint is only available for users who are Popular Investors"
2130
+ message: "This endpoint is only available for users who are Popular Investors",
2131
+ effectiveCid: effectiveCid,
2132
+ isImpersonating: isImpersonating || false
2093
2133
  });
2094
2134
  }
2095
2135
 
2096
- // Check if this is a dev override
2097
- const { getDevOverride } = require('./dev_helpers');
2098
- const devOverride = await getDevOverride(db, userCid, config, logger);
2136
+ // Check if this is a dev override (pretendToBePI)
2099
2137
  const isDevOverride = devOverride && devOverride.pretendToBePI;
2100
2138
 
2101
- // If dev override, generate sample data
2139
+ // If dev override (pretendToBePI), generate sample data
2102
2140
  if (isDevOverride) {
2103
- logger.log('INFO', `[getSignedInUserPIPersonalizedMetrics] DEV OVERRIDE: Generating sample PI metrics for user ${userCid}`);
2104
- const sampleData = generateSamplePIPersonalizedMetrics(userCid, rankEntry);
2141
+ logger.log('INFO', `[getSignedInUserPIPersonalizedMetrics] DEV OVERRIDE: Generating sample PI metrics for effective CID ${effectiveCid}`);
2142
+ const sampleData = generateSamplePIPersonalizedMetrics(effectiveCid, rankEntry);
2105
2143
  const today = new Date().toISOString().split('T')[0];
2106
2144
 
2107
2145
  return res.status(200).json({
2108
2146
  status: 'success',
2109
- userCid: String(userCid),
2147
+ userCid: String(effectiveCid),
2110
2148
  data: sampleData,
2111
2149
  dataDate: today,
2112
2150
  requestedDate: today,
2113
2151
  isFallback: false,
2114
- isDevOverride: true
2152
+ isDevOverride: true,
2153
+ isImpersonating: isImpersonating || false,
2154
+ actualCid: Number(userCid)
2115
2155
  });
2116
2156
  }
2117
2157
 
@@ -2123,6 +2163,7 @@ async function getSignedInUserPIPersonalizedMetrics(req, res, dependencies, conf
2123
2163
  const today = new Date().toISOString().split('T')[0];
2124
2164
 
2125
2165
  // Try to find computation with user-specific fallback logic
2166
+ // Use effectiveCid (impersonated or actual) for computation lookup
2126
2167
  let foundDate = null;
2127
2168
  let metricsData = null;
2128
2169
  let checkedDates = [];
@@ -2146,11 +2187,14 @@ async function getSignedInUserPIPersonalizedMetrics(req, res, dependencies, conf
2146
2187
  status: 'fallback',
2147
2188
  message: 'Computation not available, use frontend fallback',
2148
2189
  data: null,
2149
- useFrontendFallback: true
2190
+ useFrontendFallback: true,
2191
+ effectiveCid: effectiveCid,
2192
+ isImpersonating: isImpersonating || false
2150
2193
  });
2151
2194
  }
2152
2195
 
2153
2196
  // Step 2: Check if user exists in latest computation, if not, look back 7 days
2197
+ // Use effectiveCid for lookup
2154
2198
  const latestDateObj = new Date(latestComputationDate + 'T00:00:00Z');
2155
2199
 
2156
2200
  for (let daysBack = 0; daysBack <= 7; daysBack++) {
@@ -2180,13 +2224,13 @@ async function getSignedInUserPIPersonalizedMetrics(req, res, dependencies, conf
2180
2224
  }
2181
2225
  }
2182
2226
 
2183
- // Check if user exists in this computation
2227
+ // Check if user exists in this computation (use effectiveCid)
2184
2228
  if (computationData && typeof computationData === 'object' && !Array.isArray(computationData)) {
2185
- const userData = computationData[String(userCid)];
2229
+ const userData = computationData[String(effectiveCid)];
2186
2230
  if (userData) {
2187
2231
  foundDate = dateStr;
2188
2232
  metricsData = userData;
2189
- logger.log('INFO', `[getSignedInUserPIPersonalizedMetrics] Found user ${userCid} in computation date ${dateStr}`);
2233
+ logger.log('INFO', `[getSignedInUserPIPersonalizedMetrics] Found effective CID ${effectiveCid} in computation date ${dateStr}`);
2190
2234
  break;
2191
2235
  }
2192
2236
  }
@@ -2195,23 +2239,26 @@ async function getSignedInUserPIPersonalizedMetrics(req, res, dependencies, conf
2195
2239
 
2196
2240
  // Step 3: If user not found in any computation, return fallback flag
2197
2241
  if (!foundDate || !metricsData) {
2198
- logger.log('INFO', `[getSignedInUserPIPersonalizedMetrics] User ${userCid} not found in any computation, will use frontend fallback`);
2242
+ logger.log('INFO', `[getSignedInUserPIPersonalizedMetrics] Effective CID ${effectiveCid} not found in any computation, will use frontend fallback`);
2199
2243
  return res.status(200).json({
2200
2244
  status: 'fallback',
2201
2245
  message: 'User not found in computation, use frontend fallback',
2202
2246
  data: null,
2203
2247
  useFrontendFallback: true,
2204
- checkedDates: checkedDates
2248
+ checkedDates: checkedDates,
2249
+ effectiveCid: effectiveCid,
2250
+ isImpersonating: isImpersonating || false
2205
2251
  });
2206
2252
  }
2207
2253
 
2208
2254
  // Step 4: Enhance with review metrics and page views from Firestore
2209
2255
  // These require cross-collection queries that aren't in computation
2256
+ // Use effectiveCid for queries
2210
2257
 
2211
2258
  // Fetch review metrics over time
2212
2259
  const reviewsCollection = config.reviewsCollection || 'pi_reviews';
2213
2260
  const reviewsSnapshot = await db.collection(reviewsCollection)
2214
- .where('piCid', '==', Number(userCid))
2261
+ .where('piCid', '==', Number(effectiveCid))
2215
2262
  .orderBy('createdAt', 'desc')
2216
2263
  .limit(1000) // Get enough for time series
2217
2264
  .get();
@@ -2258,8 +2305,9 @@ async function getSignedInUserPIPersonalizedMetrics(req, res, dependencies, conf
2258
2305
  // Fetch profile views over time
2259
2306
  const profileViewsCollection = config.profileViewsCollection || 'profile_views';
2260
2307
  // Query without orderBy first, then sort in memory (to avoid index requirement)
2308
+ // Use effectiveCid for queries
2261
2309
  const viewsSnapshot = await db.collection(profileViewsCollection)
2262
- .where('piCid', '==', Number(userCid))
2310
+ .where('piCid', '==', Number(effectiveCid))
2263
2311
  .limit(90) // Last 90 days worth of documents
2264
2312
  .get();
2265
2313
 
@@ -2324,16 +2372,18 @@ async function getSignedInUserPIPersonalizedMetrics(req, res, dependencies, conf
2324
2372
  }
2325
2373
  };
2326
2374
 
2327
- logger.log('SUCCESS', `[getSignedInUserPIPersonalizedMetrics] Returning personalized metrics for user ${userCid} from date ${foundDate}`);
2375
+ logger.log('SUCCESS', `[getSignedInUserPIPersonalizedMetrics] Returning personalized metrics for effective CID ${effectiveCid} from date ${foundDate}`);
2328
2376
 
2329
2377
  return res.status(200).json({
2330
2378
  status: 'success',
2331
- userCid: String(userCid),
2379
+ userCid: String(effectiveCid),
2332
2380
  data: metricsData,
2333
2381
  dataDate: foundDate,
2334
2382
  requestedDate: today,
2335
2383
  isFallback: foundDate !== today,
2336
- daysBackFromLatest: checkedDates.indexOf(foundDate)
2384
+ daysBackFromLatest: checkedDates.indexOf(foundDate),
2385
+ isImpersonating: isImpersonating || false,
2386
+ actualCid: Number(userCid)
2337
2387
  });
2338
2388
 
2339
2389
  } catch (error) {
@@ -40,6 +40,7 @@ async function getDevOverride(db, userCid, config, logger = null) {
40
40
  enabled: false,
41
41
  fakeCopiedPIs: [],
42
42
  pretendToBePI: false,
43
+ impersonateCid: null, // CID to impersonate/view as
43
44
  createdAt: FieldValue.serverTimestamp(),
44
45
  lastUpdated: FieldValue.serverTimestamp()
45
46
  };
@@ -58,6 +59,7 @@ async function getDevOverride(db, userCid, config, logger = null) {
58
59
  enabled: false,
59
60
  fakeCopiedPIs: [],
60
61
  pretendToBePI: false,
62
+ impersonateCid: null,
61
63
  lastUpdated: null,
62
64
  wasAutoCreated: true
63
65
  };
@@ -70,6 +72,7 @@ async function getDevOverride(db, userCid, config, logger = null) {
70
72
  enabled: data.enabled === true,
71
73
  fakeCopiedPIs: data.fakeCopiedPIs || [],
72
74
  pretendToBePI: data.pretendToBePI === true,
75
+ impersonateCid: data.impersonateCid ? Number(data.impersonateCid) : null,
73
76
  lastUpdated: data.lastUpdated,
74
77
  wasAutoCreated: false
75
78
  };
@@ -154,7 +157,7 @@ async function hasUserCopiedWithDevOverride(db, userCid, piCid, config, logger)
154
157
  */
155
158
  async function setDevOverride(req, res, dependencies, config) {
156
159
  const { db, logger } = dependencies;
157
- const { userCid, enabled, fakeCopiedPIs, pretendToBePI } = req.body;
160
+ const { userCid, enabled, fakeCopiedPIs, pretendToBePI, impersonateCid } = req.body;
158
161
 
159
162
  if (!userCid) {
160
163
  return res.status(400).json({ error: "Missing userCid" });
@@ -177,6 +180,17 @@ async function setDevOverride(req, res, dependencies, config) {
177
180
  });
178
181
  }
179
182
 
183
+ // Validate impersonateCid if provided
184
+ if (impersonateCid !== undefined && impersonateCid !== null) {
185
+ const parsedCid = Number(impersonateCid);
186
+ if (isNaN(parsedCid) || parsedCid <= 0) {
187
+ return res.status(400).json({
188
+ error: "Invalid request",
189
+ message: "impersonateCid must be a positive number, or null to disable impersonation"
190
+ });
191
+ }
192
+ }
193
+
180
194
  // Ensure all CIDs are numbers
181
195
  const validatedPIs = enabled ? fakeCopiedPIs.map(cid => Number(cid)).filter(cid => !isNaN(cid) && cid > 0) : [];
182
196
 
@@ -193,12 +207,19 @@ async function setDevOverride(req, res, dependencies, config) {
193
207
  enabled: enabled !== undefined ? (enabled === true) : (existingData.enabled || false),
194
208
  fakeCopiedPIs: enabled !== undefined ? validatedPIs : (existingData.fakeCopiedPIs || []),
195
209
  pretendToBePI: pretendToBePI !== undefined ? (pretendToBePI === true) : (existingData.pretendToBePI || false),
210
+ impersonateCid: impersonateCid !== undefined ? (impersonateCid ? Number(impersonateCid) : null) : (existingData.impersonateCid || null),
196
211
  lastUpdated: FieldValue.serverTimestamp()
197
212
  };
198
213
 
199
214
  await overrideRef.set(overrideData, { merge: true });
200
215
 
201
- logger.log('SUCCESS', `[setDevOverride] Updated dev override for user ${userCid}: enabled=${overrideData.enabled}, pretendToBePI=${overrideData.pretendToBePI}, ${validatedPIs.length} fake PIs`);
216
+ const logParts = [
217
+ `enabled=${overrideData.enabled}`,
218
+ `pretendToBePI=${overrideData.pretendToBePI}`,
219
+ `impersonateCid=${overrideData.impersonateCid || 'null'}`,
220
+ `${validatedPIs.length} fake PIs`
221
+ ];
222
+ logger.log('SUCCESS', `[setDevOverride] Updated dev override for user ${userCid}: ${logParts.join(', ')}`);
202
223
 
203
224
  return res.status(200).json({
204
225
  success: true,
@@ -248,6 +269,7 @@ async function getDevOverrideStatus(req, res, dependencies, config) {
248
269
  enabled: devOverride.enabled,
249
270
  fakeCopiedPIs: devOverride.fakeCopiedPIs,
250
271
  pretendToBePI: devOverride.pretendToBePI || false,
272
+ impersonateCid: devOverride.impersonateCid || null,
251
273
  lastUpdated: devOverride.lastUpdated,
252
274
  wasAutoCreated: devOverride.wasAutoCreated || false
253
275
  });
@@ -258,12 +280,36 @@ async function getDevOverrideStatus(req, res, dependencies, config) {
258
280
  }
259
281
  }
260
282
 
283
+ /**
284
+ * Get the effective CID to use for a developer account
285
+ * Returns impersonateCid if set, otherwise returns the actual userCid
286
+ * Only works for developer accounts
287
+ */
288
+ async function getEffectiveCid(db, userCid, config, logger = null) {
289
+ if (!isDeveloperAccount(userCid)) {
290
+ return Number(userCid); // Not a developer, return actual CID
291
+ }
292
+
293
+ const devOverride = await getDevOverride(db, userCid, config, logger);
294
+ if (devOverride && devOverride.impersonateCid) {
295
+ if (logger && logger.log) {
296
+ logger.log('INFO', `[getEffectiveCid] DEV OVERRIDE: User ${userCid} impersonating CID ${devOverride.impersonateCid}`);
297
+ } else {
298
+ console.log(`[getEffectiveCid] DEV OVERRIDE: User ${userCid} impersonating CID ${devOverride.impersonateCid}`);
299
+ }
300
+ return Number(devOverride.impersonateCid);
301
+ }
302
+
303
+ return Number(userCid);
304
+ }
305
+
261
306
  module.exports = {
262
307
  isDeveloperAccount,
263
308
  getDevOverride,
264
309
  getCopiedPIsWithDevOverride,
265
310
  hasUserCopiedWithDevOverride,
266
311
  setDevOverride,
267
- getDevOverrideStatus
312
+ getDevOverrideStatus,
313
+ getEffectiveCid
268
314
  };
269
315
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.423",
3
+ "version": "1.0.424",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [