feat(agenda-bridge): /paciente-contexto (dentista responsável + tratamento)

Contexto interno do paciente p/ a Secretária dar continuidade: dentista responsável
(do orçamento aberto; fallback = agendamento mais recente) + em_tratamento. Por
paciente_id ou telefone.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
VPS 4 Builder
2026-07-08 08:12:13 +02:00
parent 7cfd14ae09
commit 1d0de944e1
+44
View File
@@ -1004,5 +1004,49 @@ export function createAgendaBridge(pool) {
} finally { try { client.release(); } catch { /* já liberado */ } }
});
// ── GET /paciente-contexto ────────────────────────────────────────────────────
// Contexto INTERNO do paciente p/ a Secretária: dentista responsável + se há
// tratamento em andamento. NÃO é p/ recitar ao cliente — serve p/ dar continuidade
// (agendar com o MESMO dentista) sem ficar falando de tratamento nem repetir nomes.
router.get('/paciente-contexto', async (req, res) => {
const clinicaId = String(req.query.clinica_id || '');
const pacienteId = req.query.paciente_id ? String(req.query.paciente_id) : null;
const tel = soDigitos(req.query.phone).slice(-8);
if (!clinicaId || (!pacienteId && !tel)) return res.status(400).json({ error: 'clinica_id e (paciente_id ou phone) obrigatórios' });
try {
let pacientes;
if (pacienteId) {
const { rows } = await pool.query('SELECT id, nome FROM pacientes WHERE id=$1 AND clinica_id=$2', [pacienteId, clinicaId]);
pacientes = rows;
} else {
const { rows } = await pool.query(
`SELECT id, nome FROM pacientes WHERE clinica_id=$1 AND regexp_replace(coalesce(telefone,''),'\\D','','g') LIKE '%'||$2`, [clinicaId, tel]);
pacientes = rows;
}
const out = [];
for (const p of pacientes) {
// Orçamento/tratamento em aberto → dentista responsável + em_tratamento.
const { rows: orc } = await pool.query(
`SELECT dentista_nome, dentista_id FROM orcamentos
WHERE paciente_id=$1 AND lower(coalesce(status,'')) NOT IN ('concluido','cancelado','recusado','rejeitado','finalizado')
ORDER BY created_at DESC NULLS LAST LIMIT 1`, [p.id]).catch(() => ({ rows: [] }));
let dentistaNome = orc[0]?.dentista_nome || null;
let dentistaId = orc[0]?.dentista_id || null;
let emTratamento = orc.length > 0;
if (!dentistaNome) {
const { rows: ag } = await pool.query(
`SELECT a.dentistaid, d.nome AS dentista, (a.start_time >= NOW() - interval '120 days') AS recente
FROM agendamentos a LEFT JOIN dentistas d ON d.id=a.dentistaid
WHERE a.pacienteid=$1 AND lower(coalesce(a.status,'agendado')) NOT IN ('cancelado','falta','faltou')
ORDER BY a.start_time DESC LIMIT 1`, [p.id]).catch(() => ({ rows: [] }));
dentistaNome = ag[0]?.dentista || null; dentistaId = ag[0]?.dentistaid || null;
if (ag[0]?.recente) emTratamento = true;
}
out.push({ paciente_id: p.id, nome: p.nome, dentista_responsavel: dentistaNome, dentista_id: dentistaId, em_tratamento: emTratamento });
}
res.json({ pacientes: out });
} catch (e) { res.status(500).json({ error: e.message }); }
});
return router;
}