import React, { useState, useCallback } from 'react'; import { apiCall } from '../utils/api'; import { FALLBACK_TRIGGER_REVIEW, FALLBACK_TRIGGER_PRODUCT, FALLBACK_TRIGGER_TRANSACTION } from '../constants/fallbacks'; const ENTITIES = [ { id: 'review', label: 'Customer Review' }, { id: 'product', label: 'Product' }, { id: 'transaction', label: 'Transaction' }, ]; const ENTITY_STEPS = { review: [ { label: 'BEGIN TRANSACTION', sub: 'INSERT INTO reviews (text, customer_id) executing...', color: 'var(--text)' }, { label: 'TRIGGER: ai_sentiment_analyzer FIRES', sub: 'DistilBERT sentiment analysis (confidence, label)', color: 'var(--amber)' }, { label: 'TRIGGER: ai_embedder FIRES', sub: 'text-embedding-3-small generating 1536-dim vector', color: 'var(--purple-l)' }, { label: 'TRIGGER: fulltext_indexer FIRES', sub: 'tsvector lexeme array updated for hybrid search', color: 'var(--teal)' }, { label: 'COMMIT', sub: 'ACID transaction finalized successfully ✓', color: 'var(--green)' }, ], product: [ { label: 'BEGIN TRANSACTION', sub: 'INSERT INTO products (name, description) executing...', color: 'var(--text)' }, { label: 'TRIGGER: ai_product_classifier FIRES', sub: 'LLM classification for categories, subcategories, tags', color: 'var(--amber)' }, { label: 'TRIGGER: ai_embedder FIRES', sub: 'Generating product vector representation', color: 'var(--purple-l)' }, { label: 'COMMIT', sub: 'Product catalog entry committed successfully ✓', color: 'var(--green)' }, ], transaction: [ { label: 'BEGIN TRANSACTION', sub: 'INSERT INTO transactions (amount, customer_id, merchant, location) executing...', color: 'var(--text)' }, { label: 'TRIGGER: xgboost_fraud_scorer FIRES', sub: 'Running live XGBoost Classifier inference on server...', color: 'var(--purple-l)' }, { label: 'TRIGGER: shap_tree_explainer FIRES', sub: 'SHAP TreeExplainer calculating local feature attribution...', color: 'var(--amber)' }, { label: 'COMMIT', sub: 'Transaction authorized or flagged, details logged ✓', color: 'var(--green)' }, ], }; export default function TriggerSim() { const [entity, setEntity] = useState('review'); const [reviewText, setReviewText] = useState('The battery on this product died completely after 11 days. Customer support never responded to my emails.'); const [productName, setProductName] = useState('WirelessPro X5 Headphones'); const [productDesc, setProductDesc] = useState('Premium over-ear headphones with 40hr battery, active noise cancellation, and multi-device connectivity.'); const [txAmount, setTxAmount] = useState('4821.50'); const [txCustomer, setTxCustomer] = useState('cust_0044 (avg spend $89)'); const [txMerchant, setTxMerchant] = useState('Electronics Store'); const [txLocation, setTxLocation] = useState('Lagos, NG'); const [loading, setLoading] = useState(false); const [currentStep, setCurrentStep] = useState(-1); const [result, setResult] = useState(null); const [usedFallback, setUsedFallback] = useState(false); const [showRawRow, setShowRawRow] = useState(false); const [retraining, setRetraining] = useState(false); const [retrainSuccess, setRetrainSuccess] = useState(false); const handleRetrain = useCallback(async () => { setRetraining(true); setRetrainSuccess(false); try { const res = await apiCall('/api/demo/retrain', {}, { timeout: 30000 }); if (res.success) { setRetrainSuccess(true); setResult(prev => { if (!prev) return null; return { ...prev, model_version: res.new_version || "XGBoost-v1.1-SelfHealed", drift_result: { drift_detected: false, ks_p_value: 1.0, message: "Statistical distribution has been recalibrated. System status: STABLE" } }; }); } } catch (err) { console.error("Retraining failed", err); } finally { setRetraining(false); } }, []); const handleInsert = useCallback(async () => { setLoading(true); setCurrentStep(0); setResult(null); setUsedFallback(false); setShowRawRow(false); setRetrainSuccess(false); // Animate steps const steps = ENTITY_STEPS[entity]; for (let i = 0; i < steps.length; i++) { await new Promise((r) => setTimeout(r, 600)); setCurrentStep(i); } try { let payload = { entity_type: entity }; if (entity === 'review') payload.text = reviewText; else if (entity === 'product') { payload.product_name = productName; payload.product_description = productDesc; } else { payload.amount = parseFloat(txAmount) || 0; payload.customer_id = txCustomer; payload.merchant = txMerchant; payload.location = txLocation; } const res = await apiCall('/api/demo/trigger', payload, { timeout: 30000 }); if (res.ok && res.data) { setResult(res.data); } else { throw new Error(res.error || 'Failed'); } } catch { setUsedFallback(true); if (entity === 'review') setResult(FALLBACK_TRIGGER_REVIEW); else if (entity === 'product') setResult(FALLBACK_TRIGGER_PRODUCT); else setResult(FALLBACK_TRIGGER_TRANSACTION); } finally { setLoading(false); } }, [entity, reviewText, productName, productDesc, txAmount, txCustomer, txMerchant, txLocation]); return (

Simulate a database INSERT and watch three AI models fire automatically inside PostgreSQL trigger functions — in a single ACID transaction.

{/* Entity selector */}
{ENTITIES.map((e) => ( ))}
{/* Input area */} {entity === 'review' && (