From dd0a5abb0439eff10f3152eb1bb5d6f553e38201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Gustavo?= <166467972+JoaoGustavo-dev@users.noreply.github.com> Date: Sat, 15 Nov 2025 22:04:25 -0300 Subject: [PATCH 01/14] add-report-notification --- susconecta/app/profissional/page.tsx | 4 + susconecta/lib/laudo-exemplos.ts | 275 +++++++++++++++++++++++++++ susconecta/lib/laudo-notification.ts | 193 +++++++++++++++++++ susconecta/lib/reportService.ts | 148 ++++++++++++++ susconecta/lib/reports.ts | 178 ++++++++++++++++- 5 files changed, 797 insertions(+), 1 deletion(-) create mode 100644 susconecta/lib/laudo-exemplos.ts create mode 100644 susconecta/lib/laudo-notification.ts create mode 100644 susconecta/lib/reportService.ts diff --git a/susconecta/app/profissional/page.tsx b/susconecta/app/profissional/page.tsx index e800161..85e6a64 100644 --- a/susconecta/app/profissional/page.tsx +++ b/susconecta/app/profissional/page.tsx @@ -13,6 +13,7 @@ import { buscarPacientes, listarPacientes, buscarPacientePorId, buscarPacientesP import { ENV_CONFIG } from '@/lib/env-config'; import { useReports } from "@/hooks/useReports"; import { CreateReportData } from "@/types/report-types"; +import { createAndNotifyReport } from "@/lib/reportService"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; @@ -2588,6 +2589,9 @@ const ProfissionalPage = () => { if (isNewLaudo) { if (createNewReport) { const created = await createNewReport(payload as any); + console.log('[LaudoEditor] Report criado:', { created, patient_id: payload.patient_id }); + // ✅ Webhook agora é enviado automaticamente dentro de createNewReport() / criarRelatorio() + if (onSaved) onSaved(created); } } else { diff --git a/susconecta/lib/laudo-exemplos.ts b/susconecta/lib/laudo-exemplos.ts new file mode 100644 index 0000000..14f6b02 --- /dev/null +++ b/susconecta/lib/laudo-exemplos.ts @@ -0,0 +1,275 @@ +/** + * EXEMPLO DE USO: Automação n8n para Notificação de Laudos + * + * Este arquivo demonstra como usar a função criarLaudo com integração n8n + * para criar um laudo e notificar automaticamente o paciente. + */ + +import { criarLaudo, CriarLaudoData } from '@/lib/reports'; + +/** + * Exemplo 1: Uso básico - criar um laudo simples + */ +export async function exemploBasico() { + try { + const laudoData: CriarLaudoData = { + pacienteId: 'patient-uuid-123', // ID do paciente (obrigatório) + textoLaudo: 'Paciente apresenta boa saúde geral. Sem achados relevantes.', + }; + + const novoLaudo = await criarLaudo(laudoData); + + console.log('✓ Laudo criado com sucesso!'); + console.log('ID do laudo:', novoLaudo.id); + console.log('Mensagem:', novoLaudo.mensagem); + + return novoLaudo; + } catch (erro) { + console.error('✗ Erro ao criar laudo:', erro); + throw erro; + } +} + +/** + * Exemplo 2: Criar laudo com dados médicos completos + */ +export async function exemploCompleto() { + try { + const laudoData: CriarLaudoData = { + pacienteId: 'patient-uuid-789', + medicoId: 'doctor-uuid-456', // Opcional + textoLaudo: ` + AVALIAÇÃO CLÍNICA COMPLETA + + Queixa Principal: Dor de cabeça persistente + + História Presente: + Paciente relata dor de cabeça tipo tensional há 2 semanas, + intensidade 5/10, sem irradiação. + + Exame Físico: + - PA: 120/80 mmHg + - FC: 72 bpm + - Sem alterações neurológicas + + Impressão Diagnóstica: + Cefaleia tensional + + Conduta: + - Repouso adequado + - Analgésicos conforme necessidade + - Retorno em 2 semanas se persistir + `, + exame: 'Consulta Neurologia', + diagnostico: 'Cefaleia tensional', + conclusao: 'Prescrição: Dipirona 500mg 6/6h conforme necessidade', + cidCode: 'G44.2', // CID da cefaleia tensional + status: 'concluido', + }; + + const novoLaudo = await criarLaudo(laudoData); + + console.log('✓ Laudo completo criado com sucesso!'); + console.log('ID:', novoLaudo.id); + console.log('Status:', novoLaudo.status); + console.log('CID:', novoLaudo.cid_code); + + return novoLaudo; + } catch (erro) { + console.error('✗ Erro:', erro); + throw erro; + } +} + +/** + * Exemplo 3: Integração em um componente React + * Este exemplo mostra como usar a função em um formulário + * + * NOTA: Este código deve ser usado em um arquivo .tsx (não .ts) + * e com o import de React importado corretamente + */ +export async function exemploComponenteReact() { + // Este é apenas um exemplo de estrutura para o componente + // Copie o código abaixo para um arquivo .tsx: + /* + 'use client'; + + import React from 'react'; + import { criarLaudo, CriarLaudoData } from '@/lib/reports'; + + export function ComponenteLaudoExemplo() { + const [carregando, setCarregando] = React.useState(false); + const [mensagem, setMensagem] = React.useState(''); + + const handleCriarLaudo = async (formData: any) => { + setCarregando(true); + setMensagem(''); + + try { + const laudoData: CriarLaudoData = { + pacienteId: formData.pacienteId, + medicoId: formData.medicoId, + textoLaudo: formData.texto, + exame: formData.exame, + diagnostico: formData.diagnostico, + conclusao: formData.conclusao, + cidCode: formData.cid, + status: 'concluido', + }; + + const resultado = await criarLaudo(laudoData); + + setMensagem(`✓ ${resultado.mensagem}`); + console.log('Laudo criado:', resultado.id); + + // Você pode fazer mais algo aqui, como: + // - Redirecionar para página do laudo + // - Atualizar lista de laudos + // - Limpar formulário + + } catch (erro) { + setMensagem(`✗ Erro: ${erro instanceof Error ? erro.message : String(erro)}`); + } finally { + setCarregando(false); + } + }; + + return ( +
+
{ + e.preventDefault(); + const formData = new FormData(e.currentTarget); + handleCriarLaudo(Object.fromEntries(formData)); + }}> +