2025-12-03 15:54:01 -03:00

97 lines
3.4 KiB
JavaScript

const express = require('express');
const multer = require('multer');
const cors = require('cors');
const fs = require('fs');
const path = require('path');
const OpenAI = require('openai/index.js');
require('dotenv').config();
const app = express();
const port = 3001; // O backend rodará na porta 3001
// Configurações de Segurança e JSON
app.use(cors());
app.use(express.json());
// Configuração da OpenAI
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// Configuração do Multer (Upload de arquivos temporários)
const upload = multer({ dest: 'uploads/' });
// Rota Principal: Recebe áudio e devolve JSON
app.post('/api/transcrever-relatorio', upload.single('audio'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'Nenhum arquivo de áudio enviado.' });
}
const audioPath = req.file.path;
try {
console.log("1. Recebendo áudio e iniciando transcrição...");
// PASSO 1: Whisper (Áudio -> Texto)
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream(audioPath),
model: "whisper-1",
language: "pt", // Força português para melhorar precisão médica
});
const textoTranscrevido = transcription.text;
console.log("Texto Transcrito:", textoTranscrevido);
console.log("2. Enviando para GPT-4 extrair dados...");
// PASSO 2: GPT-4o (Texto -> JSON Estruturado)
const completion = await openai.chat.completions.create({
model: "gpt-4o",
response_format: { type: "json_object" }, // Garante que volta JSON válido
messages: [
{
role: "system",
content: `
Você é um assistente médico especialista em estruturar laudos.
Sua tarefa é ler a transcrição de um ditado médico e extrair as informações para um JSON.
Os campos obrigatórios do JSON são:
- "exam": Nome do exame realizado.
- "diagnostico": O texto completo referente aos achados/diagnóstico. Melhore a pontuação e corrija termos médicos se necessário.
- "conclusao": O texto da conclusão ou impressão diagnóstica.
Se o médico não mencionar algum campo, deixe como string vazia "".
Não invente informações.
`
},
{
role: "user",
content: `Aqui está a transcrição do áudio: \n\n ${textoTranscrevido}`
}
]
});
// Parse do resultado da IA para Objeto JS
const dadosEstruturados = JSON.parse(completion.choices[0].message.content);
console.log("Dados Prontos:", dadosEstruturados);
// Devolve para o React
res.json(dadosEstruturados);
} catch (error) {
console.error("Erro no processamento:", error);
res.status(500).json({ error: 'Erro ao processar o áudio.' });
} finally {
// PASSO 3: Limpeza (Apagar o áudio da pasta uploads para não encher o servidor)
if (fs.existsSync(audioPath)) {
fs.unlinkSync(audioPath);
}
}
});
// Iniciar Servidor
app.listen(port, () => {
console.log(`🚀 Backend rodando em http://localhost:${port}`);
});