Files
html/api/ethica-feed-api.php
2026-04-12 22:57:03 +02:00

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);