// Rotas /nw/* — a Secretária IA do motor consulta os dados desta clínica. // Adaptado do satélite mercado para o domínio ODONTO (scoreodonto). // Todas as rotas exigem a integration_key (nwAuth). import { Router } from 'express' import { nwAuth } from './auth.js' import { getConfig } from './config.js' const money = (v) => v == null ? null : `R$ ${Number(v).toFixed(2).replace('.', ',')}` // Resolve a clínica-alvo: query ?clinica_id= tem prioridade; senão a do config. function resolveClinicaId(req) { return String(req.query.clinica_id || getConfig().clinicaId || '').trim() } export function createRoutes(pool) { const router = Router() router.use(nwAuth) const needClinica = (req, res) => { const id = resolveClinicaId(req) if (!id) res.status(400).json({ error: 'clinica_id ausente (configure NEWWHATS_CLINICA_ID ou passe ?clinica_id=).' }) return id } router.get('/ping', (_req, res) => res.json({ ok: true, service: 'scoreodonto', ts: new Date().toISOString() })) // Dados da clínica router.get('/clinica', async (req, res) => { const id = needClinica(req, res); if (!id) return try { const { rows } = await pool.query( `SELECT nome_fantasia, telefone, cidade, estado, logradouro, numero, bairro, cep FROM clinicas WHERE id = $1`, [id]) res.json(rows[0] || null) } catch (e) { res.status(500).json({ error: e.message }) } }) // Especialidades atendidas router.get('/especialidades', async (req, res) => { const id = needClinica(req, res); if (!id) return try { const { rows } = await pool.query( `SELECT nome, descricao, area FROM especialidades WHERE clinica_id = $1 AND ativo::int = 1 ORDER BY ordem NULLS LAST, nome`, [id]) res.json(rows) } catch (e) { res.status(500).json({ error: e.message }) } }) // Dentistas + horários de atendimento router.get('/dentistas', async (req, res) => { const id = needClinica(req, res); if (!id) return try { const { rows: dentistas } = await pool.query( `SELECT id, nome, especialidade FROM dentistas WHERE clinica_id = $1 AND ativo::int = 1 ORDER BY ordem NULLS LAST, nome`, [id]) for (const d of dentistas) { const { rows: hr } = await pool.query( `SELECT dia_semana, hora_inicio, hora_fim FROM dentistas_horarios WHERE dentista_id = $1 AND ativo::int = 1 ORDER BY dia_semana, hora_inicio`, [d.id]) d.horarios = hr delete d.id } res.json(dentistas) } catch (e) { res.status(500).json({ error: e.message }) } }) // Procedimentos + valor particular + valores por plano router.get('/procedimentos', async (req, res) => { const id = needClinica(req, res); if (!id) return try { const { rows: procs } = await pool.query( `SELECT id, nome, descricao, categoria, valorparticular FROM procedimentos WHERE clinica_id = $1 AND ativo::int = 1 ORDER BY ordem NULLS LAST, nome`, [id]) for (const p of procs) { const { rows: vp } = await pool.query( `SELECT planonome, valor FROM procedimentos_valores_planos WHERE procedimentoid = $1`, [p.id]) p.valor_particular = money(p.valorparticular) p.valores_planos = vp.map((x) => ({ plano: x.planonome, valor: money(x.valor) })) delete p.id; delete p.valorparticular } res.json(procs) } catch (e) { res.status(500).json({ error: e.message }) } }) // Planos / convênios aceitos router.get('/planos', async (req, res) => { const id = needClinica(req, res); if (!id) return try { const { rows } = await pool.query( `SELECT nome, tipo, descontopadrao FROM planos WHERE clinica_id = $1 ORDER BY nome`, [id]) res.json(rows) } catch (e) { res.status(500).json({ error: e.message }) } }) return router }