Files
NoIdle/backend/routes/dashboard.js

190 lines
7.5 KiB
JavaScript
Raw Normal View History

const express = require('express');
const router = express.Router();
const { query } = require('../config/database');
const { authenticateToken } = require('../middleware/auth');
// GET /api/dashboard - Estatísticas do dashboard
router.get('/', authenticateToken, async (req, res) => {
try {
const company_id = req.user.company_id;
console.log('GET /api/dashboard - Company ID:', company_id);
// Estatísticas de dispositivos
const devicesStats = await query(
`SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE is_active = true) as active,
COUNT(*) FILTER (WHERE is_active = false) as inactive,
COUNT(*) FILTER (WHERE user_id IS NOT NULL) as assigned
FROM devices
WHERE company_id = $1`,
[company_id]
);
// Estatísticas de usuários
const usersStats = await query(
`SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE is_active = true) as active,
COUNT(*) FILTER (WHERE is_active = false) as inactive
FROM users
WHERE company_id = $1`,
[company_id]
);
// Estatísticas de atividades (últimas 24 horas)
const activitiesStats = await query(
`SELECT
COUNT(*) as total_24h,
COUNT(*) FILTER (WHERE activity_type = 'idle') as idle_count,
COUNT(*) FILTER (WHERE activity_type = 'active') as active_count
FROM activities
WHERE company_id = $1
AND created_at >= NOW() - INTERVAL '24 hours'`,
[company_id]
);
// Estatísticas de chaves de ativação
const keysStats = await query(
`SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE is_used = true) as used,
COUNT(*) FILTER (WHERE is_used = false) as available
FROM activation_keys
WHERE company_id = $1`,
[company_id]
);
// Dispositivos recentes (últimos 5)
const recentDevices = await query(
`SELECT d.*, u.name as user_name, u.email as user_email
FROM devices d
LEFT JOIN users u ON d.user_id = u.id
WHERE d.company_id = $1
ORDER BY d.created_at DESC
LIMIT 5`,
[company_id]
);
// Atividades recentes (últimas 10)
const recentActivities = await query(
`SELECT a.*, d.device_name, u.name as user_name
FROM activities a
LEFT JOIN devices d ON a.device_id = d.device_id
LEFT JOIN users u ON d.user_id = u.id
WHERE a.company_id = $1
ORDER BY a.created_at DESC
LIMIT 10`,
[company_id]
);
// Converter valores string para números
const devicesData = devicesStats.rows[0];
const usersData = usersStats.rows[0];
const activitiesData = activitiesStats.rows[0];
const keysData = keysStats.rows[0];
const response = {
success: true,
stats: {
devices: {
total: parseInt(devicesData.total) || 0,
active: parseInt(devicesData.active) || 0,
inactive: parseInt(devicesData.inactive) || 0,
assigned: parseInt(devicesData.assigned) || 0
},
users: {
total: parseInt(usersData.total) || 0,
active: parseInt(usersData.active) || 0,
inactive: parseInt(usersData.inactive) || 0
},
activities: {
total_24h: parseInt(activitiesData.total_24h) || 0,
idle_count: parseInt(activitiesData.idle_count) || 0,
active_count: parseInt(activitiesData.active_count) || 0
},
keys: {
total: parseInt(keysData.total) || 0,
used: parseInt(keysData.used) || 0,
available: parseInt(keysData.available) || 0
}
},
recent: {
devices: recentDevices.rows,
activities: recentActivities.rows
}
};
console.log('GET /api/dashboard - Resposta:', JSON.stringify(response, null, 2));
res.json(response);
} catch (error) {
console.error('Erro ao obter dados do dashboard:', error);
console.error('Erro detalhado:', error.message);
console.error('Stack:', error.stack);
res.status(500).json({ error: 'Erro ao obter dados do dashboard', details: error.message });
}
});
// GET /api/dashboard/stats - Estatísticas expandidas para o novo dashboard
router.get('/stats', async (req, res) => {
try {
// Estatísticas básicas (simplificadas para funcionar sempre)
const usersCount = await query(`SELECT COUNT(*)::int as count FROM users`);
const devicesCount = await query(`SELECT COUNT(*)::int as count FROM devices`);
const activitiesCount = await query(`SELECT COUNT(*)::int as count FROM activities WHERE created_at::date = CURRENT_DATE`);
const devicesOnline = await query(`SELECT COUNT(*)::int as count FROM devices WHERE is_active = true`);
// Times (pode não existir)
let teamsCount = { rows: [{ count: 0 }] };
try {
teamsCount = await query(`SELECT COUNT(*)::int as count FROM teams`);
} catch (e) {
// Tabela teams pode não existir
}
// Dados MDM (podem não existir)
let policiesCount = { rows: [{ count: 0 }] };
let pendingCommands = { rows: [{ count: 0 }] };
try {
policiesCount = await query(`SELECT COUNT(*)::int as count FROM policies WHERE enabled = true`);
pendingCommands = await query(`SELECT COUNT(*)::int as count FROM policy_commands WHERE status IN ('pending', 'sent')`);
} catch (e) {
// Tabelas MDM não existem ainda
}
res.json({
success: true,
stats: {
users: parseInt(usersCount.rows[0].count) || 0,
teams: parseInt(teamsCount.rows[0].count) || 0,
devices: parseInt(devicesCount.rows[0].count) || 0,
policies: parseInt(policiesCount.rows[0].count) || 0,
activities_today: parseInt(activitiesCount.rows[0].count) || 0,
devices_online: parseInt(devicesOnline.rows[0].count) || 0,
devices_offline: parseInt(devicesCount.rows[0].count) - parseInt(devicesOnline.rows[0].count) || 0,
pending_commands: parseInt(pendingCommands.rows[0].count) || 0
},
alerts: {
devices_offline_7days: 0, // TODO: implementar
devices_no_activity_24h: 0, // TODO: implementar
failed_policies_24h: 0, // TODO: implementar
devices_need_update: 0, // TODO: implementar
low_disk_space: 0, // TODO: implementar
inactive_users: 0 // TODO: implementar
}
});
} catch (error) {
console.error('Erro ao obter estatísticas do dashboard:', error);
res.status(500).json({
success: false,
error: 'Erro ao obter estatísticas do dashboard',
details: error.message
});
}
});
module.exports = router;