fix: corrige inconsistências críticas de backend e navegação
- Backend: substitui string literals com aspas duplas por aspas simples nas queries PostgreSQL (settings, GTO builder, google_tokens delete) - Backend: corrige alias SQL 'dentistanome' para 'dentistaNome' (quoted) e ajusta frontend para usar 'pacientenome' (lowercase do PG) - Backend: move app.listen() para após todas as rotas registradas - Backend: ativa generateIntelligentNotifications no startup + intervalo 5min - Backend: magic link usa process.env.APP_URL em vez de localhost:3000 hardcoded - Frontend: adiciona 'relatorios' às permissões do role 'funcionario' - Frontend: adiciona onClick ao botão Relatórios do Dashboard - Frontend: adiciona Content-Type e JWT token em salvarAgendamento/atualizarAgendamento - Frontend: MeusTratamentos passa JWT token nas chamadas a /api/guias - Frontend: ClinicasView passa JWT token no endpoint de atualização de cor - Frontend: corrige subtítulo 'MYSQL + GOOGLE' para 'POSTGRESQL + GOOGLE' Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+21
-12
@@ -262,8 +262,6 @@ const createOAuth2Client = () => new google.auth.OAuth2(
|
||||
process.env.GOOGLE_REDIRECT_URI || `http://localhost:${PORT}/api/oauth2callback`
|
||||
);
|
||||
|
||||
app.listen(PORT, '0.0.0.0', () => console.log(`[SERVER] Running on http://0.0.0.0:${PORT}`));
|
||||
|
||||
// --- GOOGLE AUTH ROUTES ---
|
||||
app.get('/api/auth/google/url', (req, res) => {
|
||||
const { dentistId } = req.query;
|
||||
@@ -321,7 +319,7 @@ app.get('/api/auth/google/status', async (req, res) => {
|
||||
|
||||
app.delete('/api/auth/google/:ownerId', async (req, res) => {
|
||||
try {
|
||||
await pool.query('DELETE FROM google_tokens WHERE owner_id = ?', [req.params.ownerId]);
|
||||
await pool.query('DELETE FROM google_tokens WHERE owner_id = $1', [req.params.ownerId]);
|
||||
res.json({ success: true });
|
||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
||||
});
|
||||
@@ -329,7 +327,7 @@ app.delete('/api/auth/google/:ownerId', async (req, res) => {
|
||||
// --- SETTINGS ---
|
||||
app.get('/api/settings', async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.query('SELECT * FROM settings WHERE id = "main"');
|
||||
const { rows } = await pool.query("SELECT * FROM settings WHERE id = 'main'");
|
||||
res.json(rows[0] ? JSON.parse(rows[0].data) : {});
|
||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
||||
});
|
||||
@@ -337,7 +335,11 @@ app.get('/api/settings', async (req, res) => {
|
||||
app.post('/api/settings', async (req, res) => {
|
||||
try {
|
||||
const data = JSON.stringify(req.body);
|
||||
await pool.query('INSERT INTO settings (id, category, data) VALUES ("main", "general", ?) ON DUPLICATE KEY UPDATE data = ?', [data, data]);
|
||||
await pool.query(
|
||||
`INSERT INTO settings (id, category, data) VALUES ('main', 'general', $1)
|
||||
ON CONFLICT (id) DO UPDATE SET data = EXCLUDED.data`,
|
||||
[data]
|
||||
);
|
||||
res.json({ success: true });
|
||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
||||
});
|
||||
@@ -347,8 +349,8 @@ app.post('/api/dentistas/magic-link', async (req, res) => {
|
||||
const { clinicaId, dentistName } = req.body;
|
||||
try {
|
||||
const token = Math.random().toString(36).substring(2, 15);
|
||||
// Em um sistema real, salvaríamos esse token em uma tabela de convites
|
||||
const magicLink = `http://localhost:3000/#/cadastro-dentista?token=${token}&clinica=${clinicaId}&nome=${encodeURIComponent(dentistName)}`;
|
||||
const appUrl = process.env.APP_URL || `http://localhost:${process.env.FRONTEND_PORT || 3000}`;
|
||||
const magicLink = `${appUrl}/#/cadastro-dentista?token=${token}&clinica=${clinicaId}&nome=${encodeURIComponent(dentistName)}`;
|
||||
res.json({ success: true, link: magicLink });
|
||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
||||
});
|
||||
@@ -437,7 +439,7 @@ app.get('/api/google/events', async (req, res) => {
|
||||
}
|
||||
|
||||
// 2. Legacy Support: Check Settings for Public Calendars (API KEY)
|
||||
const [rows] = await pool.query('SELECT data FROM settings WHERE id = "main"');
|
||||
const [rows] = await pool.query("SELECT data FROM settings WHERE id = 'main'");
|
||||
if (rows[0]) {
|
||||
const settings = JSON.parse(rows[0].data);
|
||||
const apiKey = settings.googleApiKey;
|
||||
@@ -513,7 +515,8 @@ app.get('/api/dashboard/stats', async (req, res) => {
|
||||
|
||||
// Recent appointments with patient and dentist names
|
||||
const { rows: recent } = await pool.query(`
|
||||
SELECT a.*, d.nome as dentistanome
|
||||
SELECT a.id, a.pacientenome, a.start_time, a.status,
|
||||
d.nome as "dentistaNome"
|
||||
FROM agendamentos a
|
||||
LEFT JOIN dentistas d ON a.dentistaid = d.id
|
||||
ORDER BY a.start_time DESC
|
||||
@@ -1159,7 +1162,7 @@ app.post('/api/gto-builder', async (req, res) => {
|
||||
const { pacienteId, dentistaId, credenciadaId } = req.body;
|
||||
const id = Math.random().toString(36).substring(2, 9).toUpperCase();
|
||||
await pool.query(
|
||||
'INSERT INTO gto_builders (id, pacienteId, dentistaId, credenciadaId, status, total) VALUES (?, ?, ?, ?, "RASCUNHO", 0)',
|
||||
"INSERT INTO gto_builders (id, pacienteId, dentistaId, credenciadaId, status, total) VALUES ($1, $2, $3, $4, 'RASCUNHO', 0)",
|
||||
[id, pacienteId, dentistaId, credenciadaId]
|
||||
);
|
||||
res.json({ id });
|
||||
@@ -1204,7 +1207,7 @@ app.delete('/api/gto-builder/:id/item/:itemId', async (req, res) => {
|
||||
|
||||
app.put('/api/gto-builder/:id/finalizar', async (req, res) => {
|
||||
try {
|
||||
await pool.query('UPDATE gto_builders SET status = "FINALIZADA" WHERE id = ?', [req.params.id]);
|
||||
await pool.query("UPDATE gto_builders SET status = 'FINALIZADA' WHERE id = $1", [req.params.id]);
|
||||
|
||||
// Logic to migrate to guias_odontologicas would go here in a real app
|
||||
// For now, we just mark as finished.
|
||||
@@ -1297,5 +1300,11 @@ async function generateIntelligentNotifications() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Start server after all routes are registered
|
||||
app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`[SERVER] Running on http://0.0.0.0:${PORT}`);
|
||||
// Run immediately on startup, then every 5 minutes
|
||||
generateIntelligentNotifications();
|
||||
setInterval(generateIntelligentNotifications, 5 * 60 * 1000);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user