const express = require('express'); const cors = require('cors'); const pool = require('./db'); const app = express(); const PORT = 3001; // Porta do backend app.use(cors()); // Permite que o React (localhost:3000) acesse este servidor app.use(express.json()); // --- Rotas de Usuários --- // Listar Usuários (com filtro opcional de tenant) app.get('/api/users', async (req, res) => { try { const { tenantId } = req.query; let query = 'SELECT * FROM users'; const params = []; if (tenantId && tenantId !== 'all') { query += ' WHERE tenant_id = ?'; params.push(tenantId); } const [rows] = await pool.query(query, params); res.json(rows); } catch (error) { console.error('Erro ao buscar usuários:', error); res.status(500).json({ error: error.message }); } }); // Detalhe do Usuário app.get('/api/users/:id', async (req, res) => { try { const [rows] = await pool.query('SELECT * FROM users WHERE id = ?', [req.params.id]); if (rows.length === 0) return res.status(404).json({ message: 'User not found' }); res.json(rows[0]); } catch (error) { res.status(500).json({ error: error.message }); } }); // --- Rotas de Atendimentos --- // Listar Atendimentos (Dashboard) app.get('/api/attendances', async (req, res) => { try { const { tenantId, userId, teamId, startDate, endDate } = req.query; let query = ` SELECT a.*, u.team_id FROM attendances a JOIN users u ON a.user_id = u.id WHERE a.tenant_id = ? `; const params = [tenantId]; // Filtro de Data if (startDate && endDate) { query += ' AND a.created_at BETWEEN ? AND ?'; params.push(new Date(startDate), new Date(endDate)); } // Filtro de Usuário if (userId && userId !== 'all') { query += ' AND a.user_id = ?'; params.push(userId); } // Filtro de Time (baseado na tabela users ou teams) if (teamId && teamId !== 'all') { query += ' AND u.team_id = ?'; params.push(teamId); } query += ' ORDER BY a.created_at DESC'; const [rows] = await pool.query(query, params); // Tratamento de campos JSON se o MySQL retornar como string const processedRows = rows.map(row => ({ ...row, attention_points: typeof row.attention_points === 'string' ? JSON.parse(row.attention_points) : row.attention_points, improvement_points: typeof row.improvement_points === 'string' ? JSON.parse(row.improvement_points) : row.improvement_points, converted: Boolean(row.converted) // Garantir booleano })); res.json(processedRows); } catch (error) { console.error('Erro ao buscar atendimentos:', error); res.status(500).json({ error: error.message }); } }); // Detalhe do Atendimento app.get('/api/attendances/:id', async (req, res) => { try { const [rows] = await pool.query('SELECT * FROM attendances WHERE id = ?', [req.params.id]); if (rows.length === 0) return res.status(404).json({ message: 'Attendance not found' }); const row = rows[0]; const processedRow = { ...row, attention_points: typeof row.attention_points === 'string' ? JSON.parse(row.attention_points) : row.attention_points, improvement_points: typeof row.improvement_points === 'string' ? JSON.parse(row.improvement_points) : row.improvement_points, converted: Boolean(row.converted) }; res.json(processedRow); } catch (error) { res.status(500).json({ error: error.message }); } }); // --- Rotas de Tenants (Super Admin) --- app.get('/api/tenants', async (req, res) => { try { const [rows] = await pool.query('SELECT * FROM tenants'); res.json(rows); } catch (error) { res.status(500).json({ error: error.message }); } }); app.listen(PORT, () => { console.log(`🚀 Servidor Backend rodando em http://localhost:${PORT}`); });