HL7 MLLP Gateway

Entre com as credenciais configuradas no servidor.

HTTP-
Destino MLLP-
Listener P05-
Webhook-

Monitor

Enviados hoje0
Laudos recebidos0
ACK AA0%
Falhas hoje0

Eventos recentes

Hora Direção Tipo Paciente Accession Controle ACK ms

Histórico persistido

Hora Direção Tipo Origem Paciente Accession ACK ms Webhook

Formulário P01

MSH
PID
IN1 / ORC
Como testar ORC-1:
  • NW — Novo pedido. Use um placerOrder e accession novos para o paciente.
  • XO — Alteração. Reaproveite placerOrder/accession de um pedido já enviado e altere algum atributo (data, descrição, prioridade).
  • CA — Cancelamento. Mantenha placerOrder/accession originais do pedido a cancelar.
OBX (observação clínica)

Layouts de integração

Envio de exame P01

POST /hl7/send aceita HL7 bruto, HL7 com frame MLLP ou JSON estruturado. Quando recebe JSON, o gateway valida os campos e monta uma mensagem ORM^O01 HL7 2.4 antes de encaminhar ao destino MLLP.

O payload original (HL7 ou JSON) é preservado no evento e pode ser baixado em GET /api/events/:id/download?kind=raw.

Obtenção de laudos P05

O PACS/Mirth envia ORU^R01 para o listener MLLP local em REPORT_MLLP_HOST/REPORT_MLLP_PORT. O gateway grava o evento, responde ACK e, se houver webhook configurado, encaminha o laudo para a aplicação de terceiro.

O HL7 do laudo é preservado no evento e pode ser baixado individualmente como .hl7, .ack, JSON técnico ou payload original.

Contrato JSON de worklist

Atributo Obrigatório Referência HL7 Exemplo Descrição
msh.sendingApplication Sim MSH-3 RISAPP Aplicação remetente.
msh.sendingFacility Sim MSH-4 RISFAC Facilidade remetente.
msh.receivingApplication Sim MSH-5 PIXEON Destino, normalmente Pixeon.
msh.receivingFacility Sim MSH-6 MEDREPORT Facilidade destino.
msh.messageControlId Não MSH-10 6467855 ID único. Se ausente, gerado automaticamente.
patient.id Sim PID-3.1 25200 Código interno do paciente.
patient.cpf Não PID-3.2 00032145690 CPF.
patient.rg Não PID-3.3 3024678798 RG ou outro documento.
patient.familyName Sim PID-5.1 PIXEON Sobrenome.
patient.givenName Sim PID-5.2 PACIENTE Primeiro nome.
patient.middleName Não PID-5.3 DE TESTE Nome do meio.
patient.preferredName Não PID-5.15 Nome social.
patient.birthDate Sim PID-7 19830824 Formato yyyyMMdd.
patient.sex Sim PID-8 M Aceita F, M, O, U.
insurance.planId Não IN1-2.1 15 ID do plano.
insurance.planName Não IN1-2.2 PLANO DE SAUDE Nome do plano.
insurance.companyId Não IN1-3 5 ID do convênio.
insurance.companyName Não IN1-4 CONVENIO Nome do convênio.
order.control Sim ORC-1 NW NW novo, XO alteração, CA cancelamento.
order.placerOrder Sim ORC-2 / OBR-2 1437 Número da requisição/pedido.
order.transactionDate Sim ORC-9 20191012153000 Data/hora yyyyMMddHHmmss.
order.location Não ORC-13.1 PRONTO SOCORRO Setor solicitante.
order.room Não ORC-13.2 L12 Quarto/enfermaria.
order.department Não ORC-17 TRAUMATOLOGIA Departamento.
order.facilityName Não ORC-21 HOSPITAL XYZ Instituição.
exams[].code Sim OBR-4 20 Código do exame.
exams[].priority Não OBR-5 R R rotina ou U urgente.
exams[].description Sim OBR-15.3 RAIO-X TORAX Descrição do procedimento.
exams[].bodySite Não OBR-15.4 TORAX Região do corpo.
exams[].accession Não OBR-18 14371 Identificador do item.
exams[].performedAt Sim OBR-27.4 20191012153000 Data/hora da realização.
exams[].modality Não OBR-24 CR Modalidade DICOM.
clinicalObservation Não OBX-5 Teste OBX HL7 Observação clínica (gateway codifica em Base64).

Configuração do webhook

As alterações são persistidas em data/webhook.json e passam a valer imediatamente, sobrepondo o .env.

Modelo JSON de exemplo do webhook

{
  "eventId": "uuid",
  "receivedAt": "ISO-8601",
  "messageType": "ORU^R01",
  "summary": {
    "messageControlId": "...",
    "patientId": "...",
    "orderId": "...",
    "placerOrder": "...",
    "fillerOrder": "...",
    "accession": "...",
    "reportId": "...",
    "obxCount": 3
  },
  "hl7": "MSH|^~\\&|PIXEON|MEDREPORT|...",
  "rtf": "{\\rtf1\\ansi... }",
  "text": "Texto higienizado do laudo",
  "base64": "iVBORw0KGg... (quando OBX contém conteúdo base64)",
  "obx": [
    { "setId": 1, "value": "...", "observedAt": "..." }
  ]
}

O conteúdo de rtf/text é controlado por WEBHOOK_CONTENT. Se algum OBX trouxer base64, o gateway propaga em base64 sem decodificar.

Entregas do webhook

Hora Event ID HTTP OK ms Bytes Erro

Rotas HTTP

Rota Uso
GET / Interface gerencial do gateway.
GET /health Health check público.
GET /api/auth/status Indica se o login é obrigatório.
POST /api/auth/login Recebe {user, password}, retorna token (API key).
GET /api/status Status operacional + métricas + configuração sanitizada.
GET /api/webhook/config Configuração atual do webhook.
POST /api/webhook/config Atualiza e persiste configuração do webhook em data/webhook.json.
POST /api/hl7/build Valida JSON e devolve HL7 ORM^O01 sem enviar.
POST /hl7/send Envia HL7 (raw, framed MLLP ou JSON estruturado) ao destino Worklist.
POST /hl7/send/raw Compatibilidade text/plain, devolve ACK em texto.
POST /hl7/report Endpoint auxiliar para registrar ORU^R01 via HTTP.
GET /hl7/report/latest Último laudo recebido. ?raw=1 retorna HL7 puro.
GET /hl7/reports Lista dos últimos laudos em memória. Filtros: orderId, identifier, placerOrder, accession, reportId.
GET /api/events Lista eventos persistidos. Filtros: limit, direction, type, status.
GET /api/events/:id Evento completo (HL7, ACK, raw original, webhook).
POST /api/events/:id/webhook/resend Reenvia o webhook de um evento recebido ORU^R01.
GET /api/events/:id/download?kind=hl7|ack|log|raw Baixa HL7, ACK, JSON técnico ou payload original.
GET /api/layouts/* Layouts worklist.hl7, worklist.json, report-oru.hl7, report-ack.hl7.

Configurações

Variável Descrição
HTTP_HOST / HTTP_PORT Host e porta da interface/API HTTP.
API_KEY Quando definida, exige x-api-key ou Authorization: Bearer.
UI_USER / UI_PASSWORD Credenciais fixas para a tela de login. Se vazias, login é desabilitado.
CORS_ORIGIN Origens permitidas.
HTTP_BODY_LIMIT_BYTES Limite de payload HTTP.
MIRTH_HOST / MIRTH_PORT Destino MLLP para envio P01.
MIRTH_CONNECT_TIMEOUT_MS / MIRTH_RESPONSE_TIMEOUT_MS Timeouts do cliente MLLP.
MLLP_EXPECT_ACK Se o envio espera ACK antes de responder.
REPORT_MLLP_ENABLED Ativa/desativa listener MLLP para laudos.
REPORT_MLLP_HOST / REPORT_MLLP_PORT Host e porta do listener P05.
REPORT_STORE_LIMIT Quantos laudos manter em memória.
DATA_DIR Diretório para events/YYYY-MM-DD.jsonl, logs/YYYY-MM-DD.log e webhook.json.
EVENT_STORE_LIMIT Eventos mantidos em memória.
LOG_STDOUT Emite logs sanitizados no stdout.
ACK_* / REPORT_AUTO_ACK_* Dados do ACK de resposta P05.
WEBHOOK_URL URL para POST automático dos laudos recebidos.
WEBHOOK_FORMAT json ou hl7.
WEBHOOK_CONTENT original, sanitized, both ou none.
WEBHOOK_AUTH_HEADER Header de autenticação opcional.
WEBHOOK_TIMEOUT_MS Timeout do POST do webhook.

Persistência

  • Eventos enviados/recebidos: data/events/YYYY-MM-DD.jsonl, uma linha JSON por evento, contendo HL7, ACK e o payload original (raw HL7 ou JSON enviado pelo terceiro).
  • Logs técnicos sanitizados: data/logs/YYYY-MM-DD.log.
  • Configuração editada pela aba Webhook: data/webhook.json.
  • Para download de arquivos .hl7 individuais use a aba Monitor/Eventos ou a API /api/events/:id/download.

Segurança e operação

  • Use UI_USER+UI_PASSWORD para proteger a interface.
  • Use API_KEY em homologação/produção. Sem TLS e sem restrição de rede, não exponha o gateway publicamente.
  • Persista DATA_DIR em volume Docker para manter histórico.
  • Cada evento recebe um eventId único para auditoria e download.