From c74a41c2e3eced4d13cb6e51e1d80a7d0e2eda22 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 23:04:08 +0000 Subject: [PATCH] Fix: Add validation blocking to main queue approval --- src/hooks/moderation/useModerationActions.ts | 59 ++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/hooks/moderation/useModerationActions.ts b/src/hooks/moderation/useModerationActions.ts index 1b84bf0f..a4907be0 100644 --- a/src/hooks/moderation/useModerationActions.ts +++ b/src/hooks/moderation/useModerationActions.ts @@ -3,6 +3,7 @@ import { supabase } from '@/integrations/supabase/client'; import { useToast } from '@/hooks/use-toast'; import { logger } from '@/lib/logger'; import { getErrorMessage } from '@/lib/errorHandler'; +import { validateMultipleItems } from '@/lib/entityValidationSchemas'; import type { User } from '@supabase/supabase-js'; import type { ModerationItem } from '@/types/moderation'; @@ -123,6 +124,64 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio if (submissionItems && submissionItems.length > 0) { if (action === 'approved') { + // Fetch full item data for validation + const { data: fullItems, error: itemError } = await supabase + .from('submission_items') + .select('id, item_type, item_data') + .eq('submission_id', item.id) + .in('status', ['pending', 'rejected']); + + if (itemError) { + throw new Error(`Failed to fetch submission items: ${itemError.message}`); + } + + if (fullItems && fullItems.length > 0) { + // Run validation on all items + const validationResults = await validateMultipleItems( + fullItems.map(item => ({ + item_type: item.item_type, + item_data: item.item_data, + id: item.id + })) + ); + + // Check for blocking errors + const itemsWithBlockingErrors = fullItems.filter(item => { + const result = validationResults.get(item.id); + return result && result.blockingErrors.length > 0; + }); + + // CRITICAL: Block approval if any item has blocking errors + if (itemsWithBlockingErrors.length > 0) { + const errorDetails = itemsWithBlockingErrors.map(item => { + const result = validationResults.get(item.id); + return `${item.item_type}: ${result?.blockingErrors[0]?.message || 'Unknown error'}`; + }).join(', '); + + toast({ + title: 'Cannot Approve - Validation Errors', + description: `${itemsWithBlockingErrors.length} item(s) have blocking errors that must be fixed first. ${errorDetails}`, + variant: 'destructive', + }); + + // Return early - do NOT proceed with approval + return; + } + + // Check for warnings (optional - can proceed but inform user) + const itemsWithWarnings = fullItems.filter(item => { + const result = validationResults.get(item.id); + return result && result.warnings.length > 0; + }); + + if (itemsWithWarnings.length > 0) { + logger.info('Approval proceeding with warnings', { + submissionId: item.id, + warningCount: itemsWithWarnings.length + }); + } + } + await supabase.functions.invoke('process-selective-approval', { body: { itemIds: submissionItems.map((i) => i.id),