Secretária IA mais segura e contextual:
- Roteamento por especialidade: /contexto (dentistas+especialidades) injetado no
cérebro; descobrir o motivo e priorizar clínico geral só p/ avaliação/limpeza.
- Situações da clínica: regras editáveis injetadas no prompt (siga à risca).
- Dúvida/caso incerto → tool encaminhar_humano (não agenda; pede p/ aguardar).
- Imagem/áudio: ext:message.transcription religa no fluxo ext:message.new
(guard hadCaption evita processar 2x); a IA reage à descrição da imagem.
- Checklist do dono × banco → cautelas no /contexto: NÃO assumir clínico geral
por padrão p/ quem já é paciente; sem certeza de quem/qual dentista → humano.
- Desligar GLOBAL da Secretária: GET/POST /secretaria/power (kill-switch
auto_reply via config.set, efeito imediato, sem restart; visível a todos).
Inclui a plumbing da sessão (chat.upsert, ownership de conexão, ws-bridge).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move a transcrição para o motor (genérica p/ todos os tenants/satélites):
- media-transcribe.ts: Gemini 2.0 Flash (áudio→texto, imagem→descrição) a partir
do buffer já baixado; limite inline 18MB; fallback silencioso.
- MessageHandler.processMedia: após salvar a mídia, transcreve fire-and-forget e
grava em messages.transcription, emitindo 'message:transcription' p/ a UI.
- schema: campo Message.transcription (coluna aplicada nos bancos).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Detecta WhatsApp Business (app) via getBusinessProfile no pós-conexão e
persiste em instances.isBusiness; painel mostra "Conta Business: sim/não"
(com nota Business App ≠ Business API).
- Painel avisa que trocar de API desconecta e exige escanear o QR novamente,
com confirmação antes de aplicar a troca.
- sendRichMessage agora monitora e loga erros especificamente quando a mensagem
tem botões/lista/carrossel (diagnóstico de rejeição de interativos por engine).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Adiciona @@index nas FKs que sofrem cascade/SET NULL ao deletar instância:
messages.replyToId (self-ref, evitava O(n²) no SET NULL), chats.instanceId,
chats.contactId, contacts.instanceId, broadcasts.instanceId.
- InstanceRepository.delete agora apaga 'messages' em lotes (5k) antes do
cascade, evitando transação/locks gigantes em instâncias com dezenas de
milhares de mensagens. O restante (chats/contacts/...) sai pelo cascade,
agora rápido com os índices.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>