Files
html/api/dashboards-registry.php

95 lines
5.1 KiB
PHP

<?php
/**
* V116 - Dashboards Registry API
* Liste TOUS les dashboards/hubs avec catégorisation auto
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$ROOT = '/var/www/html';
$patterns = ['*dashboard*.html', '*-hub.html', '*-live.html', 'kpi-*.html', 'visual-*.html', 'admin-*.html', '*monitor*.html', '*report*.html']; // V125-WIDEN
$files = [];
foreach ($patterns as $p) {
$found = glob("$ROOT/$p");
if ($found) $files = array_merge($files, $found);
}
$files = array_unique($files);
sort($files);
// V119-EXCLUDE-SELF: avoid self-reference (hub doesn't list itself)
$files = array_values(array_filter($files, function($f) {
return basename($f) !== 'all-ia-hub.html';
}));
function categorize($name) {
// V118-CATEGORIZE-REFINED: reduced 'other' from 20 to <5
$n = strtolower($name);
if (strpos($n,'infra')!==false || strpos($n,'docker')!==false || strpos($n,'gpu')!==false || strpos($n,'hetzner')!==false || strpos($n,'database')!==false || strpos($n,'monitoring')!==false || strpos($n,'world-map')!==false) return ['infra','&#128187;','#3b82f6'];
if (strpos($n,'ethica')!==false || strpos($n,'medreach')!==false || strpos($n,'paperclip')!==false) return ['pharma','&#129298;','#10b981'];
if (strpos($n,'crm')!==false || strpos($n,'sales')!==false || strpos($n,'contacts')!==false || strpos($n,'acquired')!==false) return ['crm','&#128188;','#f59e0b'];
if (strpos($n,'kpi')!==false || strpos($n,'lean6sigma')!==false || strpos($n,'visual')!==false || strpos($n,'qa-')!==false) return ['kpi','&#128202;','#8b5cf6'];
if (strpos($n,'email')!==false || strpos($n,'em-')!==false || strpos($n,'office')!==false || strpos($n,'wevads')!==false) return ['email','&#128231;','#ec4899'];
if (strpos($n,'security')!==false || strpos($n,'cloudflare')!==false || strpos($n,'keys')!==false || strpos($n,'api-key')!==false) return ['security','&#128274;','#ef4444'];
if (strpos($n,'bpmn')!==false || strpos($n,'vsm')!==false || strpos($n,'architecture')!==false) return ['process','&#128207;','#f97316'];
if (strpos($n,'wevia')!==false || strpos($n,'agent')!==false || strpos($n,'tasks')!==false || strpos($n,'blade')!==false || strpos($n,'caps-')!==false || strpos($n,'knowledge')!==false || strpos($n,'tools-')!==false) return ['wevia','&#129302;','#06b6d4'];
if (strpos($n,'ai')!==false || strpos($n,'anthropic')!==false || strpos($n,'deepseek')!==false || strpos($n,'huggingface')!==false || strpos($n,'qdrant')!==false) return ['ai','&#129504;','#a855f7'];
if (strpos($n,'github')!==false || strpos($n,'google')!==false || strpos($n,'namecheap')!==false || strpos($n,'n8n')!==false || strpos($n,'automation')!==false || strpos($n,'deerflow')!==false || strpos($n,'universal')!==false) return ['integration','&#128279;','#64748b'];
if (strpos($n,'dormant')!==false || strpos($n,'orphan')!==false) return ['cleanup','&#128465;','#94a3b8'];
/* V125B-MOVE-ORDER: admin/monitor/report checks BEFORE all-screens/other fallback */
if (strpos($n,'admin')!==false) return ['admin','&#128274;','#dc2626'];
if (strpos($n,'monitor')!==false || strpos($n,'health')!==false || strpos($n,'status')!==false) return ['monitor','&#128269;','#0ea5e9'];
if (strpos($n,'report')!==false || strpos($n,'analytics')!==false) return ['report','&#128195;','#7c3aed'];
if (strpos($n,'all-screens')!==false || strpos($n,'ops-screens')!==false || strpos($n,'data-hub')!==false || strpos($n,'dashboards-hub')!==false) return ['ops','&#128295;','#84cc16'];
return ['other','&#128196;','#6b7280'];
}
$out = [];
$byCategory = [];
$checkStatus = isset($_GET['check']) && $_GET['check'] === '1';
// V117-HTTP-STATUS: optional live HTTP status via local curl
function checkHttp($name) {
/* V117-CURL-FIX: https with self-signed + follow 1 redirect to get real status */
$ch = curl_init("https://weval-consulting.com/$name");
curl_setopt_array($ch, [
CURLOPT_NOBODY => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 2,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_FOLLOWLOCATION => false,
]);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $code;
}
foreach ($files as $f) {
$name = basename($f);
$size = filesize($f);
list($cat, $icon, $color) = categorize($name);
$display = ucwords(str_replace(['-','.html','dashboard','hub','live'], [' ','','Dashboard','Hub','Live'], $name));
$display = trim(preg_replace('/\s+/', ' ', $display));
$entry = [
'name' => $name,
'display' => $display,
'url' => '/' . $name,
'category' => $cat,
'icon' => $icon,
'color' => $color,
'size_kb' => round($size/1024, 1),
'mtime' => date('c', filemtime($f))
];
if ($checkStatus) $entry['http_status'] = checkHttp($name);
$out[] = $entry;
if (!isset($byCategory[$cat])) $byCategory[$cat] = 0;
$byCategory[$cat]++;
}
echo json_encode([
'total' => count($out),
'by_category' => $byCategory,
'dashboards' => $out,
'generated' => date('c')
], JSON_UNESCAPED_UNICODE);