Fix: Resolve remaining TypeScript errors

This commit is contained in:
gpt-engineer-app[bot]
2025-11-03 02:54:43 +00:00
parent 07420a67bf
commit 516f7c4c41
14 changed files with 49 additions and 49 deletions

View File

@@ -56,7 +56,7 @@ export const performanceTestSuite: TestSuite = {
// Set performance thresholds (in milliseconds) // Set performance thresholds (in milliseconds)
const threshold = 1000; // 1 second const threshold = 1000; // 1 second
const warnings = []; const warnings: string[] = [];
if (parksDuration > threshold) { if (parksDuration > threshold) {
warnings.push(`Parks query slow: ${parksDuration}ms`); warnings.push(`Parks query slow: ${parksDuration}ms`);
@@ -229,7 +229,7 @@ export const performanceTestSuite: TestSuite = {
// Performance threshold: 200ms for simple functions // Performance threshold: 200ms for simple functions
const threshold = 200; const threshold = 200;
const warnings = []; const warnings: string[] = [];
if (modDuration > threshold) { if (modDuration > threshold) {
warnings.push(`is_moderator slow: ${modDuration}ms`); warnings.push(`is_moderator slow: ${modDuration}ms`);

View File

@@ -347,7 +347,7 @@ export const submissionTestSuite: TestSuite = {
} }
// Verify version was created with images // Verify version was created with images
let version = null; let version: any = null;
const pollStart = Date.now(); const pollStart = Date.now();
while (!version && Date.now() - pollStart < 5000) { while (!version && Date.now() - pollStart < 5000) {
const { data } = await supabase const { data } = await supabase

View File

@@ -72,16 +72,16 @@ export const unitConversionTestSuite: TestSuite = {
// Validate values are stored in metric // Validate values are stored in metric
const tolerance = 0.01; // Allow small floating point differences 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}`); 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}`); 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}`); 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}`); 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); tracker.track('rides', rideId);
// Poll for version creation // Poll for version creation
let version = null; let version: any = null;
const pollStart = Date.now(); const pollStart = Date.now();
while (!version && Date.now() - pollStart < 5000) { while (!version && Date.now() - pollStart < 5000) {
const { data } = await supabase const { data } = await supabase
@@ -193,13 +193,13 @@ export const unitConversionTestSuite: TestSuite = {
// Validate version has metric units // Validate version has metric units
const tolerance = 0.01; 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}`); 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}`); 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}`); throw new Error(`Version height_requirement_cm mismatch: expected 140, got ${version.height_requirement_cm}`);
} }

View File

@@ -43,7 +43,7 @@ export const versioningTestSuite: TestSuite = {
parkId = park.id; parkId = park.id;
// Poll for version creation // Poll for version creation
let v1 = null; let v1: any = null;
const pollStart = Date.now(); const pollStart = Date.now();
while (!v1 && Date.now() - pollStart < 5000) { while (!v1 && Date.now() - pollStart < 5000) {
const { data } = await supabase const { data } = await supabase
@@ -243,7 +243,7 @@ export const versioningTestSuite: TestSuite = {
parkId = park.id; parkId = park.id;
// Poll for version creation // Poll for version creation
let v1 = null; let v1: any = null;
const pollStart = Date.now(); const pollStart = Date.now();
while (!v1 && Date.now() - pollStart < 5000) { while (!v1 && Date.now() - pollStart < 5000) {
const { data } = await supabase const { data } = await supabase

View File

@@ -347,8 +347,8 @@ class NotificationService {
return (data || []).map(t => ({ return (data || []).map(t => ({
...t, ...t,
is_active: t.is_active ?? true, is_active: t.is_active ?? true,
description: t.description || undefined, description: t.description || null,
novu_workflow_id: t.novu_workflow_id || undefined novu_workflow_id: t.novu_workflow_id || null,
})); }));
} catch (error: unknown) { } catch (error: unknown) {
logger.error('Error fetching notification templates', { logger.error('Error fetching notification templates', {

View File

@@ -110,7 +110,7 @@ async function logRequestMetadata(metadata: RequestMetadata): Promise<void> {
// Safe cast - RPC function exists in database // Safe cast - RPC function exists in database
const { error } = await supabase.rpc('log_request_metadata' as 'log_request_metadata', { const { error } = await supabase.rpc('log_request_metadata' as 'log_request_metadata', {
p_request_id: metadata.requestId, p_request_id: metadata.requestId,
p_user_id: metadata.userId || null, p_user_id: metadata.userId ?? undefined,
p_endpoint: metadata.endpoint, p_endpoint: metadata.endpoint,
p_method: metadata.method, p_method: metadata.method,
p_status_code: metadata.statusCode, p_status_code: metadata.statusCode,

View File

@@ -1450,7 +1450,7 @@ export async function checkSubmissionConflict(
}, },
serverVersion: { serverVersion: {
last_modified_at: data.last_modified_at, 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, modified_by_profile: data.profiles as any,
}, },
}; };

View File

@@ -197,7 +197,7 @@ export default function AdminDashboard() {
onRefresh={handleRefresh} onRefresh={handleRefresh}
refreshMode={refreshMode} refreshMode={refreshMode}
pollInterval={pollInterval} pollInterval={pollInterval}
lastUpdated={lastUpdated} lastUpdated={lastUpdated ?? undefined}
isRefreshing={isRefreshing} isRefreshing={isRefreshing}
> >
<div className="space-y-6"> <div className="space-y-6">

View File

@@ -37,7 +37,7 @@ export default function AdminModeration() {
onRefresh={handleRefresh} onRefresh={handleRefresh}
refreshMode={refreshMode} refreshMode={refreshMode}
pollInterval={pollInterval} pollInterval={pollInterval}
lastUpdated={lastUpdated} lastUpdated={lastUpdated ?? undefined}
> >
<div className="space-y-6"> <div className="space-y-6">
<div> <div>
@@ -70,7 +70,7 @@ export default function AdminModeration() {
onRefresh={handleRefresh} onRefresh={handleRefresh}
refreshMode={refreshMode} refreshMode={refreshMode}
pollInterval={pollInterval} pollInterval={pollInterval}
lastUpdated={lastUpdated} lastUpdated={lastUpdated ?? undefined}
> >
<div className="space-y-6"> <div className="space-y-6">
<div> <div>

View File

@@ -38,7 +38,7 @@ export default function AdminReports() {
onRefresh={handleRefresh} onRefresh={handleRefresh}
refreshMode={refreshMode} refreshMode={refreshMode}
pollInterval={pollInterval} pollInterval={pollInterval}
lastUpdated={lastUpdated} lastUpdated={lastUpdated ?? undefined}
> >
<div className="space-y-6"> <div className="space-y-6">
<div> <div>
@@ -71,7 +71,7 @@ export default function AdminReports() {
onRefresh={handleRefresh} onRefresh={handleRefresh}
refreshMode={refreshMode} refreshMode={refreshMode}
pollInterval={pollInterval} pollInterval={pollInterval}
lastUpdated={lastUpdated} lastUpdated={lastUpdated ?? undefined}
> >
<div className="space-y-6"> <div className="space-y-6">
<div> <div>

View File

@@ -147,7 +147,7 @@ export default function Auth() {
const { handlePostAuthFlow } = await import('@/lib/authService'); const { handlePostAuthFlow } = await import('@/lib/authService');
const postAuthResult = await handlePostAuthFlow(data.session, 'password'); const postAuthResult = await handlePostAuthFlow(data.session, 'password');
if (postAuthResult.success && postAuthResult.data.shouldRedirect) { if (postAuthResult.success && postAuthResult.data?.shouldRedirect) {
// Get the TOTP factor ID // Get the TOTP factor ID
const { data: factors } = await supabase.auth.mfa.listFactors(); const { data: factors } = await supabase.auth.mfa.listFactors();
const totpFactor = factors?.totp?.find(f => f.status === 'verified'); 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.'; errorMessage = 'Invalid email or password. Please try again.';
} else if (errorMsg.includes('Email not confirmed')) { } else if (errorMsg.includes('Email not confirmed')) {
errorMessage = 'Please confirm your email address before signing in.'; 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.'; errorMessage = 'Too many login attempts. Please wait a few minutes and try again.';
} }

View File

@@ -45,8 +45,8 @@ export default function BlogIndex() {
description: searchQuery description: searchQuery
? `Search results for "${searchQuery}" in ThrillWiki Blog` ? `Search results for "${searchQuery}" in ThrillWiki Blog`
: 'News, updates, and stories from the world of theme parks and roller coasters', : 'News, updates, and stories from the world of theme parks and roller coasters',
imageUrl: data?.posts?.[0]?.featured_image_url, imageUrl: data?.posts?.[0]?.featured_image_url ?? undefined,
imageId: data?.posts?.[0]?.featured_image_id, imageId: data?.posts?.[0]?.featured_image_id ?? undefined,
type: 'website', type: 'website',
enabled: !isLoading enabled: !isLoading
}); });
@@ -97,14 +97,14 @@ export default function BlogIndex() {
slug={post.slug} slug={post.slug}
title={post.title} title={post.title}
content={post.content} content={post.content}
featuredImageId={post.featured_image_id} featuredImageId={post.featured_image_id ?? undefined}
author={{ author={{
username: post.profiles.username, username: post.profiles.username,
displayName: post.profiles.display_name, displayName: post.profiles.display_name ?? undefined,
avatarUrl: post.profiles.avatar_url, avatarUrl: post.profiles.avatar_url ?? undefined,
}} }}
publishedAt={post.published_at!} publishedAt={post.published_at!}
viewCount={post.view_count} viewCount={post.view_count ?? 0}
/> />
))} ))}
</div> </div>

View File

@@ -23,7 +23,7 @@ export default function BlogPost() {
const query = supabase const query = supabase
.from('blog_posts') .from('blog_posts')
.select('*, profiles!inner(username, display_name, avatar_url, avatar_image_id)') .select('*, profiles!inner(username, display_name, avatar_url, avatar_image_id)')
.eq('slug', slug) .eq('slug', slug || '')
.eq('status', 'published') .eq('status', 'published')
.single(); .single();
@@ -41,8 +41,8 @@ export default function BlogPost() {
useOpenGraph({ useOpenGraph({
title: post?.title || '', title: post?.title || '',
description: post?.content?.substring(0, 160), description: post?.content?.substring(0, 160),
imageUrl: post?.featured_image_url, imageUrl: post?.featured_image_url ?? undefined,
imageId: post?.featured_image_id, imageId: post?.featured_image_id ?? undefined,
type: 'article', type: 'article',
enabled: !!post enabled: !!post
}); });
@@ -106,14 +106,14 @@ export default function BlogPost() {
<div className="flex items-center justify-between mb-8 pb-6 border-b"> <div className="flex items-center justify-between mb-8 pb-6 border-b">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Avatar className="w-12 h-12"> <Avatar className="w-12 h-12">
<AvatarImage src={post.profiles.avatar_url} /> <AvatarImage src={post.profiles.avatar_url ?? undefined} />
<AvatarFallback> <AvatarFallback>
{post.profiles.display_name?.[0] || post.profiles.username[0]} {post.profiles.display_name?.[0] || post.profiles.username[0]}
</AvatarFallback> </AvatarFallback>
</Avatar> </Avatar>
<div> <div>
<p className="font-medium"> <p className="font-medium">
{post.profiles.display_name || post.profiles.username} {post.profiles.display_name ?? post.profiles.username}
</p> </p>
<div className="flex items-center gap-3 text-sm text-muted-foreground"> <div className="flex items-center gap-3 text-sm text-muted-foreground">
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">

View File

@@ -46,9 +46,9 @@ export default function DesignerDetail() {
// Update Open Graph meta tags // Update Open Graph meta tags
useOpenGraph({ useOpenGraph({
title: designer?.name || '', title: designer?.name || '',
description: designer?.description || (designer ? `${designer.name} - Ride Designer${designer.headquarters_location ? ` based in ${designer.headquarters_location}` : ''}` : ''), description: designer?.description ?? (designer ? `${designer.name} - Ride Designer${designer.headquarters_location ? ` based in ${designer.headquarters_location}` : ''}` : ''),
imageUrl: designer?.banner_image_url, imageUrl: designer?.banner_image_url ?? undefined,
imageId: designer?.banner_image_id, imageId: designer?.banner_image_id ?? undefined,
type: 'profile', type: 'profile',
enabled: !!designer enabled: !!designer
}); });
@@ -71,7 +71,7 @@ export default function DesignerDetail() {
const { data, error } = await supabase const { data, error } = await supabase
.from('companies') .from('companies')
.select('*') .select('*')
.eq('slug', slug) .eq('slug', slug || '')
.eq('company_type', 'designer') .eq('company_type', 'designer')
.maybeSingle(); .maybeSingle();
@@ -197,10 +197,10 @@ export default function DesignerDetail() {
<picture> <picture>
<source <source
media="(max-width: 768px)" media="(max-width: 768px)"
srcSet={getBannerUrls(designer.banner_image_id).mobile || designer.banner_image_url} srcSet={(getBannerUrls(designer.banner_image_id ?? undefined).mobile || designer.banner_image_url) ?? undefined}
/> />
<img <img
src={getBannerUrls(designer.banner_image_id).desktop || designer.banner_image_url} src={(getBannerUrls(designer.banner_image_id ?? undefined).desktop || designer.banner_image_url) ?? undefined}
alt={designer.name} alt={designer.name}
className="w-full h-full object-cover" className="w-full h-full object-cover"
loading="eager" loading="eager"
@@ -244,12 +244,12 @@ export default function DesignerDetail() {
</div> </div>
</div> </div>
{designer.average_rating > 0 && ( {(designer.average_rating ?? 0) > 0 && (
<div className="bg-black/30 backdrop-blur-md rounded-lg p-6 text-center"> <div className="bg-black/30 backdrop-blur-md rounded-lg p-6 text-center">
<div className="flex items-center gap-2 text-white mb-2"> <div className="flex items-center gap-2 text-white mb-2">
<Star className="w-6 h-6 fill-yellow-400 text-yellow-400" /> <Star className="w-6 h-6 fill-yellow-400 text-yellow-400" />
<span className="text-3xl font-bold"> <span className="text-3xl font-bold">
{designer.average_rating.toFixed(1)} {(designer.average_rating ?? 0).toFixed(1)}
</span> </span>
</div> </div>
<div className="text-white/90 text-sm"> <div className="text-white/90 text-sm">
@@ -361,14 +361,14 @@ export default function DesignerDetail() {
id: designer.id, id: designer.id,
name: designer.name, name: designer.name,
slug: designer.slug, slug: designer.slug,
description: designer.description, description: designer.description ?? undefined,
company_type: 'designer', company_type: 'designer',
person_type: (designer.person_type || 'company') as 'company' | 'individual' | 'firm' | 'organization', person_type: (designer.person_type || 'company') as 'company' | 'individual' | 'firm' | 'organization',
website_url: designer.website_url, website_url: designer.website_url ?? undefined,
founded_year: designer.founded_year, founded_year: designer.founded_year ?? undefined,
headquarters_location: designer.headquarters_location, headquarters_location: designer.headquarters_location ?? undefined,
banner_image_url: designer.banner_image_url, banner_image_url: designer.banner_image_url ?? undefined,
card_image_url: designer.card_image_url card_image_url: designer.card_image_url ?? undefined
}} }}
onSubmit={handleEditSubmit} onSubmit={handleEditSubmit}
onCancel={() => setIsEditModalOpen(false)} onCancel={() => setIsEditModalOpen(false)}