Merge branch 'claude/youthful-mendel-0c569f'
This commit is contained in:
+21
-18
@@ -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 });
|
||||
|
||||
Reference in New Issue
Block a user