exec('SET search_path TO admin, public'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db_ok = true; } catch (PDOException $e) { echo json_encode(['error' => 'DB: ' . $e->getMessage()]); exit; } $action = $_GET['action'] ?? $_POST['action'] ?? 'stats'; $service = basename($_SERVER['SCRIPT_FILENAME'], '.php'); // ═══ CORRECT TABLE MAPPING (real tables, verified) ═══ $MAP = [ 'sms-engine' => ['table'=>'sms_campaigns', 'status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>'sent', 'label'=>'SMS Campaigns'], 'sms-templates' => ['table'=>'email_templates', 'status_col'=>null, 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Templates'], 'send-factory' => ['table'=>'unified_send_log_new','status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Send Log'], 'send-orchestrator' => ['table'=>'unified_send_log_new','status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Send Orchestrator'], 'phone-generator' => ['table'=>'phone_numbers', 'status_col'=>'is_active', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Phone Numbers'], 'temp-email' => ['table'=>'temp_emails', 'status_col'=>'is_active', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Temp Emails'], 'captcha-solver' => ['table'=>'sms_providers', 'status_col'=>'is_active', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Captcha/Providers'], 'seed-cleaner' => ['table'=>'seed_accounts', 'status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>'inbox_count','label'=>'Seed Accounts'], 'self-healing' => ['table'=>'sentinel_knowledge', 'status_col'=>null, 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Self Healing'], 'ai-copywriter' => ['table'=>'creative_templates', 'status_col'=>null, 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'AI Copywriter'], 'fingerprint-sync' => ['table'=>'personas', 'status_col'=>null, 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Fingerprints'], 'lookalike-engine' => ['table'=>'hamid_personas', 'status_col'=>null, 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Lookalike'], 'pattern-shuffler' => ['table'=>'brain_send_configs', 'status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>'total_sent', 'label'=>'Pattern Shuffler'], 'neural-dom-mutator'=> ['table'=>'brain_send_configs', 'status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'DOM Mutator'], 'scrapping-factory' => ['table'=>'scrapping_results', 'status_col'=>'is_verified','date_col'=>'extracted_at','count_col'=>null, 'label'=>'Scraping'], 'harvest-manager' => ['table'=>'harvest_results', 'status_col'=>null, 'date_col'=>'harvested_at','count_col'=>'emails_found','label'=>'Harvest'], 'trap-detector' => ['table'=>'brain_seeds', 'status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'Trap Detector'], 'account-creator' => ['table'=>'office_accounts', 'status_col'=>'status', 'date_col'=>'created_date','count_col'=>null, 'label'=>'O365 Accounts'], 'data-manager' => ['table'=>'send_data', 'status_col'=>null, 'date_col'=>'created_at', 'count_col'=>'total_sent', 'label'=>'Data Manager'], 'world-map' => ['table'=>'unified_send_log_new','status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'World Map'], 'offer-engine' => ['table'=>'offers', 'status_col'=>'status', 'date_col'=>null, 'count_col'=>'payout', 'label'=>'Offers'], 'bpms-command-center'=>['table'=>'campaigns', 'status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>'total_sent', 'label'=>'BPMS'], 'cvc-vault' => ['table'=>'personas', 'status_col'=>null, 'date_col'=>'created_at', 'count_col'=>null, 'label'=>'CVC Vault'], 'reputation' => ['table'=>'brain_send_configs', 'status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>'inbox_rate', 'label'=>'Reputation'], ]; $cfg = $MAP[$service] ?? ['table'=>'unified_send_log_new', 'status_col'=>'status', 'date_col'=>'created_at', 'count_col'=>null, 'label'=>$service]; $tbl = $cfg['table']; $scol = $cfg['status_col']; $dcol = $cfg['date_col']; $ccol = $cfg['count_col']; // Check table exists $exists = false; try { $exists = $pdo->query("SELECT EXISTS(SELECT 1 FROM information_schema.tables WHERE table_schema='admin' AND table_name='{$tbl}')")->fetchColumn(); } catch (Exception $e) {} switch ($action) { case 'stats': if (!$exists) { echo json_encode(['status'=>'success','data'=>['total'=>0,'note'=>"Table {$tbl} not found"],'service'=>$service,'label'=>$cfg['label']]); exit; } $data = ['total' => (int)$pdo->query("SELECT COUNT(*) FROM admin.{$tbl}")->fetchColumn()]; if ($scol) { try { $rows = $pdo->query("SELECT {$scol} as s, COUNT(*) as c FROM admin.{$tbl} GROUP BY {$scol} ORDER BY c DESC LIMIT 10")->fetchAll(PDO::FETCH_ASSOC); $data['by_status'] = $rows; foreach ($rows as $r) { $key = strtolower(str_replace(' ', '_', $r['s'] ?? 'null')); $data[$key] = (int)$r['c']; } } catch (Exception $e) {} } if ($dcol) { try { $data['today'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.{$tbl} WHERE {$dcol} >= CURRENT_DATE")->fetchColumn(); $data['last_7d'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.{$tbl} WHERE {$dcol} >= CURRENT_DATE - INTERVAL '7 days'")->fetchColumn(); $data['latest'] = $pdo->query("SELECT MAX({$dcol}) FROM admin.{$tbl}")->fetchColumn(); } catch (Exception $e) {} } if ($ccol) { try { $agg = $pdo->query("SELECT SUM({$ccol}) as total_sum, AVG({$ccol})::numeric(10,2) as avg_val, MAX({$ccol}) as max_val FROM admin.{$tbl}")->fetch(PDO::FETCH_ASSOC); $data['sum_' . $ccol] = $agg['total_sum']; $data['avg_' . $ccol] = $agg['avg_val']; $data['max_' . $ccol] = $agg['max_val']; } catch (Exception $e) {} } echo json_encode(['status'=>'success','data'=>$data,'service'=>$service,'label'=>$cfg['label'],'table'=>$tbl,'timestamp'=>date('c')]); break; case 'list': $limit = min((int)($_GET['limit'] ?? 20), 100); $offset = (int)($_GET['offset'] ?? 0); if (!$exists) { echo json_encode(['status'=>'success','data'=>[],'count'=>0,'service'=>$service]); exit; } $order = $dcol ? "ORDER BY {$dcol} DESC" : "ORDER BY id DESC"; $rows = $pdo->query("SELECT * FROM admin.{$tbl} {$order} LIMIT {$limit} OFFSET {$offset}")->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['status'=>'success','data'=>$rows,'count'=>count($rows),'service'=>$service,'table'=>$tbl]); break; case 'health': $checks = ['database'=>true, 'table_exists'=>$exists, 'service'=>$service, 'table'=>$tbl]; if ($exists) { $checks['row_count'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.{$tbl}")->fetchColumn(); $checks['columns'] = array_column($pdo->query("SELECT column_name FROM information_schema.columns WHERE table_schema='admin' AND table_name='{$tbl}' ORDER BY ordinal_position")->fetchAll(PDO::FETCH_ASSOC), 'column_name'); } $checks['status'] = $exists ? 'healthy' : 'no_table'; echo json_encode($checks); break; case 'create': // Accept POST to insert row $input = json_decode(file_get_contents('php://input'), true) ?: $_POST; if (!$exists || empty($input)) { echo json_encode(['error'=>'Table missing or no data']); exit; } $cols = array_keys($input); $placeholders = array_map(fn($c)=>":$c", $cols); try { $stmt = $pdo->prepare("INSERT INTO admin.{$tbl} (" . implode(',', $cols) . ") VALUES (" . implode(',', $placeholders) . ") RETURNING id"); $stmt->execute($input); $id = $stmt->fetchColumn(); echo json_encode(['success'=>true, 'id'=>$id, 'service'=>$service]); } catch (Exception $e) { echo json_encode(['error'=>$e->getMessage()]); } break; default: echo json_encode(['service'=>$service,'label'=>$cfg['label'],'table'=>$tbl,'table_exists'=>$exists,'actions'=>['stats','list','health','create'],'timestamp'=>date('c')]); }