Remove old approval flow

Implement the destructive migration plan to remove the old approval flow entirely. This includes deleting the legacy edge function, removing the toggle component, simplifying frontend code, and updating documentation.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-06 21:14:59 +00:00
parent 406edc96df
commit bd2f9a5a9e
8 changed files with 197 additions and 3124 deletions

View File

@@ -1,101 +0,0 @@
import { useState, useEffect } from 'react';
import { Switch } from '@/components/ui/switch';
import { Label } from '@/components/ui/label';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { AlertCircle, CheckCircle2, Database } from 'lucide-react';
import { Alert, AlertDescription } from '@/components/ui/alert';
/**
* Admin toggle for switching between approval flows:
* - OLD: Manual rollback in edge function (error-prone)
* - NEW: Atomic PostgreSQL transaction (true ACID guarantees)
*/
export function ApprovalTransactionToggle() {
const [useRpcApproval, setUseRpcApproval] = useState(true);
useEffect(() => {
// NEW flow is default (100% rollout)
// Only disabled if explicitly set to 'false'
const enabled = localStorage.getItem('use_rpc_approval') !== 'false';
setUseRpcApproval(enabled);
}, []);
const handleToggle = (checked: boolean) => {
localStorage.setItem('use_rpc_approval', checked ? 'true' : 'false');
setUseRpcApproval(checked);
// Force page reload to ensure all components pick up the new setting
window.location.reload();
};
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Database className="w-5 h-5" />
Approval Transaction Mode
</CardTitle>
<CardDescription>
Atomic Transaction RPC is now the default. Toggle OFF only for emergency rollback.
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="rpc-approval-toggle" className="flex-1">
<div className="font-medium">Use Atomic Transaction RPC</div>
<div className="text-sm text-muted-foreground">
{useRpcApproval
? 'Using process-selective-approval-v2 (NEW)'
: 'Using process-selective-approval (OLD)'}
</div>
</Label>
<Switch
id="rpc-approval-toggle"
checked={useRpcApproval}
onCheckedChange={handleToggle}
/>
</div>
{useRpcApproval ? (
<Alert className="border-green-500 bg-green-50 dark:bg-green-950">
<CheckCircle2 className="h-4 w-4 text-green-600" />
<AlertDescription>
<strong className="text-green-600">Production Mode (100% Rollout) </strong>
<ul className="mt-2 space-y-1 text-sm">
<li> True ACID transactions</li>
<li> Automatic rollback on errors</li>
<li> Network-resilient (edge function crash = auto rollback)</li>
<li> Zero orphaned entities</li>
</ul>
</AlertDescription>
</Alert>
) : (
<Alert className="border-orange-500 bg-orange-50 dark:bg-orange-950">
<AlertCircle className="h-4 w-4 text-orange-600" />
<AlertDescription>
<strong className="text-orange-600">Emergency Rollback Mode Active </strong>
<ul className="mt-2 space-y-1 text-sm">
<li> Using legacy manual rollback logic</li>
<li> Risk of orphaned entities if edge function crashes</li>
<li> No true atomicity guarantee</li>
</ul>
<p className="mt-2 font-medium text-orange-600">
This mode should only be used temporarily if issues are detected with the atomic transaction flow.
</p>
</AlertDescription>
</Alert>
)}
<div className="text-xs text-muted-foreground pt-2 border-t">
<p><strong>Testing Instructions:</strong></p>
<ol className="list-decimal list-inside space-y-1 mt-1">
<li>Enable the toggle and approve a submission</li>
<li>Check logs for "Using edge function: process-selective-approval-v2"</li>
<li>Verify no orphaned entities in the database</li>
<li>Test error scenarios (invalid data, network issues)</li>
</ol>
</div>
</CardContent>
</Card>
);
}

View File

@@ -178,41 +178,31 @@ export async function approvePhotoSubmission(
* @returns Action result
*/
/**
* Feature flag: Use new atomic transaction RPC for approvals (v2)
* Approve submission items using atomic transaction RPC.
*
* ✅ DEFAULT: NEW atomic transaction flow (100% ROLLOUT)
* This function uses PostgreSQL's ACID transaction guarantees to ensure
* all-or-nothing approval with automatic rollback on any error.
*
* Benefits of v2:
* The approval process is handled entirely within a single database transaction
* via the process_approval_transaction() RPC function, which guarantees:
* - True atomic transactions (all-or-nothing)
* - Automatic rollback on ANY error
* - Network-resilient (edge function crash = auto rollback)
* - Eliminates orphaned entities
*
* To disable NEW flow (emergency rollback): localStorage.setItem('use_rpc_approval', 'false')
* To re-enable NEW flow: localStorage.removeItem('use_rpc_approval')
* - Zero orphaned entities
*/
const USE_RPC_APPROVAL = typeof window !== 'undefined' &&
localStorage.getItem('use_rpc_approval') !== 'false';
export async function approveSubmissionItems(
supabase: SupabaseClient,
submissionId: string,
itemIds: string[]
): Promise<ModerationActionResult> {
try {
// Use v2 edge function if feature flag is enabled
const edgeFunctionName = USE_RPC_APPROVAL
? 'process-selective-approval-v2'
: 'process-selective-approval';
console.log(`[Approval] Using edge function: ${edgeFunctionName}`, {
console.log(`[Approval] Processing ${itemIds.length} items via atomic transaction`, {
submissionId,
itemCount: itemIds.length,
useRpcApproval: USE_RPC_APPROVAL
itemCount: itemIds.length
});
const { data: approvalData, error: approvalError, requestId } = await invokeWithTracking(
edgeFunctionName,
'process-selective-approval',
{
itemIds,
submissionId,

View File

@@ -14,7 +14,6 @@ import { useAdminSettings } from '@/hooks/useAdminSettings';
import { NovuMigrationUtility } from '@/components/admin/NovuMigrationUtility';
import { TestDataGenerator } from '@/components/admin/TestDataGenerator';
import { IntegrationTestRunner } from '@/components/admin/IntegrationTestRunner';
import { ApprovalTransactionToggle } from '@/components/admin/ApprovalTransactionToggle';
import { Loader2, Save, Clock, Users, Bell, Shield, Settings, Trash2, Plug, AlertTriangle, Lock, TestTube, RefreshCw, Info, AlertCircle } from 'lucide-react';
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
@@ -940,8 +939,6 @@ export default function AdminSettings() {
)}
</CardContent>
</Card>
<ApprovalTransactionToggle />
</div>
</TabsContent>