From 3d61d738f2a58c3bdf110d34b4937a4ce6cf7ab5 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 17 Oct 2025 13:05:59 +0000 Subject: [PATCH] Refactor: Implement type safety and error handling --- src/App.tsx | 2 ++ src/lib/entitySubmissionHelpers.ts | 13 +++---- src/lib/supabaseHelpers.ts | 55 ++++++++++++++++++++++++++++++ src/lib/versioningUtils.ts | 1 + 4 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 src/lib/supabaseHelpers.ts diff --git a/src/App.tsx b/src/App.tsx index ffe43541..75c1cab7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -31,6 +31,7 @@ import OperatorDetail from "./pages/OperatorDetail"; import OperatorParks from "./pages/OperatorParks"; import Auth from "./pages/Auth"; import Profile from "./pages/Profile"; +import ParkRides from "./pages/ParkRides"; import UserSettings from "./pages/UserSettings"; import Search from "./pages/Search"; import NotFound from "./pages/NotFound"; @@ -77,6 +78,7 @@ function AppContent() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/src/lib/entitySubmissionHelpers.ts b/src/lib/entitySubmissionHelpers.ts index 165ee277..2bc6f2e0 100644 --- a/src/lib/entitySubmissionHelpers.ts +++ b/src/lib/entitySubmissionHelpers.ts @@ -2,6 +2,7 @@ import { supabase } from '@/integrations/supabase/client'; import type { Json } from '@/integrations/supabase/types'; import { ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; import { uploadPendingImages } from './imageUploadHelper'; +import type { ProcessedImage } from './supabaseHelpers'; /** * ═══════════════════════════════════════════════════════════════════ @@ -302,7 +303,7 @@ export async function submitParkUpdate( item_data: { ...data, park_id: parkId, - images: processedImages as any + images: processedImages as unknown as Json }, original_data: JSON.parse(JSON.stringify(existingPark)), status: 'pending', @@ -465,7 +466,7 @@ export async function submitRideUpdate( item_data: { ...data, ride_id: rideId, - images: processedImages as any + images: processedImages as unknown as Json }, original_data: JSON.parse(JSON.stringify(existingRide)), status: 'pending', @@ -724,7 +725,7 @@ export async function submitManufacturerUpdate( ...data, company_id: companyId, company_type: 'manufacturer', - images: processedImages as any + images: processedImages as unknown as Json }, original_data: JSON.parse(JSON.stringify(existingCompany)), status: 'pending', @@ -832,7 +833,7 @@ export async function submitDesignerUpdate( ...data, company_id: companyId, company_type: 'designer', - images: processedImages as any + images: processedImages as unknown as Json }, original_data: JSON.parse(JSON.stringify(existingCompany)), status: 'pending', @@ -940,7 +941,7 @@ export async function submitOperatorUpdate( ...data, company_id: companyId, company_type: 'operator', - images: processedImages as any + images: processedImages as unknown as Json }, original_data: JSON.parse(JSON.stringify(existingCompany)), status: 'pending', @@ -1048,7 +1049,7 @@ export async function submitPropertyOwnerUpdate( ...data, company_id: companyId, company_type: 'property_owner', - images: processedImages as any + images: processedImages as unknown as Json }, original_data: JSON.parse(JSON.stringify(existingCompany)), status: 'pending', diff --git a/src/lib/supabaseHelpers.ts b/src/lib/supabaseHelpers.ts new file mode 100644 index 00000000..70375c66 --- /dev/null +++ b/src/lib/supabaseHelpers.ts @@ -0,0 +1,55 @@ +/** + * Type-safe Supabase query helpers + * + * Provides type-safe table query builders to eliminate `as any` assertions. + */ + +import { supabase } from '@/integrations/supabase/client'; +import type { Database } from '@/integrations/supabase/types'; + +// Define valid table names from the database schema +export type TableName = keyof Database['public']['Tables']; + +/** + * Create a type-safe query builder for a specific table + * + * @example + * ```typescript + * const query = createTableQuery('parks').select('*').eq('slug', 'disneyland'); + * const query2 = createTableQuery('rides').select('id, name').eq('status', 'operating'); + * ``` + */ +export function createTableQuery(tableName: T) { + return supabase.from(tableName); +} + +/** + * Dynamically query a table by name with type safety + * + * Use this when the table name is determined at runtime (e.g., version tables). + * + * @example + * ```typescript + * const versions = await queryTable('park_versions', (q) => + * q.select('*').eq('park_id', parkId) + * ); + * ``` + */ +export async function queryTable( + tableName: T, + queryBuilder: (query: ReturnType>) => any +) { + const query = createTableQuery(tableName); + return queryBuilder(query); +} + +/** + * Type-safe interface for processed uploaded images + */ +export interface ProcessedImage { + url: string; + cloudflare_id: string; + order: number; + title?: string; + caption?: string; +} diff --git a/src/lib/versioningUtils.ts b/src/lib/versioningUtils.ts index f8b550e3..4cbe2cdd 100644 --- a/src/lib/versioningUtils.ts +++ b/src/lib/versioningUtils.ts @@ -10,6 +10,7 @@ import { supabase } from '@/integrations/supabase/client'; import type { EntityType } from '@/types/versioning'; +import { createTableQuery } from './supabaseHelpers'; /** * Manually trigger cleanup of old versions for a specific entity type