Merge branch 'claude/youthful-mendel-0c569f'

This commit is contained in:
VPS 4 Builder
2026-05-14 04:18:31 +02:00
+21 -18
View File
@@ -39,22 +39,24 @@ async function withTransaction(fn) {
}
// Helper: build INSERT query from plain object (PG native)
// Keys are lowercased to match PG's case-folded column storage.
function buildInsert(table, obj) {
const allowed = Object.entries(obj).filter(([, v]) => v !== undefined && v !== null || typeof v === 'boolean' || v === 0);
const keys = allowed.map(([k]) => k);
const keys = allowed.map(([k]) => k.toLowerCase());
const vals = allowed.map(([, v]) => v);
const cols = keys.map(k => `"${k}"`).join(', ');
const cols = keys.join(', ');
const placeholders = keys.map((_, i) => `$${i + 1}`).join(', ');
return { text: `INSERT INTO ${table} (${cols}) VALUES (${placeholders})`, values: vals };
}
// Helper: build UPDATE SET clause from plain object (PG native)
// Keys are lowercased to match PG's case-folded column storage.
function buildUpdate(table, obj, whereCol, whereVal) {
const skip = new Set(['id', 'createdAt', 'created_at']);
const entries = Object.entries(obj).filter(([k, v]) => !skip.has(k) && v !== undefined);
const set = entries.map(([k], i) => `"${k}" = $${i + 1}`).join(', ');
const skip = new Set(['id', 'createdat', 'created_at']);
const entries = Object.entries(obj).filter(([k, v]) => !skip.has(k.toLowerCase()) && v !== undefined);
const set = entries.map(([k], i) => `${k.toLowerCase()} = $${i + 1}`).join(', ');
const values = [...entries.map(([, v]) => v), whereVal];
return { text: `UPDATE ${table} SET ${set} WHERE "${whereCol}" = $${entries.length + 1}`, values };
return { text: `UPDATE ${table} SET ${set} WHERE ${whereCol.toLowerCase()} = $${entries.length + 1}`, values };
}
// Helper: convert PostgreSQL error codes to friendly messages
@@ -290,7 +292,7 @@ app.post('/api/dentistas/register', async (req, res) => {
// 3. Create or update Dentist record for agenda
await client.query(`
INSERT INTO dentistas (id, clinica_id, nome, email, telefone, especialidade, "corAgenda")
INSERT INTO dentistas (id, clinica_id, nome, email, telefone, especialidade, coragenda)
VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (id) DO UPDATE SET
nome = EXCLUDED.nome, especialidade = EXCLUDED.especialidade
@@ -917,7 +919,7 @@ app.put('/api/procedimentos/:id', async (req, res) => {
await withTransaction(async (client) => {
const upd = buildUpdate('procedimentos', updateData, 'id', req.params.id);
await client.query(upd.text, upd.values);
await client.query('DELETE FROM procedimentos_valores_planos WHERE "procedimentoId" = $1', [req.params.id]);
await client.query('DELETE FROM procedimentos_valores_planos WHERE procedimentoid = $1', [req.params.id]);
if (valoresPlanos && valoresPlanos.length > 0) {
for (const v of valoresPlanos) {
const vIns = buildInsert('procedimentos_valores_planos', { ...v, procedimentoId: req.params.id });
@@ -1008,13 +1010,13 @@ app.get('/api/guias', async (req, res) => {
let paramIdx = 1;
if (gto) {
where += ` AND ("numeroGuiaPrestador" LIKE $${paramIdx} OR "numeroGuiaOperadora" LIKE $${paramIdx + 1})`;
where += ` AND (numeroguiaprestador LIKE $${paramIdx} OR numeroguiaoperadora LIKE $${paramIdx + 1})`;
params.push(`%${gto}%`, `%${gto}%`);
paramIdx += 2;
}
if (search) {
where += ` AND ("beneficiarioNome" LIKE $${paramIdx} OR "beneficiarioIdentificacao" LIKE $${paramIdx + 1})`;
where += ` AND (beneficiarionome LIKE $${paramIdx} OR beneficiarioidentificacao LIKE $${paramIdx + 1})`;
params.push(`%${search}%`, `%${search}%`);
paramIdx += 2;
}
@@ -1026,20 +1028,21 @@ app.get('/api/guias', async (req, res) => {
}
if (dataInicio) {
where += ` AND "dataSolicitacao" >= $${paramIdx}`;
where += ` AND datasolicitacao >= $${paramIdx}`;
params.push(dataInicio);
paramIdx++;
}
if (dataFim) {
where += ` AND "dataSolicitacao" <= $${paramIdx}`;
where += ` AND datasolicitacao <= $${paramIdx}`;
params.push(dataFim);
paramIdx++;
}
// Validate sortField and sortOrder to prevent SQL injection
const allowedSortFields = ['dataSolicitacao', 'beneficiarioNome', 'status', 'numeroGuiaPrestador'];
const finalSortField = allowedSortFields.includes(sortField) ? `"${sortField}"` : '"dataSolicitacao"';
const allowedSortFields = ['datasolicitacao', 'beneficiarionome', 'status', 'numeroguiaprestador'];
const normalizedSort = sortField.toLowerCase();
const finalSortField = allowedSortFields.includes(normalizedSort) ? normalizedSort : 'datasolicitacao';
const finalSortOrder = sortOrder.toUpperCase() === 'ASC' ? 'ASC' : 'DESC';
const query = `
@@ -1071,7 +1074,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 ($1, $2, $3, $4, '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 });
@@ -1081,7 +1084,7 @@ app.post('/api/gto-builder', async (req, res) => {
app.get('/api/gto-builder/:id', async (req, res) => {
try {
const { rows: builder } = await pool.query('SELECT * FROM gto_builders WHERE id = $1', [req.params.id]);
const { rows: items } = await pool.query('SELECT * FROM gto_items WHERE "builderId" = $1', [req.params.id]);
const { rows: items } = await pool.query('SELECT * FROM gto_items WHERE builderid = $1', [req.params.id]);
res.json({ ...builder[0], items });
} catch (err) { res.status(500).json({ error: err.message }); }
});
@@ -1095,7 +1098,7 @@ app.post('/api/gto-builder/:id/item', async (req, res) => {
// Update total
await pool.query(
'UPDATE gto_builders SET total = (SELECT SUM("valorTotal") FROM gto_items WHERE "builderId" = $1) WHERE id = $2',
'UPDATE gto_builders SET total = (SELECT SUM(valortotal) FROM gto_items WHERE builderid = $1) WHERE id = $2',
[req.params.id, req.params.id]
);
@@ -1108,7 +1111,7 @@ app.delete('/api/gto-builder/:id/item/:itemId', async (req, res) => {
await pool.query('DELETE FROM gto_items WHERE id = $1', [req.params.itemId]);
// Update total
await pool.query(
'UPDATE gto_builders SET total = COALESCE((SELECT SUM("valorTotal") FROM gto_items WHERE "builderId" = $1), 0) WHERE id = $2',
'UPDATE gto_builders SET total = COALESCE((SELECT SUM(valortotal) FROM gto_items WHERE builderid = $1), 0) WHERE id = $2',
[req.params.id, req.params.id]
);
res.json({ success: true });