feat(patients): fix date bug, convenio dropdown, redesign grupo familiar
- Fix dataNascimento date format error: convert dd/MM/yyyy → yyyy-MM-dd when loading EditarPacienteModal so <input type="date"> validates correctly - Change convênio field from free text to dropdown populated from planos table - Redesign grupo familiar: search a patient as family member instead of named group, with parentesco field (datalist with common options, accepts custom) - GET /api/pacientes: proper camelCase aliases, LEFT JOINs for grupoFamiliarNome and indicadoPorNome, sort parameter support (az/za/convenio/recentes) - Add startup migrations: ADD COLUMN IF NOT EXISTS for grupofamiliarid, grupofamiliarrelacao, indicadorporid on pacientes table - savePaciente: preserve caller-supplied id instead of overwriting with Math.random - Add grupoFamiliarRelacao to Paciente type Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+29
-3
@@ -728,14 +728,27 @@ app.put('/api/notificacoes/:id/read', async (req, res) => {
|
||||
// --- PACIENTES ---
|
||||
app.get('/api/pacientes', async (req, res) => {
|
||||
try {
|
||||
const { q } = req.query;
|
||||
const { q, sort } = req.query;
|
||||
const orderMap = { az: 'p.nome ASC', za: 'p.nome DESC', convenio: 'p.convenio ASC NULLS LAST, p.nome ASC', recentes: 'p.nome ASC' };
|
||||
const orderBy = orderMap[sort] || 'p.nome ASC';
|
||||
const base = `SELECT p.id, p.nome, p.cpf, p.telefone, p.email,
|
||||
p.ultimotratamento AS "ultimoTratamento",
|
||||
p.convenio, p.datanascimento AS "dataNascimento",
|
||||
p.grupofamiliarid AS "grupoFamiliarId",
|
||||
pf.nome AS "grupoFamiliarNome",
|
||||
p.grupofamiliarrelacao AS "grupoFamiliarRelacao",
|
||||
p.indicadorporid AS "indicadoPorId",
|
||||
pi.nome AS "indicadoPorNome"
|
||||
FROM pacientes p
|
||||
LEFT JOIN pacientes pf ON pf.id = p.grupofamiliarid
|
||||
LEFT JOIN pacientes pi ON pi.id = p.indicadorporid`;
|
||||
let text, params;
|
||||
if (q && q.trim()) {
|
||||
const term = `%${q.trim().toUpperCase()}%`;
|
||||
text = `SELECT * FROM pacientes WHERE UPPER(nome) LIKE $1 OR cpf LIKE $1 ORDER BY nome LIMIT 100`;
|
||||
text = `${base} WHERE UPPER(p.nome) LIKE $1 OR p.cpf LIKE $1 ORDER BY ${orderBy} LIMIT 100`;
|
||||
params = [term];
|
||||
} else {
|
||||
text = `SELECT * FROM pacientes ORDER BY nome LIMIT 50`;
|
||||
text = `${base} ORDER BY ${orderBy} LIMIT 50`;
|
||||
params = [];
|
||||
}
|
||||
const { rows } = await pool.query(text, params);
|
||||
@@ -1652,10 +1665,23 @@ async function generateIntelligentNotifications() {
|
||||
}
|
||||
}
|
||||
|
||||
async function runMigrations() {
|
||||
const migrations = [
|
||||
`ALTER TABLE pacientes ADD COLUMN IF NOT EXISTS grupofamiliarid TEXT`,
|
||||
`ALTER TABLE pacientes ADD COLUMN IF NOT EXISTS grupofamiliarrelacao TEXT`,
|
||||
`ALTER TABLE pacientes ADD COLUMN IF NOT EXISTS indicadorporid TEXT`,
|
||||
];
|
||||
for (const sql of migrations) {
|
||||
try { await pool.query(sql); } catch (e) { console.error('[MIGRATION]', e.message); }
|
||||
}
|
||||
console.log('[MIGRATION] pacientes columns OK');
|
||||
}
|
||||
|
||||
// Start server after all routes are registered
|
||||
app.listen(PORT, '0.0.0.0', async () => {
|
||||
console.log(`[SERVER] Running on http://0.0.0.0:${PORT}`);
|
||||
await loadGoogleCredsFromDb();
|
||||
await runMigrations();
|
||||
generateIntelligentNotifications();
|
||||
setInterval(generateIntelligentNotifications, 5 * 60 * 1000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user