Files
rx.scoreodonto.com/dental-server/routes/gtos.js
T
VPS 4 Builder 5b0d80bf22
continuous-integration/webhook Deploy concluido (rx.scoreodonto.com)
feat: reestruturacao de menus na sidebar, niveis de acesso e migracao para postgresql/dragonflydb
2026-05-26 21:08:48 +02:00

158 lines
5.9 KiB
JavaScript

const express = require('express');
const router = express.Router();
const db = require('../database');
// ================================================================
// GET /api/gtos?patient=nome — listar GTOs de um paciente
// GET /api/gtos — listar todas as GTOs
// ================================================================
router.get('/', async (req, res) => {
try {
const { patient } = req.query;
let rows;
if (patient) {
rows = await db.all(
`SELECT g.*, COUNT(gi.id) as image_count
FROM gtos g
LEFT JOIN gto_images gi ON gi.gto_id = g.id
WHERE g.patient_name = $1
GROUP BY g.id
ORDER BY g.created_at DESC`,
[patient]
);
} else {
rows = await db.all(
`SELECT g.*, COUNT(gi.id) as image_count
FROM gtos g
LEFT JOIN gto_images gi ON gi.gto_id = g.id
GROUP BY g.id
ORDER BY g.created_at DESC
LIMIT 200`
);
}
res.json(rows);
} catch (err) {
console.error('Erro ao listar GTOs:', err);
res.status(500).json({ error: err.message });
}
});
// ================================================================
// GET /api/gtos/:id — detalhe de uma GTO com imagens vinculadas
// ================================================================
router.get('/:id', async (req, res) => {
try {
const gto = await db.get('SELECT * FROM gtos WHERE id = $1', [req.params.id]);
if (!gto) return res.status(404).json({ error: 'GTO não encontrada' });
const images = await db.all(
`SELECT i.*, gi.id as link_id
FROM gto_images gi
JOIN images i ON i.id = gi.image_id
WHERE gi.gto_id = $1
ORDER BY gi.created_at DESC`,
[req.params.id]
);
res.json({ ...gto, images });
} catch (err) {
console.error('Erro ao buscar GTO:', err);
res.status(500).json({ error: err.message });
}
});
// ================================================================
// POST /api/gtos — criar nova GTO
// Body: { gto_number, patient_name, description }
// ================================================================
router.post('/', async (req, res) => {
try {
const { gto_number, patient_name, description } = req.body;
if (!gto_number || !patient_name) {
return res.status(400).json({ error: 'gto_number e patient_name são obrigatórios' });
}
const result = await db.run(
`INSERT INTO gtos (gto_number, patient_name, description) VALUES ($1, $2, $3) RETURNING id`,
[gto_number.trim(), patient_name.trim(), description || '']
);
const gto = await db.get('SELECT * FROM gtos WHERE id = $1', [result.lastID]);
res.status(201).json(gto);
} catch (err) {
console.error('Erro ao criar GTO:', err);
res.status(500).json({ error: err.message });
}
});
// ================================================================
// PUT /api/gtos/:id — atualizar GTO
// ================================================================
router.put('/:id', async (req, res) => {
try {
const { gto_number, description } = req.body;
await db.run(
`UPDATE gtos SET gto_number = $1, description = $2 WHERE id = $3`,
[gto_number, description || '', req.params.id]
);
const gto = await db.get('SELECT * FROM gtos WHERE id = $1', [req.params.id]);
res.json(gto);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// ================================================================
// DELETE /api/gtos/:id — remover GTO e vínculos
// ================================================================
router.delete('/:id', async (req, res) => {
try {
await db.run('DELETE FROM gto_images WHERE gto_id = $1', [req.params.id]);
await db.run('DELETE FROM gtos WHERE id = $1', [req.params.id]);
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// ================================================================
// POST /api/gtos/:id/images — vincular imagem à GTO
// Body: { image_id }
// ================================================================
router.post('/:id/images', async (req, res) => {
try {
const { image_id } = req.body;
if (!image_id) return res.status(400).json({ error: 'image_id é obrigatório' });
// Verificar se já está vinculada
const existing = await db.get(
'SELECT id FROM gto_images WHERE gto_id = $1 AND image_id = $2',
[req.params.id, image_id]
);
if (existing) return res.status(409).json({ error: 'Imagem já vinculada a esta GTO' });
await db.run(
'INSERT INTO gto_images (gto_id, image_id) VALUES ($1, $2) RETURNING id',
[req.params.id, image_id]
);
res.status(201).json({ success: true, message: 'Imagem vinculada à GTO' });
} catch (err) {
console.error('Erro ao vincular imagem:', err);
res.status(500).json({ error: err.message });
}
});
// ================================================================
// DELETE /api/gtos/:id/images/:imageId — desvincular imagem
// ================================================================
router.delete('/:id/images/:imageId', async (req, res) => {
try {
await db.run(
'DELETE FROM gto_images WHERE gto_id = $1 AND image_id = $2',
[req.params.id, req.params.imageId]
);
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
module.exports = router;