Fix Retry flashing and dependency validation

This commit is contained in:
gpt-engineer-app[bot]
2025-10-09 17:55:58 +00:00
parent a1953b8557
commit 88bcb00157
2 changed files with 79 additions and 8 deletions

View File

@@ -776,6 +776,22 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
const handleRetryFailedItems = async (item: ModerationItem) => { const handleRetryFailedItems = async (item: ModerationItem) => {
setActionLoading(item.id); setActionLoading(item.id);
// Optimistic UI update - remove from queue immediately
const shouldRemove = (
activeStatusFilter === 'pending' ||
activeStatusFilter === 'flagged' ||
activeStatusFilter === 'partially_approved'
);
if (shouldRemove) {
requestAnimationFrame(() => {
setItems(prev => prev.filter(i => i.id !== item.id));
recentlyRemovedRef.current.add(item.id);
setTimeout(() => recentlyRemovedRef.current.delete(item.id), 3000);
});
}
try { try {
// Fetch failed/rejected submission items // Fetch failed/rejected submission items
const { data: failedItems, error: fetchError } = await supabase const { data: failedItems, error: fetchError } = await supabase
@@ -812,7 +828,6 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
description: `Processed ${failedItems.length} failed item(s)`, description: `Processed ${failedItems.length} failed item(s)`,
}); });
// No refresh needed - item already updated optimistically
} catch (error: any) { } catch (error: any) {
console.error('Error retrying failed items:', error); console.error('Error retrying failed items:', error);
toast({ toast({

View File

@@ -197,6 +197,7 @@ serve(async (req) => {
itemType: string; itemType: string;
success: boolean; success: boolean;
error?: string; error?: string;
isDependencyFailure?: boolean;
}> = []; }> = [];
// Process items in order // Process items in order
@@ -285,23 +286,71 @@ serve(async (req) => {
console.log(`Successfully approved item ${item.id} -> entity ${entityId}`); console.log(`Successfully approved item ${item.id} -> entity ${entityId}`);
} catch (error) { } catch (error) {
console.error(`Error processing item ${item.id}:`, error); console.error(`Error processing item ${item.id}:`, error);
const isDependencyError = error instanceof Error && (
error.message.includes('Missing dependency') ||
error.message.includes('depends on') ||
error.message.includes('Circular dependency')
);
approvalResults.push({ approvalResults.push({
itemId: item.id, itemId: item.id,
itemType: item.item_type, itemType: item.item_type,
success: false, success: false,
error: error instanceof Error ? error.message : 'Unknown error' error: error instanceof Error ? error.message : 'Unknown error',
isDependencyFailure: isDependencyError
}); });
// Mark item as rejected in submission_items
const { error: markRejectedError } = await supabase
.from('submission_items')
.update({
status: 'rejected',
rejection_reason: error instanceof Error ? error.message : 'Unknown error',
updated_at: new Date().toISOString()
})
.eq('id', item.id);
if (markRejectedError) {
console.error(`Failed to mark item ${item.id} as rejected:`, markRejectedError);
}
} }
} }
// Update submission status // Check if any failures were dependency-related
const hasDependencyFailure = approvalResults.some(r =>
!r.success && r.isDependencyFailure
);
const allApproved = approvalResults.every(r => r.success); const allApproved = approvalResults.every(r => r.success);
const someApproved = approvalResults.some(r => r.success);
const allFailed = approvalResults.every(r => !r.success);
// Determine final status:
// - If dependency validation failed: keep pending for escalation
// - If all approved: approved
// - If some approved: partially_approved
// - If all failed but no dependency issues: rejected (can retry)
const finalStatus = hasDependencyFailure && !someApproved
? 'pending' // Keep pending for escalation only
: allApproved
? 'approved'
: allFailed
? 'rejected' // Total failure, allow retry
: 'partially_approved'; // Mixed results
const reviewerNotes = hasDependencyFailure && !someApproved
? 'Submission has unresolved dependencies. Escalation required.'
: undefined;
const { error: updateError } = await supabase const { error: updateError } = await supabase
.from('content_submissions') .from('content_submissions')
.update({ .update({
status: allApproved ? 'approved' : 'partially_approved', status: finalStatus,
reviewer_id: authenticatedUserId, reviewer_id: authenticatedUserId,
reviewed_at: new Date().toISOString() reviewed_at: new Date().toISOString(),
reviewer_notes: reviewerNotes,
escalated: hasDependencyFailure && !someApproved ? true : undefined
}) })
.eq('id', submissionId); .eq('id', submissionId);
@@ -313,7 +362,7 @@ serve(async (req) => {
JSON.stringify({ JSON.stringify({
success: true, success: true,
results: approvalResults, results: approvalResults,
submissionStatus: allApproved ? 'approved' : 'partially_approved' submissionStatus: finalStatus
}), }),
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } } { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
); );
@@ -335,7 +384,10 @@ function topologicalSort(items: any[]): any[] {
const visit = (item: any) => { const visit = (item: any) => {
if (visited.has(item.id)) return; if (visited.has(item.id)) return;
if (visiting.has(item.id)) { if (visiting.has(item.id)) {
throw new Error(`Circular dependency detected for item ${item.id}`); throw new Error(
`Circular dependency detected: item ${item.id} (${item.item_type}) ` +
`creates a dependency loop. This submission requires escalation.`
);
} }
visiting.add(item.id); visiting.add(item.id);
@@ -343,7 +395,11 @@ function topologicalSort(items: any[]): any[] {
if (item.depends_on) { if (item.depends_on) {
const parent = items.find(i => i.id === item.depends_on); const parent = items.find(i => i.id === item.depends_on);
if (!parent) { if (!parent) {
throw new Error(`Missing dependency: item ${item.id} depends on ${item.depends_on} which is not in the submission`); throw new Error(
`Missing dependency: item ${item.id} (${item.item_type}) ` +
`depends on ${item.depends_on} which is not in this submission or has not been approved. ` +
`This submission requires escalation.`
);
} }
visit(parent); visit(parent);
} }