'confirm_sql', 'tool' => 'sql_draft_confirm_and_exec']; $sr_exec = function($sql) { $ch = curl_init('http://10.1.0.3:5890/api/sentinel-brain.php?action=exec&cmd=' . urlencode("PGPASSWORD=admin123 psql -U admin -d adx_system -h 127.0.0.1 -t -A -c \"{$sql}\"")); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10]); $r = curl_exec($ch); curl_close($ch); return @json_decode($r, true); }; // Check if table exists $exists = $sr_exec("SELECT count(*) FROM information_schema.tables WHERE table_schema='admin' AND table_name='pending_sql_drafts'"); $table_exists = $exists && (int)(trim($exists['output'] ?? '0')) > 0; if (!$table_exists) { $out['status'] = 'no_pending_drafts'; $out['note'] = 'Table admin.pending_sql_drafts non créée encore. Intent prêt mais stockage drafts pas activé.'; $out['init_sql_draft'] = "CREATE TABLE admin.pending_sql_drafts (id SERIAL PRIMARY KEY, draft_name VARCHAR(200), sql_text TEXT, created_at TIMESTAMP DEFAULT now(), executed_at TIMESTAMP, result TEXT)"; $out['workflow'] = [ '1. Intent X (ex office_senders) génère SQL draft', '2. WEVIA insert dans admin.pending_sql_drafts (status=pending)', '3. Yacine chat "confirm sql" → intent liste drafts + id', '4. Yacine chat "exec sql 3" → intent exec sentinel + mark executed', '5. Result retourné via chat', ]; $out['compliance'] = 'Doctrine 70 (SQL draft only) + 74 (chat NL, pas manuel) compatible'; $out['next_step'] = 'Créer table via doctrine 70 SQL confirm flow lui-même (chicken-egg, manual 1 fois via WEVIA chat "init pending drafts")'; } else { // Liste drafts en attente $pending = $sr_exec("SELECT id, draft_name, LEFT(sql_text, 100), created_at FROM admin.pending_sql_drafts WHERE executed_at IS NULL ORDER BY created_at DESC LIMIT 10"); $drafts = []; if ($pending && !empty($pending['output'])) { foreach (explode("\n", trim($pending['output'])) as $line) { $parts = explode('|', $line); if (count($parts) >= 4) { $drafts[] = [ 'id' => (int)$parts[0], 'name' => $parts[1], 'sql_preview' => $parts[2] . '...', 'created_at' => $parts[3], ]; } } } $out['status'] = empty($drafts) ? 'no_pending_drafts' : 'pending_drafts_available'; $out['pending_drafts'] = $drafts; $out['usage'] = 'Yacine chat "exec sql " pour confirmer et executer un draft specifique'; } $out['linked_intents'] = [ 'office_senders' => 'Génère drafts re-activation graph_accounts', 'azure_reregister' => 'Génère drafts UPDATE graph_tenants client_secret', ]; header("Content-Type: application/json"); echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); exit; } } $_cs_msg = ''; $_body = @file_get_contents('php://input'); if ($_body) { $_j = @json_decode($_body, true); if (is_array($_j) && !empty($_j['message'])) $_cs_msg = $_j['message']; } if (!$_cs_msg) $_cs_msg = $_POST['message'] ?? $_GET['message'] ?? ''; if ($_cs_msg) wevia_confirm_sql($_cs_msg);