diff --git a/src/lib/integrationTests/suites/performanceTests.ts b/src/lib/integrationTests/suites/performanceTests.ts index 948faea6..284d6ed8 100644 --- a/src/lib/integrationTests/suites/performanceTests.ts +++ b/src/lib/integrationTests/suites/performanceTests.ts @@ -56,7 +56,7 @@ export const performanceTestSuite: TestSuite = { // Set performance thresholds (in milliseconds) const threshold = 1000; // 1 second - const warnings = []; + const warnings: string[] = []; if (parksDuration > threshold) { warnings.push(`Parks query slow: ${parksDuration}ms`); @@ -229,7 +229,7 @@ export const performanceTestSuite: TestSuite = { // Performance threshold: 200ms for simple functions const threshold = 200; - const warnings = []; + const warnings: string[] = []; if (modDuration > threshold) { warnings.push(`is_moderator slow: ${modDuration}ms`); diff --git a/src/lib/integrationTests/suites/submissionTests.ts b/src/lib/integrationTests/suites/submissionTests.ts index 33eaec16..34c26998 100644 --- a/src/lib/integrationTests/suites/submissionTests.ts +++ b/src/lib/integrationTests/suites/submissionTests.ts @@ -347,7 +347,7 @@ export const submissionTestSuite: TestSuite = { } // Verify version was created with images - let version = null; + let version: any = null; const pollStart = Date.now(); while (!version && Date.now() - pollStart < 5000) { const { data } = await supabase diff --git a/src/lib/integrationTests/suites/unitConversionTests.ts b/src/lib/integrationTests/suites/unitConversionTests.ts index e52d9e83..25e4949a 100644 --- a/src/lib/integrationTests/suites/unitConversionTests.ts +++ b/src/lib/integrationTests/suites/unitConversionTests.ts @@ -72,16 +72,16 @@ export const unitConversionTestSuite: TestSuite = { // Validate values are stored in metric const tolerance = 0.01; // Allow small floating point differences - if (Math.abs(ride.max_speed_kmh - testData.max_speed_kmh) > tolerance) { + if (Math.abs((ride.max_speed_kmh ?? 0) - testData.max_speed_kmh) > tolerance) { throw new Error(`max_speed_kmh mismatch: expected ${testData.max_speed_kmh}, got ${ride.max_speed_kmh}`); } - if (Math.abs(ride.max_height_meters - testData.max_height_meters) > tolerance) { + if (Math.abs((ride.max_height_meters ?? 0) - testData.max_height_meters) > tolerance) { throw new Error(`max_height_meters mismatch: expected ${testData.max_height_meters}, got ${ride.max_height_meters}`); } - if (Math.abs(ride.length_meters - testData.length_meters) > tolerance) { + if (Math.abs((ride.length_meters ?? 0) - testData.length_meters) > tolerance) { throw new Error(`length_meters mismatch: expected ${testData.length_meters}, got ${ride.length_meters}`); } - if (Math.abs(ride.height_requirement - testData.height_requirement) > tolerance) { + if (Math.abs((ride.height_requirement ?? 0) - testData.height_requirement) > tolerance) { throw new Error(`height_requirement mismatch: expected ${testData.height_requirement} cm, got ${ride.height_requirement}`); } @@ -172,7 +172,7 @@ export const unitConversionTestSuite: TestSuite = { tracker.track('rides', rideId); // Poll for version creation - let version = null; + let version: any = null; const pollStart = Date.now(); while (!version && Date.now() - pollStart < 5000) { const { data } = await supabase @@ -193,13 +193,13 @@ export const unitConversionTestSuite: TestSuite = { // Validate version has metric units const tolerance = 0.01; - if (Math.abs(version.max_speed_kmh - 120.0) > tolerance) { + if (Math.abs((version.max_speed_kmh ?? 0) - 120.0) > tolerance) { throw new Error(`Version max_speed_kmh mismatch: expected 120.0, got ${version.max_speed_kmh}`); } - if (Math.abs(version.height_meters - 60.0) > tolerance) { + if (Math.abs((version.height_meters ?? 0) - 60.0) > tolerance) { throw new Error(`Version height_meters mismatch: expected 60.0, got ${version.height_meters}`); } - if (Math.abs(version.height_requirement_cm - 140) > tolerance) { + if (Math.abs((version.height_requirement_cm ?? 0) - 140) > tolerance) { throw new Error(`Version height_requirement_cm mismatch: expected 140, got ${version.height_requirement_cm}`); } diff --git a/src/lib/integrationTests/suites/versioningTests.ts b/src/lib/integrationTests/suites/versioningTests.ts index 13a0e727..a8a6e748 100644 --- a/src/lib/integrationTests/suites/versioningTests.ts +++ b/src/lib/integrationTests/suites/versioningTests.ts @@ -43,7 +43,7 @@ export const versioningTestSuite: TestSuite = { parkId = park.id; // Poll for version creation - let v1 = null; + let v1: any = null; const pollStart = Date.now(); while (!v1 && Date.now() - pollStart < 5000) { const { data } = await supabase @@ -243,7 +243,7 @@ export const versioningTestSuite: TestSuite = { parkId = park.id; // Poll for version creation - let v1 = null; + let v1: any = null; const pollStart = Date.now(); while (!v1 && Date.now() - pollStart < 5000) { const { data } = await supabase diff --git a/src/lib/notificationService.ts b/src/lib/notificationService.ts index ef27107e..76701097 100644 --- a/src/lib/notificationService.ts +++ b/src/lib/notificationService.ts @@ -347,8 +347,8 @@ class NotificationService { return (data || []).map(t => ({ ...t, is_active: t.is_active ?? true, - description: t.description || undefined, - novu_workflow_id: t.novu_workflow_id || undefined + description: t.description || null, + novu_workflow_id: t.novu_workflow_id || null, })); } catch (error: unknown) { logger.error('Error fetching notification templates', { diff --git a/src/lib/requestTracking.ts b/src/lib/requestTracking.ts index 7f277933..100967a3 100644 --- a/src/lib/requestTracking.ts +++ b/src/lib/requestTracking.ts @@ -110,7 +110,7 @@ async function logRequestMetadata(metadata: RequestMetadata): Promise { // Safe cast - RPC function exists in database const { error } = await supabase.rpc('log_request_metadata' as 'log_request_metadata', { p_request_id: metadata.requestId, - p_user_id: metadata.userId || null, + p_user_id: metadata.userId ?? undefined, p_endpoint: metadata.endpoint, p_method: metadata.method, p_status_code: metadata.statusCode, diff --git a/src/lib/submissionItemsService.ts b/src/lib/submissionItemsService.ts index b15bb2ab..ba097097 100644 --- a/src/lib/submissionItemsService.ts +++ b/src/lib/submissionItemsService.ts @@ -1450,7 +1450,7 @@ export async function checkSubmissionConflict( }, serverVersion: { last_modified_at: data.last_modified_at, - last_modified_by: data.last_modified_by, + last_modified_by: (data.last_modified_by ?? undefined) as string, modified_by_profile: data.profiles as any, }, }; diff --git a/src/pages/AdminDashboard.tsx b/src/pages/AdminDashboard.tsx index 72d7ed8c..3c54c53b 100644 --- a/src/pages/AdminDashboard.tsx +++ b/src/pages/AdminDashboard.tsx @@ -197,7 +197,7 @@ export default function AdminDashboard() { onRefresh={handleRefresh} refreshMode={refreshMode} pollInterval={pollInterval} - lastUpdated={lastUpdated} + lastUpdated={lastUpdated ?? undefined} isRefreshing={isRefreshing} >
diff --git a/src/pages/AdminModeration.tsx b/src/pages/AdminModeration.tsx index fb1906c5..5dea1bbf 100644 --- a/src/pages/AdminModeration.tsx +++ b/src/pages/AdminModeration.tsx @@ -37,7 +37,7 @@ export default function AdminModeration() { onRefresh={handleRefresh} refreshMode={refreshMode} pollInterval={pollInterval} - lastUpdated={lastUpdated} + lastUpdated={lastUpdated ?? undefined} >
@@ -70,7 +70,7 @@ export default function AdminModeration() { onRefresh={handleRefresh} refreshMode={refreshMode} pollInterval={pollInterval} - lastUpdated={lastUpdated} + lastUpdated={lastUpdated ?? undefined} >
diff --git a/src/pages/AdminReports.tsx b/src/pages/AdminReports.tsx index 785c3cc9..4aa2dbaa 100644 --- a/src/pages/AdminReports.tsx +++ b/src/pages/AdminReports.tsx @@ -38,7 +38,7 @@ export default function AdminReports() { onRefresh={handleRefresh} refreshMode={refreshMode} pollInterval={pollInterval} - lastUpdated={lastUpdated} + lastUpdated={lastUpdated ?? undefined} >
@@ -71,7 +71,7 @@ export default function AdminReports() { onRefresh={handleRefresh} refreshMode={refreshMode} pollInterval={pollInterval} - lastUpdated={lastUpdated} + lastUpdated={lastUpdated ?? undefined} >
diff --git a/src/pages/Auth.tsx b/src/pages/Auth.tsx index ce460ae8..212993d5 100644 --- a/src/pages/Auth.tsx +++ b/src/pages/Auth.tsx @@ -147,7 +147,7 @@ export default function Auth() { const { handlePostAuthFlow } = await import('@/lib/authService'); const postAuthResult = await handlePostAuthFlow(data.session, 'password'); - if (postAuthResult.success && postAuthResult.data.shouldRedirect) { + if (postAuthResult.success && postAuthResult.data?.shouldRedirect) { // Get the TOTP factor ID const { data: factors } = await supabase.auth.mfa.listFactors(); const totpFactor = factors?.totp?.find(f => f.status === 'verified'); @@ -189,7 +189,7 @@ export default function Auth() { errorMessage = 'Invalid email or password. Please try again.'; } else if (errorMsg.includes('Email not confirmed')) { errorMessage = 'Please confirm your email address before signing in.'; - } else if (error.message.includes('Too many requests')) { + } else if (error instanceof Error && error.message.includes('Too many requests')) { errorMessage = 'Too many login attempts. Please wait a few minutes and try again.'; } diff --git a/src/pages/BlogIndex.tsx b/src/pages/BlogIndex.tsx index 59731e6e..d502013b 100644 --- a/src/pages/BlogIndex.tsx +++ b/src/pages/BlogIndex.tsx @@ -45,8 +45,8 @@ export default function BlogIndex() { description: searchQuery ? `Search results for "${searchQuery}" in ThrillWiki Blog` : 'News, updates, and stories from the world of theme parks and roller coasters', - imageUrl: data?.posts?.[0]?.featured_image_url, - imageId: data?.posts?.[0]?.featured_image_id, + imageUrl: data?.posts?.[0]?.featured_image_url ?? undefined, + imageId: data?.posts?.[0]?.featured_image_id ?? undefined, type: 'website', enabled: !isLoading }); @@ -97,14 +97,14 @@ export default function BlogIndex() { slug={post.slug} title={post.title} content={post.content} - featuredImageId={post.featured_image_id} + featuredImageId={post.featured_image_id ?? undefined} author={{ username: post.profiles.username, - displayName: post.profiles.display_name, - avatarUrl: post.profiles.avatar_url, + displayName: post.profiles.display_name ?? undefined, + avatarUrl: post.profiles.avatar_url ?? undefined, }} publishedAt={post.published_at!} - viewCount={post.view_count} + viewCount={post.view_count ?? 0} /> ))}
diff --git a/src/pages/BlogPost.tsx b/src/pages/BlogPost.tsx index bcf05d1c..251968f6 100644 --- a/src/pages/BlogPost.tsx +++ b/src/pages/BlogPost.tsx @@ -23,7 +23,7 @@ export default function BlogPost() { const query = supabase .from('blog_posts') .select('*, profiles!inner(username, display_name, avatar_url, avatar_image_id)') - .eq('slug', slug) + .eq('slug', slug || '') .eq('status', 'published') .single(); @@ -41,8 +41,8 @@ export default function BlogPost() { useOpenGraph({ title: post?.title || '', description: post?.content?.substring(0, 160), - imageUrl: post?.featured_image_url, - imageId: post?.featured_image_id, + imageUrl: post?.featured_image_url ?? undefined, + imageId: post?.featured_image_id ?? undefined, type: 'article', enabled: !!post }); @@ -106,14 +106,14 @@ export default function BlogPost() {
- + {post.profiles.display_name?.[0] || post.profiles.username[0]}

- {post.profiles.display_name || post.profiles.username} + {post.profiles.display_name ?? post.profiles.username}

diff --git a/src/pages/DesignerDetail.tsx b/src/pages/DesignerDetail.tsx index e8218551..af7e5be0 100644 --- a/src/pages/DesignerDetail.tsx +++ b/src/pages/DesignerDetail.tsx @@ -46,9 +46,9 @@ export default function DesignerDetail() { // Update Open Graph meta tags useOpenGraph({ title: designer?.name || '', - description: designer?.description || (designer ? `${designer.name} - Ride Designer${designer.headquarters_location ? ` based in ${designer.headquarters_location}` : ''}` : ''), - imageUrl: designer?.banner_image_url, - imageId: designer?.banner_image_id, + description: designer?.description ?? (designer ? `${designer.name} - Ride Designer${designer.headquarters_location ? ` based in ${designer.headquarters_location}` : ''}` : ''), + imageUrl: designer?.banner_image_url ?? undefined, + imageId: designer?.banner_image_id ?? undefined, type: 'profile', enabled: !!designer }); @@ -71,7 +71,7 @@ export default function DesignerDetail() { const { data, error } = await supabase .from('companies') .select('*') - .eq('slug', slug) + .eq('slug', slug || '') .eq('company_type', 'designer') .maybeSingle(); @@ -197,10 +197,10 @@ export default function DesignerDetail() { {designer.name}
- {designer.average_rating > 0 && ( + {(designer.average_rating ?? 0) > 0 && (
- {designer.average_rating.toFixed(1)} + {(designer.average_rating ?? 0).toFixed(1)}
@@ -361,14 +361,14 @@ export default function DesignerDetail() { id: designer.id, name: designer.name, slug: designer.slug, - description: designer.description, + description: designer.description ?? undefined, company_type: 'designer', person_type: (designer.person_type || 'company') as 'company' | 'individual' | 'firm' | 'organization', - website_url: designer.website_url, - founded_year: designer.founded_year, - headquarters_location: designer.headquarters_location, - banner_image_url: designer.banner_image_url, - card_image_url: designer.card_image_url + website_url: designer.website_url ?? undefined, + founded_year: designer.founded_year ?? undefined, + headquarters_location: designer.headquarters_location ?? undefined, + banner_image_url: designer.banner_image_url ?? undefined, + card_image_url: designer.card_image_url ?? undefined }} onSubmit={handleEditSubmit} onCancel={() => setIsEditModalOpen(false)}