Caso real resuelto con la bitácora (23/08, 12:11): tres rellamados de E001, el del medio no sonó. No fue la voz: la pestaña que anunciaba estaba en segundo plano —era el Mac de pruebas, no el televisor; lo delata la voz Paulina— y Chrome frena los relojes de las pestañas ocultas a ~1 tic por minuto. En ese hueco el llamado intermedio fue invisible: cuando la pestaña volvió a consultar, el servidor ya solo mostraba el estado más reciente. Para que ese estado deje de confundirse con un fallo de la voz, la pantalla registra ahora el evento 'lag' cuando detecta un hueco de más de 10 s entre tics o cuando pasa a segundo plano, y la tarjeta de Actividad lo traduce como «Pantalla congelada» con su explicación. En el televisor real —siempre visible, en primer plano— este estado no debe aparecer; si aparece, es la señal de que alguien lo dejó oculto o el equipo se suspendió. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
49 lines
1.6 KiB
PHP
49 lines
1.6 KiB
PHP
<?php
|
|
/**
|
|
* POST /modules/turnero/api/log_tv.php
|
|
* Recibe la bitácora de voz de la pantalla del televisor (via sendBeacon).
|
|
*
|
|
* SIN SESIÓN, a propósito: la pantalla es un kiosco público (display_global es
|
|
* ruta pública) y el envío es fire-and-forget. Por eso el endpoint es
|
|
* deliberadamente sordo y estrecho:
|
|
* - solo acepta los eventos de la lista, nada libre;
|
|
* - recorta el detalle a 500 caracteres;
|
|
* - no devuelve datos, solo un 204;
|
|
* - inserta y nada más: no lee, no borra, no actualiza.
|
|
*/
|
|
|
|
require_once __DIR__ . '/../../../config/config.php';
|
|
|
|
http_response_code(204);
|
|
header('Content-Type: text/plain');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') exit;
|
|
|
|
$raw = file_get_contents('php://input');
|
|
if ($raw === false || strlen($raw) > 2000) exit;
|
|
|
|
$d = json_decode($raw, true);
|
|
if (!is_array($d)) exit;
|
|
|
|
$evento = $d['e'] ?? '';
|
|
$PERMITIDOS = ['start', 'end', 'error', 'sin_start', 'mudo', 'lag'];
|
|
if (!in_array($evento, $PERMITIDOS, true)) exit;
|
|
|
|
unset($d['e'], $d['t']); // el timestamp lo pone la base, no el cliente
|
|
|
|
try {
|
|
$pdo = Database::getInstance()->getConnection();
|
|
$stmt = $pdo->prepare(
|
|
"INSERT INTO turnero_tv_log (evento, detalle, ip, user_agent) VALUES (?, ?, ?, ?)"
|
|
);
|
|
$stmt->execute([
|
|
$evento,
|
|
mb_substr(json_encode($d, JSON_UNESCAPED_UNICODE), 0, 500),
|
|
substr(trim(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '')[0]), 0, 45),
|
|
substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 255),
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
// La bitácora jamás debe afectar a la pantalla
|
|
error_log('[log_tv] ' . $e->getMessage());
|
|
}
|