bulltrackers-module 1.0.605 → 1.0.607
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.
|
@@ -1846,7 +1846,84 @@ const getSyncStatus = async (db, targetId) => {
|
|
|
1846
1846
|
const isProcessingState = processingStates.includes(currentStatus);
|
|
1847
1847
|
|
|
1848
1848
|
if (isProcessingState) {
|
|
1849
|
-
//
|
|
1849
|
+
// First, check if computation results exist (computation may have completed but status wasn't updated)
|
|
1850
|
+
// This is especially important for "computing" status
|
|
1851
|
+
if (currentStatus === 'computing' || currentStatus === 'indexing') {
|
|
1852
|
+
try {
|
|
1853
|
+
const today = new Date().toISOString().split('T')[0];
|
|
1854
|
+
const userType = data.userType || 'SIGNED_IN_USER';
|
|
1855
|
+
|
|
1856
|
+
// Determine which computation to check based on user type
|
|
1857
|
+
let computationNames = [];
|
|
1858
|
+
if (userType === 'POPULAR_INVESTOR') {
|
|
1859
|
+
computationNames = ['PopularInvestorProfileMetrics'];
|
|
1860
|
+
// Check if also a signed-in user
|
|
1861
|
+
try {
|
|
1862
|
+
await isSignedInUser(db, targetId);
|
|
1863
|
+
computationNames.push('SignedInUserPIPersonalizedMetrics');
|
|
1864
|
+
} catch (e) {
|
|
1865
|
+
// Not a signed-in user
|
|
1866
|
+
}
|
|
1867
|
+
} else {
|
|
1868
|
+
computationNames = ['SignedInUserProfileMetrics'];
|
|
1869
|
+
// Check if also a PI
|
|
1870
|
+
try {
|
|
1871
|
+
await fetchPopularInvestorMasterList(db, String(targetId));
|
|
1872
|
+
computationNames.push('SignedInUserPIPersonalizedMetrics', 'PopularInvestorProfileMetrics');
|
|
1873
|
+
} catch (e) {
|
|
1874
|
+
// Not a PI
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
// Check if any computation results exist for today
|
|
1879
|
+
let computationFound = false;
|
|
1880
|
+
for (const compName of computationNames) {
|
|
1881
|
+
try {
|
|
1882
|
+
const pageRef = db.collection('unified_insights')
|
|
1883
|
+
.doc(today)
|
|
1884
|
+
.collection('results')
|
|
1885
|
+
.doc('popular-investor')
|
|
1886
|
+
.collection('computations')
|
|
1887
|
+
.doc(compName)
|
|
1888
|
+
.collection('pages')
|
|
1889
|
+
.doc(String(targetId));
|
|
1890
|
+
|
|
1891
|
+
const pageSnap = await pageRef.get();
|
|
1892
|
+
if (pageSnap.exists) {
|
|
1893
|
+
computationFound = true;
|
|
1894
|
+
break;
|
|
1895
|
+
}
|
|
1896
|
+
} catch (error) {
|
|
1897
|
+
// Continue checking other computations
|
|
1898
|
+
console.error(`Error checking computation ${compName} for ${today}:`, error);
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
// If computation results exist, mark as completed
|
|
1903
|
+
if (computationFound) {
|
|
1904
|
+
await doc.ref.update({
|
|
1905
|
+
status: 'completed',
|
|
1906
|
+
completedAt: new Date(),
|
|
1907
|
+
updatedAt: new Date()
|
|
1908
|
+
});
|
|
1909
|
+
|
|
1910
|
+
return {
|
|
1911
|
+
requestId: requestId,
|
|
1912
|
+
status: 'completed',
|
|
1913
|
+
type: data.userType,
|
|
1914
|
+
createdAt: data.createdAt ? (data.createdAt.toDate ? data.createdAt.toDate().toISOString() : (data.createdAt.toISOString ? data.createdAt.toISOString() : data.createdAt)) : null,
|
|
1915
|
+
updatedAt: new Date().toISOString(),
|
|
1916
|
+
completedAt: new Date().toISOString(),
|
|
1917
|
+
canRequest: true
|
|
1918
|
+
};
|
|
1919
|
+
}
|
|
1920
|
+
} catch (error) {
|
|
1921
|
+
// If error checking computation results, continue with timeout check
|
|
1922
|
+
console.error(`[getSyncStatus] Error checking computation results:`, error);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
// Check age of request for timeout
|
|
1850
1927
|
const createdAt = data.createdAt;
|
|
1851
1928
|
const updatedAt = data.updatedAt;
|
|
1852
1929
|
|
|
@@ -20,10 +20,12 @@ const PUBLIC_ROUTES = [
|
|
|
20
20
|
'/popular-investors/categories',
|
|
21
21
|
'/popular-investors/master-list',
|
|
22
22
|
'/popular-investors/search',
|
|
23
|
+
'/popular-investors/profile', // Public PI profiles - userCid optional for personalization
|
|
23
24
|
'/verification/lookup', // Uses Firebase Auth token instead of userCid
|
|
24
25
|
'/alerts/types', // Static data - doesn't need userCid
|
|
25
26
|
'/alerts/dynamic-watchlist-computations', // Static data - doesn't need userCid
|
|
26
|
-
'/popular-investors/track-view' // Optional userCid - can track views anonymously
|
|
27
|
+
'/popular-investors/track-view', // Optional userCid - can track views anonymously
|
|
28
|
+
'/reviews' // Public reviews - userCid optional (for showing current user's review)
|
|
27
29
|
];
|
|
28
30
|
|
|
29
31
|
const isPublicRoute = (path, originalUrl) => {
|
|
@@ -36,10 +38,21 @@ const isPublicRoute = (path, originalUrl) => {
|
|
|
36
38
|
if (fullPath === route || fullPath.includes(route)) {
|
|
37
39
|
return true;
|
|
38
40
|
}
|
|
39
|
-
// Pattern match for routes with parameters
|
|
41
|
+
// Pattern match for routes with parameters
|
|
42
|
+
// /popular-investors/:piId/profile or /popular-investors/:piId/track-view
|
|
43
|
+
if (route.includes('/profile') && fullPath.includes('/profile')) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
40
46
|
if (route.includes('/track-view') && fullPath.includes('/track-view')) {
|
|
41
47
|
return true;
|
|
42
48
|
}
|
|
49
|
+
// /reviews/:piId (but not /reviews/me or /reviews/:piId/eligibility)
|
|
50
|
+
if (route === '/reviews' && fullPath.startsWith('/reviews/')) {
|
|
51
|
+
// Exclude /reviews/me (requires auth) and /reviews/:piId/eligibility (requires auth)
|
|
52
|
+
if (!fullPath.startsWith('/reviews/me') && !fullPath.includes('/eligibility')) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
return false;
|