Files
html/api/wevia-confirm-sql-intent.php

80 lines
4.2 KiB
PHP

<?php
// Intent confirm_sql - permet à Yacine d'approuver un SQL draft via chat "ok", puis sentinel exec
// Doctrine 70 compliant (draft-first, Yacine valide) + 74 compliant (chat NL, pas manuel terminal)
// Stocke drafts dans admin.pending_sql_drafts, exec après confirmation
if (!function_exists('wevia_confirm_sql')) {
function wevia_confirm_sql($msg) {
if (!$msg) return false;
// Match "ok sql", "confirm sql", "exec sql [id]", "valide sql"
if (!preg_match('/\b(ok\s*sql|confirm\s*sql|exec\s*sql|valide\s*sql|run\s*sql\s*draft|approve\s*sql)\b/i', $msg)) return false;
$out = ['intent' => '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 <id>" 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);