71 lines
3.2 KiB
PHP
71 lines
3.2 KiB
PHP
<?php
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: *');
|
|
|
|
function sentinel_query($sql) {
|
|
$cmd = "PGPASSWORD=admin123 psql -U admin -d adx_system -t -A -F '|' -c " . escapeshellarg($sql) . " 2>/dev/null";
|
|
$url = "http://10.1.0.3:5890/api/sentinel-brain.php?action=exec&cmd=" . urlencode($cmd);
|
|
$ctx = stream_context_create(['http'=>['timeout'=>10]]);
|
|
$r = @file_get_contents($url, false, $ctx);
|
|
if(!$r) return '';
|
|
$d = json_decode($r, true);
|
|
return $d['output'] ?? '';
|
|
}
|
|
|
|
$feed = [];
|
|
|
|
// 1. Scraper v2 events
|
|
$raw = sentinel_query("SELECT to_char(created_at,'YYYY-MM-DD HH24:MI'), source, country, spec, found, new_contacts FROM ethica.scraper_v2_log ORDER BY created_at DESC LIMIT 15");
|
|
foreach(explode("\n", trim($raw)) as $line) {
|
|
if(!$line) continue;
|
|
$p = explode('|', $line);
|
|
if(count($p)<6) continue;
|
|
$feed[] = ['ts'=>trim($p[0]), 'icon'=>"\xF0\x9F\x94\x8D", 'color'=>(int)$p[5]>0?'#22c55e':'#64748b',
|
|
'msg'=>'Scraping '.trim($p[1]).': +'.trim($p[5]).' HCPs ('.trim($p[3]).', '.trim($p[2]).')'];
|
|
}
|
|
|
|
// 2. CrossValidator audit
|
|
$raw2 = sentinel_query("SELECT to_char(created_at,'YYYY-MM-DD HH24:MI'), action, old_value, new_value, affected_count, source_filter FROM ethica.crossvalidator_audit ORDER BY created_at DESC LIMIT 10");
|
|
foreach(explode("\n", trim($raw2)) as $line) {
|
|
if(!$line) continue;
|
|
$p = explode('|', $line);
|
|
if(count($p)<6) continue;
|
|
$icons = ['cleanup'=>"\xF0\x9F\xA7\xB9",'dedup'=>"\xF0\x9F\x94\x80",'enrich_phone'=>"\xE2\x98\x8E\xEF\xB8\x8F",'merge'=>"\xF0\x9F\x94\x97"];
|
|
$icon = $icons[trim($p[1])] ?? "\xF0\x9F\x9B\xA1";
|
|
$feed[] = ['ts'=>trim($p[0]), 'icon'=>$icon, 'color'=>'#f59e0b',
|
|
'msg'=>ucfirst(trim($p[1])).': '.trim($p[4]).' HCPs ('.trim($p[2]).' → '.trim($p[3]).') ['.trim($p[5]).']'];
|
|
}
|
|
|
|
// 3. Ethica validator log (from file)
|
|
$cmd = "tail -50 /opt/wevads/logs/ethica-validator.log 2>/dev/null | grep -v 'Nothing to check' | tail -10";
|
|
$url = "http://10.1.0.3:5890/api/sentinel-brain.php?action=exec&cmd=" . urlencode($cmd);
|
|
$ctx = stream_context_create(['http'=>['timeout'=>5]]);
|
|
$vlog = @file_get_contents($url, false, $ctx);
|
|
if($vlog) {
|
|
$vd = json_decode($vlog, true);
|
|
$vout = $vd['output'] ?? '';
|
|
foreach(explode("\n", trim($vout)) as $line) {
|
|
if(!$line || strlen($line)<10) continue;
|
|
$feed[] = ['ts'=>substr($line,0,8), 'icon'=>"\xE2\x9C\x89", 'color'=>'#818cf8',
|
|
'msg'=>'Validator: '.trim($line)];
|
|
}
|
|
}
|
|
|
|
// 4. Summary KPIs
|
|
$totalRaw = sentinel_query("SELECT count(*) FROM ethica.medecins_validated");
|
|
$emailRaw = sentinel_query("SELECT count(*) FROM ethica.medecins_validated WHERE email_valid='valid'");
|
|
$telRaw = sentinel_query("SELECT count(*) FROM ethica.medecins_validated WHERE telephone IS NOT NULL AND telephone != ''");
|
|
$weekRaw = sentinel_query("SELECT count(*) FROM ethica.medecins_validated WHERE created_at > NOW() - INTERVAL '7 days'");
|
|
|
|
// Sort by timestamp desc
|
|
usort($feed, function($a,$b){ return strcmp($b['ts'],$a['ts']); });
|
|
|
|
echo json_encode([
|
|
'feed' => array_slice($feed, 0, 30),
|
|
'total' => (int)trim($totalRaw),
|
|
'with_email' => (int)trim($emailRaw),
|
|
'with_tel' => (int)trim($telRaw),
|
|
'week_new' => (int)trim($weekRaw),
|
|
'generated' => date('c')
|
|
], JSON_UNESCAPED_UNICODE);
|