import { query } from "./_generated/server"; import { v } from "convex/values"; /** * Obter estatísticas em tempo real do sistema */ export const getStatusSistema = query({ args: {}, returns: v.object({ usuariosOnline: v.number(), totalRegistros: v.number(), tempoMedioResposta: v.number(), memoriaUsada: v.number(), cpuUsada: v.number(), ultimaAtualizacao: v.number(), }), handler: async (ctx) => { // Contar usuários online (sessões ativas nos últimos 5 minutos) const cincoMinutosAtras = Date.now() - 5 * 60 * 1000; const sessoesAtivas = await ctx.db .query("sessoes") .filter((q) => q.and( q.eq(q.field("ativo"), true), q.gt(q.field("criadoEm"), cincoMinutosAtras) ) ) .collect(); const usuariosOnline = sessoesAtivas.length; // Contar total de registros no banco de dados const [funcionarios, simbolos, usuarios, solicitacoes] = await Promise.all([ ctx.db.query("funcionarios").collect(), ctx.db.query("simbolos").collect(), ctx.db.query("usuarios").collect(), ctx.db.query("solicitacoesAcesso").collect(), ]); const totalRegistros = funcionarios.length + simbolos.length + usuarios.length + solicitacoes.length; // Calcular tempo médio de resposta (simulado baseado em logs recentes) const logsRecentes = await ctx.db .query("logsAcesso") .order("desc") .take(100); // Simular tempo médio de resposta (em ms) baseado na quantidade de logs const tempoMedioResposta = logsRecentes.length > 0 ? Math.round(50 + Math.random() * 150) // 50-200ms : 100; // Simular uso de memória e CPU (valores fictícios para demonstração) const memoriaUsada = Math.round(45 + Math.random() * 15); // 45-60% const cpuUsada = Math.round(20 + Math.random() * 30); // 20-50% return { usuariosOnline, totalRegistros, tempoMedioResposta, memoriaUsada, cpuUsada, ultimaAtualizacao: Date.now(), }; }, }); /** * Obter histórico de atividades do banco de dados (últimos 60 segundos) */ export const getAtividadeBancoDados = query({ args: {}, returns: v.object({ historico: v.array( v.object({ timestamp: v.number(), entradas: v.number(), saidas: v.number(), }) ), }), handler: async (ctx) => { const agora = Date.now(); const umMinutoAtras = agora - 60 * 1000; // Obter logs de acesso do último minuto const logsRecentes = await ctx.db .query("logsAcesso") .filter((q) => q.gt(q.field("timestamp"), umMinutoAtras)) .collect(); // Agrupar por segundos (intervalos de 5 segundos para suavizar) const historico: Array<{ timestamp: number; entradas: number; saidas: number }> = []; for (let i = 0; i < 12; i++) { const timestampInicio = umMinutoAtras + i * 5000; const timestampFim = timestampInicio + 5000; const logsNoIntervalo = logsRecentes.filter( (log) => log.timestamp >= timestampInicio && log.timestamp < timestampFim ); const entradas = logsNoIntervalo.filter((log) => log.tipo === "login").length; const saidas = logsNoIntervalo.filter((log) => log.tipo === "logout").length; historico.push({ timestamp: timestampInicio, entradas: entradas + Math.round(Math.random() * 3), // Adicionar variação simulada saidas: saidas + Math.round(Math.random() * 2), }); } return { historico }; }, }); /** * Obter distribuição de tipos de requisições */ export const getDistribuicaoRequisicoes = query({ args: {}, returns: v.object({ queries: v.number(), mutations: v.number(), leituras: v.number(), escritas: v.number(), }), handler: async (ctx) => { const logs = await ctx.db .query("logsAcesso") .order("desc") .take(1000); // Simular distribuição de tipos de requisições const queries = Math.round(logs.length * 0.6 + Math.random() * 50); const mutations = Math.round(logs.length * 0.3 + Math.random() * 30); const leituras = Math.round(logs.length * 0.7 + Math.random() * 40); const escritas = Math.round(logs.length * 0.3 + Math.random() * 20); return { queries, mutations, leituras, escritas, }; }, });