Skip to main content

G2I — Ficha de Integração

Integração outbound com o sistema G2I: a Public API envia status de assinatura do exame (redirect) e, em fluxo separado, notifica comentário + status (notify) ao endpoint configurado no cliente.

Referência OpenAPI — POST /exam/redirect Referência OpenAPI — POST /exam/notify

:::info Classificação

  • T2 (outbound): adapter g2i em POST /exam/redirect (acao=REDIRECT) e POST /exam/notify (acao=NOTIFY) — Mobilemed envia payload ao url de tb_integracao_config.
  • T1 (inbound): não se aplica — não há rota gateway específica G2I no código. :::

Identificação​

CampoValor
TipoT2 (adapter outbound)
adapter_keyg2i
Classeadapters/G2IAdapter.js
Cliente/tenantMulti-tenant (configurado por tb_integracao)
Statusativo
Owner squadTais Oliveira
Contato técnico clienterodrigo@grupog2i.com.br, alex@grupog2i.com.br, gustavo.coutinho@grupog2i.com.br
Última revisão2026-09-22

Escopo​

Fluxo completo​

Rotas envolvidas​

DireçãoMétodoRotaacao (middleware)Função
OutboundPOST/exam/redirectREDIRECTMonta { accessionNumber, isSigned } e envia ao url do adapter g2i
OutboundPOST/exam/notifyNOTIFYBusca último comentário do exame e envia { comment, status } ao url
OutboundPOST/exam/notifyUpdateNOTIFY_UPDATEMesmo handler notify do controller; exige config com acao=NOTIFY_UPDATE se usada

O adapter implementa apply() e notify(). Não há override de getRequests, convertUrlVariable nem _validateToken.

:::caution OpenAPI Não existe path /exam/g2i (nem equivalente) em swaggerDocs.json. Os contratos HTTP do gateway são os genéricos Integra exame (POST /exam/redirect) e Envia notificação de exame (POST /exam/notify). :::

Ambientes​

AmbienteBase URL
Homologaçãohttps://gateway-homolog.mobilemed.com.br/api-public
Produçãohttps://integracao.mobilemed.com.br/v1

Headers obrigatórios no gateway: token, api (mob ou one).


Configuração (banco)​

Registros em tb_integracao + tb_integracao_config (models/IntegrationConfig.js). Em geral são duas configs (ou mais), uma por acao.

CampoValor típicoObservação
adapterg2iDeve bater com adapters/index.js
acaoREDIRECT e/ou NOTIFYMiddleware: /exam/redirect → REDIRECT; /exam/notify → NOTIFY. Opcional: NOTIFY_UPDATE para /exam/notifyUpdate
urlURL do endpoint G2I do clienteG2IAdapter não implementa convertUrlVariable; URL com [#variable#] falharia no service
reportFormatqualquer ENUM válidoNão usado pelo G2IAdapter (payload não inclui corpo de laudo)
tipo_envioJSONPayload é objeto JS; service envia como JSON quando tipo_envio === "JSON"
base64irrelevante para este adapterNão há conversão de laudo no adapter
auth_typeTOKEN, BASIC_AUTH ou DEFAULTVer seção Autenticação — comportamento diferente entre redirect e notify
automatic_retryconforme tb_integracaoUsado pelo RetryService no fluxo de redirect
additional_settings.alternativeMethodex. "put"Método HTTP alternativo no externalRequest (fluxo genérico)
additional_settings.redirectConditionalsobjeto condicionalSó no fluxo redirect() — pode lançar BLOCKED_BY_CONFIG
additional_settings.validateTokense aplicávelChama _validateToken do adapter antes do envio (G2I não implementa o método)
additional_settings.notificarEnvioComentariotruePortal-API (verificaNotifyUpdate): com acao=NOTIFY_UPDATE, ao adicionar comentário dispara o emit de notify
headers_adicionaisJSON em tb_integracaoHeaders extras no POST outbound

:::info Pré-requisito de laudo (redirect e notify assinados) Mesmo sem converter laudo, o fluxo genérico de redirect() exige study.laudo.pdf_path (tenta reprocessar; senão lança erro). Em notify(), se status_id for 1 ou 5 e não houver pdf_path, também lança erro antes de chamar o adapter. :::


Autenticação​

Inbound (gateway → Mobilemed)​

HeaderObrigatórioDescrição
tokensimToken da integração (tb_integracao.token)
apisimAmbiente: mob ou one

Outbound (Mobilemed → G2I)​

POST /exam/redirect → exam.service.js → redirect()​

Usa integration.config.auth_type (com fallback DEFAULT para credenciais de tb_integracao):

auth_type (config ou integração)Comportamento
TOKEN + token_nameHeader dinâmico: {token_name}: {client_token}
BASIC_AUTHHeader Authorization: Basic {base64(user:pass)}
DEFAULTHerda auth_type / credenciais de tb_integracao

POST /exam/notify → exam.service.js → notify()​

Usa somente integration.auth_type de tb_integracao (não lê config.auth_type):

auth_type (tb_integracao)Comportamento
TOKEN + token_nameHeader {token_name}: {client_token}
BASIC_AUTHHeader Authorization: Basic {base64(user:pass)}

Credenciais adicionais podem ser injetadas via headers_adicionais (JSON) em ambos os fluxos.

Rotação de credenciais: a confirmar (responsável / data).


Contrato​

Inbound​

Não se aplica.

Outbound — POST /exam/redirect → G2IAdapter.apply()​

Payload montado pelo adapter e enviado ao url:

json
{
"accessionNumber": "2026001001",
"isSigned": true
}
CampoRegra no código
accessionNumberstudy.pacs_accession_no
isSignedtrue se status_id === 1 ou status_id === 5; caso contrário false

O adapter ignora integration, reportOptions e env em apply() (assinatura efetiva: apply(_, study)).

Outbound — POST /exam/notify → G2IAdapter.notify()​

Antes de montar o payload, o adapter:

  1. Instancia CommentService(env) e busca o último comentário (ExameComentario ordenado por id DESC).
  2. Se a busca falhar, registra log de integração tipo 52 com mensagem G2I: erro ao buscar último comentário... e segue com comment vazio.
  3. Se não houver comentário, comment fica "".
json
{
"comment": "Texto do último comentário do exame",
"status": 1
}
CampoRegra no código
commentcomment.descricao do último ExameComentario, ou ""
statusstudy.status_id (número)

_integration e _anexoID são recebidos mas não usados pelo adapter.

Erros comuns (outbound)​

ErroCausa
Erro ao redirecionar exame devido a laudo ainda não processadoLaudo sem pdf_path no fluxo genérico de redirect()
Erro ao notificar devido a laudo ainda não processadostatus_id 1 ou 5 sem pdf_path no fluxo genérico de notify()
BLOCKED_BY_CONFIGBloqueio por redirectConditionals em additional_settings (só redirect)
404 No integration foundToken inválido/inativo ou config com acao correspondente ausente
adapter.convertUrlVariable is not a functionurl contém [#variable#] e o G2IAdapter não implementa o método
Log tipo 52 (não aborta o notify)Falha ao buscar último comentário — payload segue com comment: ""

Idempotência / retry​

  • Exames com status_id = 5 passam pela lógica de retentativa (RetryService) no controller redirect.
  • automatic_retry em tb_integracao controla retentativas automáticas no redirect.
  • Payloads são determinísticos para o mesmo estado do exame (sem ID aleatório) — reenvio com o mesmo status/comentário produz o mesmo corpo.
  • O fluxo notify não usa RetryService no trecho lido do controller.

Operação​

ItemDetalhe
Código adaptermm-pacs-public-api/adapters/G2IAdapter.js
Registro da chaveadapters/index.js → g2i: G2IAdapter
Controller outboundcontrollers/exam.controllers.js → redirect, notify
Service outboundservices/exam.service.js → redirect(), notify()
Comentários (notify)services/comment.service.js → getLastComment()
Logs de falha de comentárioservices/log.service.js (tipo 52)
Deploy / runbooka confirmar
MonitoramentoLogs de integração no redirect/notify (tipo 42 no controller); tipo 52 em falha de comentário G2I
Escalaçãoa confirmar

Evidências​

Homologação com dados de teste (sem PHI de paciente real).

Configuração no Portal — acao=REDIRECT​

Sistema Teste G2I, adapter g2i, autenticação Default, envio JSON, URL de webhook de teste. additional_settings: {"notificarEnvioComentario":true}.

Configuração redirect G2I no Portal

Redirect — payload outbound​

Corpo enviado ao cliente (G2IAdapter.apply()):

json
{
"accessionNumber": "123123123123123123123123123123",
"isSigned": true
}

Payload redirect G2I

Notify — payload outbound​

Corpo enviado ao cliente (G2IAdapter.notify()), comentário de teste:

json
{
"comment": "tatatat",
"status": 0
}

Payload notify G2I


Rastreio​

ItemValor
Tarefa Bitrixhttps://mobilemed.bitrix24.com.br/company/personal/user/1970/tasks/task/view/62318/
PR códigoPublic-API: develop #443, master #441
Portal-API: develop #782, master #780
PR documentaçãodevelop #57, main #55
URL publicada/docs/interfaceReference/integrations/g2i
Ficha no repodocs/interfaceReference/integrations/g2i/index.md