mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-28 02:07:04 -05:00
Compare commits
2 Commits
67525173cb
...
406edc96df
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
406edc96df | ||
|
|
3be551dc5a |
@@ -11,11 +11,12 @@ import { Alert, AlertDescription } from '@/components/ui/alert';
|
|||||||
* - NEW: Atomic PostgreSQL transaction (true ACID guarantees)
|
* - NEW: Atomic PostgreSQL transaction (true ACID guarantees)
|
||||||
*/
|
*/
|
||||||
export function ApprovalTransactionToggle() {
|
export function ApprovalTransactionToggle() {
|
||||||
const [useRpcApproval, setUseRpcApproval] = useState(false);
|
const [useRpcApproval, setUseRpcApproval] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Read feature flag from localStorage
|
// NEW flow is default (100% rollout)
|
||||||
const enabled = localStorage.getItem('use_rpc_approval') === 'true';
|
// Only disabled if explicitly set to 'false'
|
||||||
|
const enabled = localStorage.getItem('use_rpc_approval') !== 'false';
|
||||||
setUseRpcApproval(enabled);
|
setUseRpcApproval(enabled);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ export function ApprovalTransactionToggle() {
|
|||||||
Approval Transaction Mode
|
Approval Transaction Mode
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Control which approval flow is used for moderation
|
Atomic Transaction RPC is now the default. Toggle OFF only for emergency rollback.
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4">
|
||||||
@@ -56,10 +57,10 @@ export function ApprovalTransactionToggle() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{useRpcApproval ? (
|
{useRpcApproval ? (
|
||||||
<Alert>
|
<Alert className="border-green-500 bg-green-50 dark:bg-green-950">
|
||||||
<CheckCircle2 className="h-4 w-4" />
|
<CheckCircle2 className="h-4 w-4 text-green-600" />
|
||||||
<AlertDescription>
|
<AlertDescription>
|
||||||
<strong>Atomic Transaction Mode Enabled</strong>
|
<strong className="text-green-600">Production Mode (100% Rollout) ✓</strong>
|
||||||
<ul className="mt-2 space-y-1 text-sm">
|
<ul className="mt-2 space-y-1 text-sm">
|
||||||
<li>✅ True ACID transactions</li>
|
<li>✅ True ACID transactions</li>
|
||||||
<li>✅ Automatic rollback on errors</li>
|
<li>✅ Automatic rollback on errors</li>
|
||||||
@@ -69,17 +70,17 @@ export function ApprovalTransactionToggle() {
|
|||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
) : (
|
) : (
|
||||||
<Alert>
|
<Alert className="border-orange-500 bg-orange-50 dark:bg-orange-950">
|
||||||
<AlertCircle className="h-4 w-4" />
|
<AlertCircle className="h-4 w-4 text-orange-600" />
|
||||||
<AlertDescription>
|
<AlertDescription>
|
||||||
<strong>Legacy Mode Active</strong>
|
<strong className="text-orange-600">Emergency Rollback Mode Active ⚠️</strong>
|
||||||
<ul className="mt-2 space-y-1 text-sm">
|
<ul className="mt-2 space-y-1 text-sm">
|
||||||
<li>⚠️ Manual rollback logic (error-prone)</li>
|
<li>⚠️ Using legacy manual rollback logic</li>
|
||||||
<li>⚠️ Risk of orphaned entities if edge function crashes</li>
|
<li>⚠️ Risk of orphaned entities if edge function crashes</li>
|
||||||
<li>⚠️ No true atomicity guarantee</li>
|
<li>⚠️ No true atomicity guarantee</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p className="mt-2 font-medium">
|
<p className="mt-2 font-medium text-orange-600">
|
||||||
Consider enabling Atomic Transaction Mode for improved reliability.
|
This mode should only be used temporarily if issues are detected with the atomic transaction flow.
|
||||||
</p>
|
</p>
|
||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|||||||
@@ -178,9 +178,9 @@ export async function approvePhotoSubmission(
|
|||||||
* @returns Action result
|
* @returns Action result
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Feature flag to enable atomic transaction RPC approval flow.
|
* Feature flag: Use new atomic transaction RPC for approvals (v2)
|
||||||
* Set to true to use the new process-selective-approval-v2 edge function
|
*
|
||||||
* that wraps the entire approval in a single PostgreSQL transaction.
|
* ✅ DEFAULT: NEW atomic transaction flow (100% ROLLOUT)
|
||||||
*
|
*
|
||||||
* Benefits of v2:
|
* Benefits of v2:
|
||||||
* - True atomic transactions (all-or-nothing)
|
* - True atomic transactions (all-or-nothing)
|
||||||
@@ -188,11 +188,11 @@ export async function approvePhotoSubmission(
|
|||||||
* - Network-resilient (edge function crash = auto rollback)
|
* - Network-resilient (edge function crash = auto rollback)
|
||||||
* - Eliminates orphaned entities
|
* - Eliminates orphaned entities
|
||||||
*
|
*
|
||||||
* To enable: localStorage.setItem('use_rpc_approval', 'true')
|
* To disable NEW flow (emergency rollback): localStorage.setItem('use_rpc_approval', 'false')
|
||||||
* To disable: localStorage.setItem('use_rpc_approval', 'false')
|
* To re-enable NEW flow: localStorage.removeItem('use_rpc_approval')
|
||||||
*/
|
*/
|
||||||
const USE_RPC_APPROVAL = typeof window !== 'undefined' &&
|
const USE_RPC_APPROVAL = typeof window !== 'undefined' &&
|
||||||
localStorage.getItem('use_rpc_approval') === 'true';
|
localStorage.getItem('use_rpc_approval') !== 'false';
|
||||||
|
|
||||||
export async function approveSubmissionItems(
|
export async function approveSubmissionItems(
|
||||||
supabase: SupabaseClient,
|
supabase: SupabaseClient,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { useAdminSettings } from '@/hooks/useAdminSettings';
|
|||||||
import { NovuMigrationUtility } from '@/components/admin/NovuMigrationUtility';
|
import { NovuMigrationUtility } from '@/components/admin/NovuMigrationUtility';
|
||||||
import { TestDataGenerator } from '@/components/admin/TestDataGenerator';
|
import { TestDataGenerator } from '@/components/admin/TestDataGenerator';
|
||||||
import { IntegrationTestRunner } from '@/components/admin/IntegrationTestRunner';
|
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 { Loader2, Save, Clock, Users, Bell, Shield, Settings, Trash2, Plug, AlertTriangle, Lock, TestTube, RefreshCw, Info, AlertCircle } from 'lucide-react';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
|
||||||
@@ -915,6 +916,7 @@ export default function AdminSettings() {
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="system">
|
<TabsContent value="system">
|
||||||
|
<div className="space-y-4">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2">
|
<CardTitle className="flex items-center gap-2">
|
||||||
@@ -938,6 +940,9 @@ export default function AdminSettings() {
|
|||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
<ApprovalTransactionToggle />
|
||||||
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="integrations">
|
<TabsContent value="integrations">
|
||||||
|
|||||||
Reference in New Issue
Block a user