db = Database::getInstance(); } // ───────────────────────────────────────────────────────────────────────── // Registro de actividad // ───────────────────────────────────────────────────────────────────────── /** * Registra una acción en el log. * * @param int|null $adminId admin_users.id * @param string $modulo pacientes|ordenes|domicilios|enfermeras|asignaciones * @param string $accion crear|editar|eliminar|autorizar|rechazar|asignar... * @param int|null $entidadId ID del registro afectado * @param mixed $detalle Texto o array (se serializa como JSON) */ public function registrar( ?int $adminId, string $modulo, string $accion, ?int $entidadId = null, $detalle = null ): int { $adminNombre = null; if ($adminId) { $row = $this->db->fetch( 'SELECT full_name FROM admin_users WHERE id = ?', [$adminId] ); $adminNombre = $row['full_name'] ?? null; } $detalleStr = is_array($detalle) || is_object($detalle) ? json_encode($detalle, JSON_UNESCAPED_UNICODE) : (string)($detalle ?? ''); return $this->db->insert('lab_actividad_admin', [ 'admin_id' => $adminId, 'admin_nombre'=> $adminNombre, 'modulo' => $modulo, 'accion' => $accion, 'entidad_id' => $entidadId, 'detalle' => $detalleStr, 'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null, 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null, ]); } // ───────────────────────────────────────────────────────────────────────── // Consultas // ───────────────────────────────────────────────────────────────────────── /** * Actividad reciente del módulo. * * @param int $limit * @param string $modulo Filtro opcional por módulo */ public function reciente(int $limit = 50, string $modulo = ''): array { $where = $modulo ? 'WHERE a.modulo = ?' : ''; $params = $modulo ? [$modulo] : []; $params[] = $limit; return $this->db->fetchAll(" SELECT a.*, u.username AS admin_username FROM lab_actividad_admin a LEFT JOIN admin_users u ON u.id = a.admin_id $where ORDER BY a.created_at DESC LIMIT ? ", $params); } /** * Actividad de un administrador específico. */ public function porAdmin(int $adminId, int $limit = 100): array { return $this->db->fetchAll(" SELECT * FROM lab_actividad_admin WHERE admin_id = ? ORDER BY created_at DESC LIMIT ? ", [$adminId, $limit]); } /** * Actividad sobre una entidad concreta. */ public function porEntidad(string $modulo, int $entidadId): array { return $this->db->fetchAll(" SELECT a.*, u.username AS admin_username FROM lab_actividad_admin a LEFT JOIN admin_users u ON u.id = a.admin_id WHERE a.modulo = ? AND a.entidad_id = ? ORDER BY a.created_at ASC ", [$modulo, $entidadId]); } /** * Estadísticas de actividad por módulo en un rango de fechas. */ public function estadisticas(string $desde, string $hasta): array { return $this->db->fetchAll(" SELECT modulo, accion, COUNT(*) AS total FROM lab_actividad_admin WHERE DATE(created_at) BETWEEN ? AND ? GROUP BY modulo, accion ORDER BY modulo, total DESC ", [$desde, $hasta]); } }