mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-28 00:07:16 -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)
|
||||
*/
|
||||
export function ApprovalTransactionToggle() {
|
||||
const [useRpcApproval, setUseRpcApproval] = useState(false);
|
||||
const [useRpcApproval, setUseRpcApproval] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Read feature flag from localStorage
|
||||
const enabled = localStorage.getItem('use_rpc_approval') === 'true';
|
||||
// NEW flow is default (100% rollout)
|
||||
// Only disabled if explicitly set to 'false'
|
||||
const enabled = localStorage.getItem('use_rpc_approval') !== 'false';
|
||||
setUseRpcApproval(enabled);
|
||||
}, []);
|
||||
|
||||
@@ -35,7 +36,7 @@ export function ApprovalTransactionToggle() {
|
||||
Approval Transaction Mode
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Control which approval flow is used for moderation
|
||||
Atomic Transaction RPC is now the default. Toggle OFF only for emergency rollback.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
@@ -56,10 +57,10 @@ export function ApprovalTransactionToggle() {
|
||||
</div>
|
||||
|
||||
{useRpcApproval ? (
|
||||
<Alert>
|
||||
<CheckCircle2 className="h-4 w-4" />
|
||||
<Alert className="border-green-500 bg-green-50 dark:bg-green-950">
|
||||
<CheckCircle2 className="h-4 w-4 text-green-600" />
|
||||
<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">
|
||||
<li>✅ True ACID transactions</li>
|
||||
<li>✅ Automatic rollback on errors</li>
|
||||
@@ -69,17 +70,17 @@ export function ApprovalTransactionToggle() {
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
) : (
|
||||
<Alert>
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<Alert className="border-orange-500 bg-orange-50 dark:bg-orange-950">
|
||||
<AlertCircle className="h-4 w-4 text-orange-600" />
|
||||
<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">
|
||||
<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>⚠️ No true atomicity guarantee</li>
|
||||
</ul>
|
||||
<p className="mt-2 font-medium">
|
||||
Consider enabling Atomic Transaction Mode for improved reliability.
|
||||
<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>
|
||||
|
||||
@@ -178,9 +178,9 @@ export async function approvePhotoSubmission(
|
||||
* @returns Action result
|
||||
*/
|
||||
/**
|
||||
* Feature flag to enable atomic transaction RPC approval flow.
|
||||
* Set to true to use the new process-selective-approval-v2 edge function
|
||||
* that wraps the entire approval in a single PostgreSQL transaction.
|
||||
* Feature flag: Use new atomic transaction RPC for approvals (v2)
|
||||
*
|
||||
* ✅ DEFAULT: NEW atomic transaction flow (100% ROLLOUT)
|
||||
*
|
||||
* Benefits of v2:
|
||||
* - True atomic transactions (all-or-nothing)
|
||||
@@ -188,11 +188,11 @@ export async function approvePhotoSubmission(
|
||||
* - Network-resilient (edge function crash = auto rollback)
|
||||
* - Eliminates orphaned entities
|
||||
*
|
||||
* To enable: localStorage.setItem('use_rpc_approval', 'true')
|
||||
* To disable: localStorage.setItem('use_rpc_approval', 'false')
|
||||
* To disable NEW flow (emergency rollback): localStorage.setItem('use_rpc_approval', 'false')
|
||||
* To re-enable NEW flow: localStorage.removeItem('use_rpc_approval')
|
||||
*/
|
||||
const USE_RPC_APPROVAL = typeof window !== 'undefined' &&
|
||||
localStorage.getItem('use_rpc_approval') === 'true';
|
||||
localStorage.getItem('use_rpc_approval') !== 'false';
|
||||
|
||||
export async function approveSubmissionItems(
|
||||
supabase: SupabaseClient,
|
||||
|
||||
@@ -14,6 +14,7 @@ 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';
|
||||
|
||||
@@ -915,29 +916,33 @@ export default function AdminSettings() {
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="system">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Settings className="w-5 h-5" />
|
||||
System Configuration
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Configure system-wide settings, maintenance options, and technical parameters
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{getSettingsByCategory('system').filter(s => !s.setting_key.startsWith('retry.') && !s.setting_key.startsWith('circuit_breaker.')).length > 0 ? (
|
||||
getSettingsByCategory('system').filter(s => !s.setting_key.startsWith('retry.') && !s.setting_key.startsWith('circuit_breaker.')).map((setting) => (
|
||||
<SettingInput key={setting.id} setting={setting} />
|
||||
))
|
||||
) : (
|
||||
<div className="text-center py-8 text-muted-foreground">
|
||||
<Settings className="w-12 h-12 mx-auto mb-4 opacity-50" />
|
||||
<p>No system settings configured yet.</p>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Settings className="w-5 h-5" />
|
||||
System Configuration
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Configure system-wide settings, maintenance options, and technical parameters
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{getSettingsByCategory('system').filter(s => !s.setting_key.startsWith('retry.') && !s.setting_key.startsWith('circuit_breaker.')).length > 0 ? (
|
||||
getSettingsByCategory('system').filter(s => !s.setting_key.startsWith('retry.') && !s.setting_key.startsWith('circuit_breaker.')).map((setting) => (
|
||||
<SettingInput key={setting.id} setting={setting} />
|
||||
))
|
||||
) : (
|
||||
<div className="text-center py-8 text-muted-foreground">
|
||||
<Settings className="w-12 h-12 mx-auto mb-4 opacity-50" />
|
||||
<p>No system settings configured yet.</p>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<ApprovalTransactionToggle />
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="integrations">
|
||||
|
||||
Reference in New Issue
Block a user