feat(newwhats): agenda inteligente — especialidades, situações, dúvidas, checklist do dono e pendências
Satélite da Secretária IA: - /contexto (dentistas+especialidades+situações+cautelas) e /duvida (encaminhar ao humano sem agendar); agenda_pedidos ganha tipo=duvida + resumo. - Situações da clínica: tabela agenda_situacoes + config (dono) + aba na UI. - Checklist do dono (checklist-defs.js + agenda_checklist): perguntas Sim/Não conferidas contra o banco (dentistas/pacientes) → pendências de config + cautelas p/ a IA não chutar. - Área de PENDÊNCIAS DO DONO (PendenciasDono.tsx): engloba config + fila operacional (horários/dúvidas); botão+badge no /wa-secretaria (só o dono). - Fila humana (PedidosPendentes): cards de dúvida + resolver; /resolver. - Botão DESLIGAR global da Secretária no ThinNav (secPowerApi, visível a todos). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
// Checklist do DONO do workspace: perguntas Sim/Não sobre a clínica que a
|
||||
// Secretária IA usa para saber quando PODE agendar sozinha e quando deve ter
|
||||
// cautela. As respostas são conferidas contra o banco (dentistas/pacientes):
|
||||
// quando a declaração do dono não bate com os dados, geramos uma PENDÊNCIA
|
||||
// para ele configurar/cadastrar — e a IA fica cautelosa (encaminha ao humano).
|
||||
//
|
||||
// Fonte única: config (UI), consistência (pendências) e injeção no cérebro
|
||||
// (cautelas) consomem esta mesma definição para nunca divergirem.
|
||||
|
||||
export const CHECKLIST_QUESTOES = [
|
||||
{
|
||||
chave: 'multi_dentista',
|
||||
pergunta: 'A clínica tem mais de um dentista?',
|
||||
ajuda: 'Se sim, a Secretária não pode assumir um único dentista nem "clínico geral" por padrão — precisa saber quem atende cada paciente.',
|
||||
},
|
||||
{
|
||||
chave: 'pacientes_cadastrados',
|
||||
pergunta: 'Os pacientes já estão cadastrados no sistema (/pacientes)?',
|
||||
ajuda: 'Sem os pacientes cadastrados, a Secretária não reconhece quem já é paciente e encaminha os retornos para a secretária humana confirmar.',
|
||||
},
|
||||
{
|
||||
chave: 'dentista_fixo',
|
||||
pergunta: 'Cada paciente tem um dentista de referência (fixo)?',
|
||||
ajuda: 'Se sim, um paciente de retorno deve voltar para o MESMO dentista — a IA não deve agendá-lo no clínico geral.',
|
||||
},
|
||||
];
|
||||
|
||||
const sim = (r, k) => r[k] === 1;
|
||||
const nao = (r, k) => r[k] === 0;
|
||||
|
||||
// Pendências de CONFIG do dono: a declaração não bate com o banco.
|
||||
// counts = { dentistas, pacientes }.
|
||||
export function pendenciasDeConfig(respostas, counts) {
|
||||
const r = respostas || {};
|
||||
const dentistas = Number(counts?.dentistas || 0);
|
||||
const pacientes = Number(counts?.pacientes || 0);
|
||||
const P = [];
|
||||
|
||||
if (sim(r, 'multi_dentista') && dentistas <= 1)
|
||||
P.push({ chave: 'multi_dentista', severidade: 'alta', titulo: 'Cadastre os demais dentistas',
|
||||
detalhe: `Você indicou que a clínica tem mais de um dentista, mas há apenas ${dentistas} cadastrado. A Secretária não consegue direcionar cada paciente ao dentista certo — cadastre os outros dentistas.` });
|
||||
if (nao(r, 'multi_dentista') && dentistas > 1)
|
||||
P.push({ chave: 'multi_dentista', severidade: 'media', titulo: 'Confirme quantos dentistas atendem',
|
||||
detalhe: `Você indicou um único dentista, mas há ${dentistas} cadastrados no sistema. Ajuste a resposta ou os cadastros.` });
|
||||
|
||||
if (sim(r, 'pacientes_cadastrados') && pacientes === 0)
|
||||
P.push({ chave: 'pacientes_cadastrados', severidade: 'alta', titulo: 'Cadastre os pacientes',
|
||||
detalhe: 'Você indicou que os pacientes estão cadastrados, mas não há nenhum paciente no sistema. A Secretária não reconhece quem já é paciente.' });
|
||||
if (r['pacientes_cadastrados'] == null || nao(r, 'pacientes_cadastrados'))
|
||||
P.push({ chave: 'pacientes_cadastrados', severidade: 'media', titulo: 'Complete o cadastro de pacientes',
|
||||
detalhe: 'Enquanto os pacientes não estiverem cadastrados, a Secretária vai encaminhar todo retorno para a secretária humana confirmar (não agenda sozinha).' });
|
||||
|
||||
if (sim(r, 'dentista_fixo') && dentistas <= 1 && sim(r, 'multi_dentista'))
|
||||
P.push({ chave: 'dentista_fixo', severidade: 'media', titulo: 'Cadastre os dentistas de referência',
|
||||
detalhe: 'Você indicou que cada paciente tem um dentista fixo, mas o sistema ainda não tem os dentistas todos cadastrados para fazer esse vínculo.' });
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
// Cautelas para injetar no cérebro da IA (texto direto no system prompt).
|
||||
export function cautelasParaIA(respostas, counts) {
|
||||
const r = respostas || {};
|
||||
const dentistas = Number(counts?.dentistas || 0);
|
||||
const pacientes = Number(counts?.pacientes || 0);
|
||||
const C = [];
|
||||
|
||||
const multi = sim(r, 'multi_dentista') || dentistas > 1;
|
||||
if (multi)
|
||||
C.push('A clínica tem MAIS DE UM dentista: NUNCA assuma um dentista nem "clínico geral" por padrão para quem já é paciente. Descubra/pergunte qual dentista atende. Sem certeza → encaminhe ao humano.');
|
||||
if (sim(r, 'multi_dentista') && dentistas <= 1)
|
||||
C.push('ATENÇÃO: o sistema ainda não tem todos os dentistas cadastrados. Para pacientes de retorno ou que pedem um dentista específico, encaminhe ao humano — NÃO agende no clínico geral.');
|
||||
if (sim(r, 'dentista_fixo'))
|
||||
C.push('Cada paciente tem um dentista fixo: um retorno deve voltar ao MESMO dentista. Se você não sabe qual é (falta cadastro), encaminhe ao humano.');
|
||||
if (pacientes === 0 || nao(r, 'pacientes_cadastrados'))
|
||||
C.push('O cadastro de pacientes está incompleto: você NÃO consegue confirmar histórico nem o dentista de quem diz já ser paciente. Nesses casos, encaminhe ao humano em vez de agendar.');
|
||||
|
||||
return C;
|
||||
}
|
||||
Reference in New Issue
Block a user