FCM – Payload enviado pelo integrador (para o app Flutter)¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-06
O integrador roda em duas instâncias (SulPlata e OnPetro Trading). Cada instância usa push.empresa e envia nos 4 tópicos (2 por empresa). O payload inclui data.tipo e data.empresa para o app abrir na tela correta e exibir a origem (SulPlata / OnPetro).
Tópicos (4 no total)¶
| Empresa | Tópico | Uso |
|---|---|---|
| SulPlata | bl_liberado_sulplata |
BL liberado |
| SulPlata | nota_venda_emitida_sulplata |
Nota de venda emitida |
| OnPetro Trading | bl_liberado_onpetrotrading |
BL liberado |
| OnPetro Trading | nota_venda_emitida_onpetrotrading |
Nota de venda emitida |
- Cada instância do integrador configura
push.empresa:sulplataouonpetrotrading. - O serviço envia no tópico correspondente (ex.: instância SulPlata →
bl_liberado_sulplataenota_venda_emitida_sulplata).
O que o integrador envia em data¶
tipo(obrigatório):"bl_liberado"ou"nota_venda_emitida"— o app usa para decidir a tela (Saldo BL ou Vendas).empresa(obrigatório):"sulplata"ou"onpetrotrading"— identifica a empresa para o app exibir "SulPlata: ..." / "OnPetro: ..." e tratar corretamente.click_action:"FLUTTER_NOTIFICATION_CLICK"(recomendado para Android antigos).- Demais chaves do contexto:
request_id,origem,title,body, etc.
Título e corpo por tipo de push¶
- BL liberado: título e corpo montados a partir do BL, navio e dados do contrato.
- Nota de venda emitida (apenas quando a nota altera saldo do BL — venda ao cliente final):
- Título:
Venda · <volume> m³ · <cliente:nome_curto|nome>— ex.: "Venda · 2.500 m³ · Fazenda ABC" (separador: bolinha ·). - Corpo (body):
R$ <preço unitário> · <filial> · R$ <prêmio> · R$ <total>— ex.: "R$ 15,01 · Filial Teste · — · R$ 1.500,50". - Volume = soma dos Qtde dos itens da nota (m³); cliente de NotaCompl.chaveProp → Propriedades; filial de Propriedades.codMun → Municipio.nomeMun; preço unitário e total a partir dos itens. Prêmio = soma, por item, de (preço unitário do produto − preço Petrobrás por m³) × volume (m³); Preço Petrobrás por m³ =
vlProd(TbpcoEst, em R$/L) × 1000; registro na data da nota (dt_estentreval_inieval_fin). - Quando envia: só se (1) a ChaveNota indicar tipo saída (contém "R" — venda) e (2) a nota alterar o saldo do BL (lote vinculado a ItensPedAmx no banco). ChaveNota com "P" = entrada, não dispara push. Avalia apenas as letras P e R (o "0" eventual faz parte de outra parte da chave).
- Imagem: não é enviada (apenas texto).
Corpo da notificação (body)¶
O integrador acrescenta ao final do corpo um sufixo por empresa, para o app exibir a origem:
- SulPlata: o body termina com
[Sul Plata] - OnPetro Trading: o body termina com
[On Petro Trading]
Exemplo: "Nota de entrada do BL #123 Navio X emitida. [Sul Plata]"
Notification, Android e APNS¶
notification: apenastitleebody(já com o sufixo por empresa). Sem imagem/logo (apenas texto).- Android:
priority: "high". - APNS: header
apns-priority: "10".
Rotas no app (Flutter)¶
data.tipo |
Tela no app | Rota |
|---|---|---|
bl_liberado |
Saldo BL | /saldo-bl-2 |
nota_venda_emitida |
Vendas | /vendas-2 |
O app usa data.empresa para rotular e lógica interna; a rota é decidida por tipo.
Configuração por instância¶
- SulPlata (ex.: porta 3001):
push.empresa: "sulplata"(ou omitir; é o padrão). - OnPetro Trading (ex.: porta 3002):
push.empresa: "onpetrotrading".
Valores aceitos: exatamente sulplata | onpetrotrading (minúsculas).
Fluxos que disparam o push¶
- Real: PUT XADM com origem PBLDI ou PNOTAI →
PushContextBuildermonta título/corpo →FcmPushServiceenvia no tópico da instância (*_sulplataou*_onpetrotrading) comdata.tipo,data.empresa,data.click_action, prioridades e imagem. - Teste: tela
/debug(botões BL Liberado e Nota de Venda) → mesmo serviço, com título/corpo de exemplo; a instância já define a empresa e o tópico.
Disparo (desacoplado por evento)¶
O push não é chamado direto pelo XadmService. Após aplicar um PUT XADM com sucesso, o ingest publica um NotaAplicadaEvent (em core); o NotaAplicadaPushListener (em push) reage, decide por Origem (PBLDI/PNOTAI) e dispara o FCM em thread virtual (fire-and-forget). Isso quebra o acoplamento ingest↔push — ver estrutura de pacotes.