feat(turnero): bacteriólogo sin dashboard/historial, redirige por IP

- Auth: agrega isBacteriologo()
- App: guard que bloquea dashboard e historial para bacteriólogo y
  redirige según IP (turnero_dispositivos); IP registrada → ese lugar,
  IP libre → primer lugar de muestras
- module.php: sidebar bacteriólogo sin Dashboard/Historial; IP
  registrada muestra solo ese lugar, IP libre muestra TV + todos los
  lugares muestras

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-08 07:54:48 -05:00
co-authored by Claude Sonnet 4.6
parent a776c5733c
commit b2e7130762
3 changed files with 82 additions and 10 deletions
+45
View File
@@ -44,6 +44,17 @@ class App
header('Location: ' . APP_ROOT . '/../enfermero_portal.php');
exit;
}
// Bacteriólogos: sin dashboard ni historial; redirige según IP
if (Auth::isBacteriologo()) {
$mod = $router->getModule();
$view = $router->getView();
$blocked = ($mod === 'dashboard')
|| ($mod === 'turnero' && in_array($view, ['dashboard', 'historial'], true));
if ($blocked) {
header('Location: ' . self::bacteDefaultUrl());
exit;
}
}
}
self::dispatch($router);
@@ -99,6 +110,40 @@ class App
include $viewFile;
}
// ─── Helpers de rol ─────────────────────────────────────────────────────
/**
* URL de destino para bacteriólogo según IP del cliente.
* IP registrada en turnero_dispositivos → ese lugar.
* IP no registrada → primer lugar de tipo muestras.
*/
private static function bacteDefaultUrl(): string
{
$base = '/erp.php?m=turnero&v=lugar&lugar_id=';
try {
$pdo = Database::getInstance()->getConnection();
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
// ¿IP registrada?
$dev = $pdo->prepare(
"SELECT lugar_id FROM turnero_dispositivos WHERE ip = ? AND activo = 1 LIMIT 1"
);
$dev->execute([$ip]);
$row = $dev->fetch(PDO::FETCH_ASSOC);
if ($row) {
return $base . (int)$row['lugar_id'];
}
// Primer lugar de toma de muestras
$first = $pdo->query(
"SELECT id FROM turnero_lugares WHERE activo=1 AND tipo='muestras' ORDER BY sort_order LIMIT 1"
)->fetch(PDO::FETCH_ASSOC);
if ($first) {
return $base . (int)$first['id'];
}
} catch (\Throwable $_) {}
// Fallback: turnero sin vista específica
return '/erp.php?m=turnero';
}
// ─── Páginas de error ────────────────────────────────────────────────────
private static function render404(string $module, string $view): void