diff --git a/src/lib/submissionItemsService.ts b/src/lib/submissionItemsService.ts index 4d585a7c..dde06194 100644 --- a/src/lib/submissionItemsService.ts +++ b/src/lib/submissionItemsService.ts @@ -2,167 +2,15 @@ import { supabase } from '@/integrations/supabase/client'; import { getErrorMessage } from './errorHandler'; import { logger } from './logger'; -// ============= TYPE DEFINITIONS ============= - -type EntityType = 'park' | 'ride' | 'manufacturer' | 'operator' | 'property_owner' | 'designer' | 'ride_model' | 'photo' | 'timeline_event' | 'milestone' | 'location'; - -interface ImageAssignment { - url: string; - cloudflare_id: string; -} - -interface ImageAssignments { - uploaded?: ImageAssignment[]; - banner_assignment?: number | null; - card_assignment?: number | null; -} - -interface LocationData { - name: string; - city?: string | null; - state_province?: string | null; - country: string; - postal_code?: string | null; - latitude: number; - longitude: number; - timezone?: string | null; -} - -interface PhotoData { - url: string; - cloudflare_image_id?: string; - title?: string; - caption?: string; - photographer_credit?: string; - date?: string; - date_taken?: string; - order?: number; -} - -// Flexible entity form data that accommodates all entity types -// This is intentionally permissive to maintain backwards compatibility -// while adding type safety to function signatures -interface EntityFormData { - // Common fields (not all entities have all fields) - name?: string; - slug?: string; - description?: string | null; - images?: ImageAssignments; - - // Park-specific fields - park_id?: string; - park_type?: string; - status?: string; - opening_date?: string | null; - closing_date?: string | null; - opening_date_precision?: string | null; - closing_date_precision?: string | null; - website_url?: string | null; - phone?: string | null; - email?: string | null; - operator_id?: string | null; - property_owner_id?: string | null; - location_id?: string | null; - location?: LocationData; - - // Ride-specific fields - ride_id?: string; - category?: string; - park_id?: string; - manufacturer_id?: string | null; - manufacturer_name?: string | null; - designer_id?: string | null; - ride_model_id?: string | null; - height_requirement?: number | null; - age_requirement?: number | null; - capacity_per_hour?: number | null; - duration_seconds?: number | null; - max_speed_kmh?: number | null; - max_height_meters?: number | null; - length_meters?: number | null; - inversions?: number | null; - coaster_type?: string | null; - seating_type?: string | null; - intensity_level?: string | null; - drop_height_meters?: number | null; - max_g_force?: number | null; - ride_sub_type?: string | null; - - // Company-specific fields - id?: string; - company_type?: string; - founded_year?: number | null; - founded_date?: string | null; - founded_date_precision?: string | null; - headquarters_location?: string | null; - - // Ride model fields - technical_specs?: Record; - - // Photo submission fields - photos?: PhotoData[]; - entity_id?: string; - context?: EntityType; - title?: string; - - // Timeline/milestone fields - entity_type?: EntityType; - event_type?: string; - event_date?: string; - event_date_precision?: string; - from_value?: string | null; - to_value?: string | null; - from_entity_id?: string | null; - to_entity_id?: string | null; - from_location_id?: string | null; - to_location_id?: string | null; - is_public?: boolean; - - // Allow additional properties for flexibility - [key: string]: unknown; -} - -// Specific typed interfaces for function parameters -interface ParkFormData extends EntityFormData { - name: string; - slug: string; - park_type: string; - status: string; -} - -interface RideFormData extends EntityFormData { - name: string; - slug: string; - category: string; - status: string; - park_id: string; -} - -interface CompanyFormData extends EntityFormData { - name: string; - slug: string; -} - -interface RideModelFormData extends EntityFormData { - name: string; - slug: string; - manufacturer_id: string; -} - -interface PhotoSubmissionData extends EntityFormData { - photos: PhotoData[]; - entity_id: string; - context: EntityType; -} - -// ============= MAIN INTERFACES ============= +// Core submission item interface with dependencies +// Type safety for item_data will be added in Phase 5 after fixing components export interface SubmissionItemWithDeps { id: string; submission_id: string; item_type: string; - item_data: EntityFormData; - original_data: EntityFormData | null; + item_data: any; // Complex nested structure - will be typed properly in Phase 5 + original_data: any; // Complex nested structure - will be typed properly in Phase 5 action_type?: 'create' | 'edit' | 'delete'; status: 'pending' | 'approved' | 'rejected'; depends_on: string | null; @@ -465,7 +313,7 @@ function topologicalSort(items: SubmissionItemWithDeps[]): SubmissionItemWithDep /** * Extract image URLs from ImageAssignments structure */ -function extractImageAssignments(images: Record | undefined) { +function extractImageAssignments(images: any) { if (!images || !images.uploaded || !Array.isArray(images.uploaded)) { return { banner_image_url: null, @@ -494,7 +342,7 @@ function extractImageAssignments(images: Record | undefined) { /** * Helper functions to create entities with dependency resolution */ -async function createPark(data: Record, dependencyMap: Map): Promise { +async function createPark(data: any, dependencyMap: Map): Promise { const { transformParkData, validateSubmissionData } = await import('./entityTransformers'); const { ensureUniqueSlug } = await import('./slugUtils'); @@ -603,7 +451,7 @@ async function createPark(data: Record, dependencyMap: Map | undefined): Promise { +async function resolveLocationId(locationData: any): Promise { if (!locationData || !locationData.latitude || !locationData.longitude) { return null; } @@ -649,7 +497,7 @@ async function resolveLocationId(locationData: Record | undefin return newLocation.id; } -async function createRide(data: Record, dependencyMap: Map): Promise { +async function createRide(data: any, dependencyMap: Map): Promise { const { transformRideData, validateSubmissionData } = await import('./entityTransformers'); const { ensureUniqueSlug } = await import('./slugUtils'); @@ -737,7 +585,7 @@ async function createRide(data: Record, dependencyMap: Map, + data: any, companyType: string, dependencyMap: Map ): Promise { @@ -814,7 +662,7 @@ async function createCompany( return company.id; } -async function createRideModel(data: Record, dependencyMap: Map): Promise { +async function createRideModel(data: any, dependencyMap: Map): Promise { const { transformRideModelData, validateSubmissionData } = await import('./entityTransformers'); const { ensureUniqueSlug } = await import('./slugUtils'); @@ -851,7 +699,7 @@ async function createRideModel(data: Record, dependencyMap: Map return model.id; } -async function approvePhotos(data: Record, dependencyMap: Map, userId: string, submissionId: string): Promise { +async function approvePhotos(data: any, dependencyMap: Map, userId: string, submissionId: string): Promise { // Photos are already uploaded to Cloudflare // Resolve dependencies for entity associations const resolvedData = resolveDependencies(data, dependencyMap); @@ -885,7 +733,7 @@ async function approvePhotos(data: Record, dependencyMap: Map, index: number) => { + const photosToInsert = resolvedData.photos.map((photo: any, index: number) => { // Extract CloudFlare image ID from URL if not provided let cloudflareImageId = photo.cloudflare_image_id; if (!cloudflareImageId && photo.url) { @@ -1008,7 +856,7 @@ async function updateEntityFeaturedImage( * Resolve dependency references in submission data * Replaces submission item IDs with actual database entity IDs */ -function resolveDependencies(data: Record, dependencyMap: Map): Record { +function resolveDependencies(data: any, dependencyMap: Map): any { const resolved = { ...data }; // List of foreign key fields that may need resolution @@ -1183,7 +1031,7 @@ async function updateSubmissionStatusAfterRejection(submissionId: string): Promi */ export async function editSubmissionItem( itemId: string, - newData: Record, + newData: any, userId: string ): Promise { if (!userId) {