diff --git a/src/components/moderation/EntityEditPreview.tsx b/src/components/moderation/EntityEditPreview.tsx index 0bfaf82d..e4f38fdc 100644 --- a/src/components/moderation/EntityEditPreview.tsx +++ b/src/components/moderation/EntityEditPreview.tsx @@ -90,9 +90,9 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti .from('submission_items') .select(` *, - park_submission:park_submissions!item_data_id(*), - ride_submission:ride_submissions!item_data_id(*), - photo_submission:photo_submissions!item_data_id( + park_submission:park_submissions!park_submission_id(*), + ride_submission:ride_submissions!ride_submission_id(*), + photo_submission:photo_submissions!photo_submission_id( *, photo_items:photo_submission_items(*) ) diff --git a/src/components/moderation/SubmissionItemsList.tsx b/src/components/moderation/SubmissionItemsList.tsx index 25eb3d31..06efaaa2 100644 --- a/src/components/moderation/SubmissionItemsList.tsx +++ b/src/components/moderation/SubmissionItemsList.tsx @@ -59,10 +59,39 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({ if (itemsError) throw itemsError; - // Fetch entity data for each item based on item_type + // Fetch entity data for each item based on item_type and typed FK columns const transformedItems = await Promise.all( (itemsData || []).map(async (item) => { - if (!item.item_data_id) { + // Determine which FK column to use based on item_type + let itemDataId: string | null = null; + switch (item.item_type) { + case 'park': + itemDataId = item.park_submission_id; + break; + case 'ride': + itemDataId = item.ride_submission_id; + break; + case 'photo': + case 'photo_edit': + case 'photo_delete': + itemDataId = item.photo_submission_id; + break; + case 'manufacturer': + case 'operator': + case 'designer': + case 'property_owner': + itemDataId = item.company_submission_id; + break; + case 'ride_model': + itemDataId = item.ride_model_submission_id; + break; + case 'milestone': + case 'timeline_event': + itemDataId = item.timeline_event_submission_id; + break; + } + + if (!itemDataId) { return { ...item, item_data: {}, entity_data: null }; } @@ -75,7 +104,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({ const { data } = await supabase .from('park_submissions') .select('*') - .eq('id', item.item_data_id) + .eq('id', itemDataId) .maybeSingle(); entityData = data as any; break; @@ -84,7 +113,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({ const { data } = await supabase .from('ride_submissions') .select('*') - .eq('id', item.item_data_id) + .eq('id', itemDataId) .maybeSingle(); entityData = data as any; break; @@ -96,7 +125,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({ const { data } = await supabase .from('company_submissions') .select('*') - .eq('id', item.item_data_id) + .eq('id', itemDataId) .maybeSingle(); entityData = data as any; break; @@ -105,7 +134,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({ const { data } = await supabase .from('photo_submissions') .select('*') - .eq('id', item.item_data_id) + .eq('id', itemDataId) .maybeSingle(); entityData = data as any; break; @@ -114,7 +143,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({ const { data } = await supabase .from('ride_model_submissions') .select('*') - .eq('id', item.item_data_id) + .eq('id', itemDataId) .maybeSingle(); entityData = data as any; break; diff --git a/src/hooks/moderation/useModerationActions.ts b/src/hooks/moderation/useModerationActions.ts index 76ad13b8..437562a0 100644 --- a/src/hooks/moderation/useModerationActions.ts +++ b/src/hooks/moderation/useModerationActions.ts @@ -138,8 +138,8 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio .select(` id, item_type, - park_submission:park_submissions!item_data_id(*), - ride_submission:ride_submissions!item_data_id(*) + park_submission:park_submissions!park_submission_id(*), + ride_submission:ride_submissions!ride_submission_id(*) `) .eq('submission_id', item.id) .in('status', ['pending', 'rejected']); diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index d8079158..19a488a1 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -765,6 +765,27 @@ export type Database = { referencedRelation: "filtered_profiles" referencedColumns: ["id"] }, + { + foreignKeyName: "contact_submissions_submitter_profile_id_fkey" + columns: ["submitter_profile_id"] + isOneToOne: false + referencedRelation: "moderation_queue_with_entities" + referencedColumns: ["assignee_profile_id"] + }, + { + foreignKeyName: "contact_submissions_submitter_profile_id_fkey" + columns: ["submitter_profile_id"] + isOneToOne: false + referencedRelation: "moderation_queue_with_entities" + referencedColumns: ["reviewer_profile_id"] + }, + { + foreignKeyName: "contact_submissions_submitter_profile_id_fkey" + columns: ["submitter_profile_id"] + isOneToOne: false + referencedRelation: "moderation_queue_with_entities" + referencedColumns: ["submitter_profile_id"] + }, { foreignKeyName: "contact_submissions_submitter_profile_id_fkey" columns: ["submitter_profile_id"] @@ -4660,49 +4681,71 @@ export type Database = { Row: { action_type: string | null approved_entity_id: string | null + company_submission_id: string | null created_at: string depends_on: string | null id: string is_test_data: boolean | null - item_data_id: string | null item_type: string order_index: number | null + park_submission_id: string | null + photo_submission_id: string | null rejection_reason: string | null + ride_model_submission_id: string | null + ride_submission_id: string | null status: string submission_id: string + timeline_event_submission_id: string | null updated_at: string } Insert: { action_type?: string | null approved_entity_id?: string | null + company_submission_id?: string | null created_at?: string depends_on?: string | null id?: string is_test_data?: boolean | null - item_data_id?: string | null item_type: string order_index?: number | null + park_submission_id?: string | null + photo_submission_id?: string | null rejection_reason?: string | null + ride_model_submission_id?: string | null + ride_submission_id?: string | null status?: string submission_id: string + timeline_event_submission_id?: string | null updated_at?: string } Update: { action_type?: string | null approved_entity_id?: string | null + company_submission_id?: string | null created_at?: string depends_on?: string | null id?: string is_test_data?: boolean | null - item_data_id?: string | null item_type?: string order_index?: number | null + park_submission_id?: string | null + photo_submission_id?: string | null rejection_reason?: string | null + ride_model_submission_id?: string | null + ride_submission_id?: string | null status?: string submission_id?: string + timeline_event_submission_id?: string | null updated_at?: string } Relationships: [ + { + foreignKeyName: "submission_items_company_submission_id_fkey" + columns: ["company_submission_id"] + isOneToOne: false + referencedRelation: "company_submissions" + referencedColumns: ["id"] + }, { foreignKeyName: "submission_items_depends_on_fkey" columns: ["depends_on"] @@ -4710,6 +4753,34 @@ export type Database = { referencedRelation: "submission_items" referencedColumns: ["id"] }, + { + foreignKeyName: "submission_items_park_submission_id_fkey" + columns: ["park_submission_id"] + isOneToOne: false + referencedRelation: "park_submissions" + referencedColumns: ["id"] + }, + { + foreignKeyName: "submission_items_photo_submission_id_fkey" + columns: ["photo_submission_id"] + isOneToOne: false + referencedRelation: "photo_submissions" + referencedColumns: ["id"] + }, + { + foreignKeyName: "submission_items_ride_model_submission_id_fkey" + columns: ["ride_model_submission_id"] + isOneToOne: false + referencedRelation: "ride_model_submissions" + referencedColumns: ["id"] + }, + { + foreignKeyName: "submission_items_ride_submission_id_fkey" + columns: ["ride_submission_id"] + isOneToOne: false + referencedRelation: "ride_submissions" + referencedColumns: ["id"] + }, { foreignKeyName: "submission_items_submission_id_fkey" columns: ["submission_id"] @@ -4724,6 +4795,13 @@ export type Database = { referencedRelation: "moderation_queue_with_entities" referencedColumns: ["id"] }, + { + foreignKeyName: "submission_items_timeline_event_submission_id_fkey" + columns: ["timeline_event_submission_id"] + isOneToOne: false + referencedRelation: "timeline_event_submissions" + referencedColumns: ["id"] + }, ] } submission_metadata: { @@ -5264,26 +5342,43 @@ export type Database = { } moderation_queue_with_entities: { Row: { + approval_mode: string | null assigned_at: string | null - assigned_profile: Json | null assigned_to: string | null + assignee_avatar_url: string | null + assignee_display_name: string | null + assignee_profile_id: string | null + assignee_username: string | null created_at: string | null escalated: boolean | null escalated_at: string | null + escalated_by: string | null escalation_reason: string | null + first_reviewed_at: string | null id: string | null is_test_data: boolean | null + last_modified_at: string | null + last_modified_by: string | null locked_until: string | null + resolved_at: string | null + review_count: number | null + review_notes: string | null reviewed_at: string | null reviewed_by: string | null - reviewer_notes: string | null - reviewer_profile: Json | null + reviewer_avatar_url: string | null + reviewer_display_name: string | null + reviewer_profile_id: string | null + reviewer_username: string | null status: string | null submission_items: Json | null submission_type: string | null submitted_at: string | null - submitter_id: string | null - submitter_profile: Json | null + submitted_by: string | null + submitter_avatar_url: string | null + submitter_display_name: string | null + submitter_profile_id: string | null + submitter_reputation: number | null + submitter_username: string | null } Relationships: [ { @@ -5300,6 +5395,20 @@ export type Database = { referencedRelation: "profiles" referencedColumns: ["user_id"] }, + { + foreignKeyName: "content_submissions_escalated_by_fkey" + columns: ["escalated_by"] + isOneToOne: false + referencedRelation: "filtered_profiles" + referencedColumns: ["user_id"] + }, + { + foreignKeyName: "content_submissions_escalated_by_fkey" + columns: ["escalated_by"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["user_id"] + }, { foreignKeyName: "content_submissions_reviewer_id_fkey" columns: ["reviewed_by"] @@ -5316,14 +5425,14 @@ export type Database = { }, { foreignKeyName: "content_submissions_user_id_fkey" - columns: ["submitter_id"] + columns: ["submitted_by"] isOneToOne: false referencedRelation: "filtered_profiles" referencedColumns: ["user_id"] }, { foreignKeyName: "content_submissions_user_id_fkey" - columns: ["submitter_id"] + columns: ["submitted_by"] isOneToOne: false referencedRelation: "profiles" referencedColumns: ["user_id"] diff --git a/src/lib/entitySubmissionHelpers.ts b/src/lib/entitySubmissionHelpers.ts index 19e63510..051ba3f1 100644 --- a/src/lib/entitySubmissionHelpers.ts +++ b/src/lib/entitySubmissionHelpers.ts @@ -503,7 +503,7 @@ export async function submitParkCreation( submission_id: submissionData.id, item_type: 'park', action_type: 'create', - item_data_id: (parkSubmission as any).id, + park_submission_id: (parkSubmission as any).id, status: 'pending' as const, order_index: 0 } as any); @@ -827,7 +827,7 @@ export async function submitRideCreation( submission_id: submissionData.id, item_type: 'ride', action_type: 'create', - item_data_id: (rideSubmission as any).id, + ride_submission_id: (rideSubmission as any).id, status: 'pending' as const, order_index: 0 } as any); diff --git a/src/lib/moderation/validation.ts b/src/lib/moderation/validation.ts index f20f9426..7f322f94 100644 --- a/src/lib/moderation/validation.ts +++ b/src/lib/moderation/validation.ts @@ -29,7 +29,13 @@ const SubmissionItemSchema = z.object({ status: z.string(), item_type: z.string().optional(), item_data: z.record(z.string(), z.any()).optional().nullable(), - item_data_id: z.string().uuid().optional().nullable(), + // Typed FK columns (optional, only one will be populated) + park_submission_id: z.string().uuid().optional().nullable(), + ride_submission_id: z.string().uuid().optional().nullable(), + photo_submission_id: z.string().uuid().optional().nullable(), + company_submission_id: z.string().uuid().optional().nullable(), + ride_model_submission_id: z.string().uuid().optional().nullable(), + timeline_event_submission_id: z.string().uuid().optional().nullable(), action_type: z.enum(['create', 'edit', 'delete']).optional(), original_data: z.record(z.string(), z.any()).optional().nullable(), error_message: z.string().optional().nullable(), diff --git a/src/lib/submissionItemsService.ts b/src/lib/submissionItemsService.ts index 2b3746a0..2daaaedc 100644 --- a/src/lib/submissionItemsService.ts +++ b/src/lib/submissionItemsService.ts @@ -60,9 +60,9 @@ export async function fetchSubmissionItems(submissionId: string): Promise