Independent dashboard for CambioReal agents with local SQLite auth and read-only RDS connection. Features login, per-agent transaction filtering, KPIs, charts (Chart.js), and detailed transaction table. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
88 lines
2.3 KiB
JavaScript
88 lines
2.3 KiB
JavaScript
/**
|
|
* BI Agentes — CambioReal
|
|
*
|
|
* Uso: node server.js
|
|
* Abre: http://localhost:3080
|
|
*/
|
|
require('dotenv').config();
|
|
|
|
const express = require('express');
|
|
const session = require('express-session');
|
|
const path = require('path');
|
|
const { authenticate, requireAuth } = require('./src/auth');
|
|
const { fetchTransacoes, serialize } = require('./src/queries');
|
|
const { buildHTML } = require('./src/dashboard');
|
|
|
|
// Initialize SQLite (creates tables on first run)
|
|
require('./src/db-local');
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3080;
|
|
|
|
// Middleware
|
|
app.use(express.urlencoded({ extended: false }));
|
|
app.use(express.json());
|
|
app.use(session({
|
|
secret: process.env.SESSION_SECRET || 'bi-agentes-default-secret',
|
|
resave: false,
|
|
saveUninitialized: false,
|
|
cookie: { maxAge: 8 * 60 * 60 * 1000 }, // 8 horas
|
|
}));
|
|
|
|
// Static files
|
|
app.use('/public', express.static(path.join(__dirname, 'public')));
|
|
|
|
// --- Routes ---
|
|
|
|
// Login page
|
|
app.get('/login', (req, res) => {
|
|
if (req.session && req.session.agente) return res.redirect('/dashboard');
|
|
res.sendFile(path.join(__dirname, 'public', 'login.html'));
|
|
});
|
|
|
|
// Login POST
|
|
app.post('/login', async (req, res) => {
|
|
const { email, senha } = req.body;
|
|
try {
|
|
const agente = await authenticate(email, senha);
|
|
if (!agente) return res.redirect('/login?error=1');
|
|
req.session.agente = {
|
|
id: agente.id,
|
|
email: agente.email,
|
|
agente_id: agente.agente_id,
|
|
nome: agente.nome,
|
|
};
|
|
res.redirect('/dashboard');
|
|
} catch (err) {
|
|
console.error('Login error:', err);
|
|
res.redirect('/login?error=1');
|
|
}
|
|
});
|
|
|
|
// Logout
|
|
app.get('/logout', (req, res) => {
|
|
req.session.destroy(() => res.redirect('/login'));
|
|
});
|
|
|
|
// Dashboard (protected)
|
|
app.get('/dashboard', requireAuth, async (req, res) => {
|
|
try {
|
|
const agente = req.session.agente;
|
|
const { rowsBrlUsd, rowsUsdBrl } = await fetchTransacoes(agente.agente_id);
|
|
const data = serialize(rowsBrlUsd, rowsUsdBrl);
|
|
const html = buildHTML(data, agente);
|
|
res.send(html);
|
|
} catch (err) {
|
|
console.error('Dashboard error:', err);
|
|
res.status(500).send('Erro ao carregar dashboard: ' + err.message);
|
|
}
|
|
});
|
|
|
|
// Root redirect
|
|
app.get('/', (req, res) => res.redirect('/dashboard'));
|
|
|
|
// Start
|
|
app.listen(PORT, () => {
|
|
console.log(`BI Agentes rodando: http://localhost:${PORT}`);
|
|
});
|