Documentação de Suporte

P&G LATAM Coopidrogas Sentry

Maintainer: Linyker Mendes (linyker.mendes@b2list.com)
Atualizado: 2026-06-19  ·  Versão: v3

Documentação de Suporte — P&G LATAM / Coopidrogas / Sentry

Maintainer: Linyker Mendes (linyker.mendes@b2list.com)
Última atualização: 2026-06-19 (v2 — URLs, Keycloak, ETL, SFTP, Deploy, Postman)
Finalidade: Guia completo para qualquer membro do time atender chamados e incidentes relacionados ao projeto P&G LATAM (App Sentry / Coopidrogas) na ausência do Linyker.


Índice

1. Visão Geral do Ecossistema

O projeto P&G LATAM (internamente chamado de "App Sentry" ou "Sentry") é uma plataforma de vendas field para a Procter & Gamble Colômbia. O app mobile é usado por transferencistas (promotoras de campo) para registrar visitas e gerar pedidos de produtos P&G nas farmácias atendidas pela Coopidrogas (cooperativa de drogarias colombiana).

┌─────────────────────────────────────────────────────────────────┐
│                       ECOSSISTEMA P&G LATAM                     │
│                                                                 │
│  [Transferencista] ──► [App Sentry (b2mobile-sentry)]          │
│                               │                                 │
│                    ┌──────────┴──────────┐                      │
│                    ▼                     ▼                      │
│        [api-integration-coopidrogas]  [b2app-coopidrogas-panel] │
│                    │                     │                      │
│                    ▼                     │                      │
│         [Integração SFTP]                │                      │
│                    │                     │                      │
│                    ▼                     ▼                      │
│            [Coopidrogas ERP]     [Panel Web B2List]             │
│                                          │                      │
│                         [etl-coopidrogas (Panel de Cobertura)]  │
└─────────────────────────────────────────────────────────────────┘

Componentes principais

Componente O que faz
App Sentry (b2mobile-sentry) App React Native (Expo) usado pelas transferencistas para registrar visitas e pedidos
API Integration Coopidrogas (api-integration-coopidrogas) Backend Java/Spring que integra pedidos do app com o ERP da Coopidrogas via SFTP
Panel Web (b2app-coopidrogas-panel) Painel React para supervisores e P&G visualizarem dados de cobertura/visitas
ETL Coopidrogas (etl-coopidrogas) Processa o "Panel de Cobertura" (Excel) enviado mensalmente pela Marco Marketing e carrega os dados no sistema
Sentry.io Ferramenta de monitoramento de erros do app em produção

2. Stakeholders e Contatos

Time B2List

Nome Email Papel
Linyker Mendes linyker.mendes@b2list.com Suporte TI — P&G / Coopidrogas / Sentry (você está aqui)
Nathália Franqueiro nathalia.franqueiro@b2list.com CS / Account Manager — ponto focal com P&G
Daniel daniel@b2list.com Tech Lead
Sabrina Santos sabrina.santos@b2list.com CS
Heloisy Vaz heloisy.vaz@b2list.com CS
Murillo murillo@b2list.com CS/Produto
Jaime Leite jaime.leite@b2list.com Coordenador de Incidentes / Triagem
Gabriel Marra Meireles gabriel.marra@b2list.com Backend Dev (integração Coopidrogas)
Vinicius Arvelos vinicius.arvelos@b2list.com Dev / Fechamento de incidentes
Matheus Fernandes Melo Dev Backend
João Pedro Martins Pinheiro Dev / QA
Vitor Emmanuel Dev

Time P&G LATAM (cliente)

Nome Email Papel
Steven Sevilla sevilla.s@pg.com PM / Lead P&G LATAM — principal ponto de contato
Daniel Delgado delgado.jd.6@pg.com Senior OU Technologist PHC LA — analista técnico P&G
Roberto Orozco orozco.r.3@pg.com P&G LATAM
Eliana Guzmán guzman.e.3@pg.com P&G LATAM — relacionamento com Coopidrogas
Natalia Franqueiro (P&G) franqueiro.ns@pg.com P&G LATAM

Marco Marketing / HeyMarco (agência de campo — Colômbia)

Marco Marketing é a agência responsável pelas operações de campo. Eles gerenciam as transferencistas e enviam o Panel de Cobertura mensalmente.

Nome Email Papel
Astrid Parra astridp@marcomkt.com Responsável pelo Panel de Cobertura (arquivo Excel)
Andrés Linares andresflv@marcomkt.com Operações de campo
Aldemar Martínez aldemarm@marcomkt.com Operações de campo
Santiago Beltrán santiagob@heymarco.com Operações de campo

3. Repositórios e Tecnologias

Todos os repos estão em C:\Users\Linyker\b2list-repos\ (clone local via Bitbucket).

Repos principais do projeto

Repositório Tech Descrição
b2mobile-sentry React Native / Expo App mobile das transferencistas
api-integration-coopidrogas Java / Spring Boot API de integração com Coopidrogas (pedidos via SFTP)
b2app-coopidrogas-panel React Painel web de cobertura/visitas
integration-coopidrogas Camada de integração adicional
etl-coopidrogas ETL que processa o Panel de Cobertura mensal
connector-coopidrogas Connector de dados Coopidrogas

Auth

O app usa Keycloak para autenticação OAuth2. Sessões expiram e o refresh token pode ficar inválido (ver incidente #1 na seção 9).


4. Infraestrutura e Acessos

ATENÇÃO: Todos os acessos abaixo exigem a VPN B2List conectada.

Banco de Dados — MongoDB

Ambiente Host Porta Usuário Auth DB
DEV mongodb.dev-aws.b2list.com 27017 linyker.mendes admin
HML mongodb.hml-aws.b2list.com 27017 linyker.mendes admin
PRD mongodb.prd-aws.b2list.com 27017 linyker.mendes admin
  • Autenticação: SCRAM-SHA-256 ou SCRAM-SHA-1
  • PRD = somente leitura. DEV/HML = leitura + escrita.

Banco de Dados — PostgreSQL

Ambiente Host Porta Usuário DB Padrão
DEV postgresql.dev-aws.b2list.com 5432 linyker_mendes postgres
HML postgresql.hml-aws.b2list.com 5432 linyker_mendes postgres
PRD postgresql.prd-aws.b2list.com 5432 linyker_mendes postgres
  • PRD = somente leitura. Senhas: pedir ao Arvelos ou consultar o vault seguro do time.

VPN

Sempre que for preciso acessar banco de dados ou serviços internos, conecte a VPN B2List primeiro.


5. Monitoramento com Sentry.io

Acesso

  • Organização: b2list
  • URL da plataforma: https://sentry.io/organizations/b2list/
  • API Base: https://us.sentry.io/api/0/
  • Auth: Bearer token (sntryu_...) — gerar em: sentry.io → foto do perfil → User Auth Tokens → Create New Token
  • Escopos necessários: org:read, project:read, event:read, member:read

O token não fica salvo em lugar nenhum por segurança. Cada sessão precisa de um novo token ou usar o existente enquanto válido.

Projetos monitorados

Slug Project ID O que monitora
sentry 4510149568692224 App mobile b2mobile-sentry (Coopidrogas / P&G LATAM)
api-integration-coopidrogas Backend de integração Coopidrogas
b2app-coopidrogas-panel Painel web Coopidrogas
b2mobile-refactored App B2List refatorado
super-seller App Super Seller

Queries PowerShell prontas

Pré-requisito: definir o token

$token = "sntryu_SEU_TOKEN_AQUI"
$headers = @{ "Authorization" = "Bearer $token" }

Listar últimos erros do app (últimos 7 dias)

$r = Invoke-RestMethod -Uri "https://us.sentry.io/api/0/organizations/b2list/events/?field=id&field=title&field=timestamp&field=error.value&field=user.email&field=user.username&field=release&field=os.name&field=device.family&sort=-timestamp&per_page=50&project=sentry&query=level:error&statsPeriod=7d" -Headers $headers -Method GET
$r.data | ForEach-Object { "$($_.timestamp.Substring(0,16).Replace('T',' ')) | $($_.'user.email') | $($_.title)" }

Filtrar por tipo de erro específico

# Substituir "AxiosError" pelo termo desejado
$r = Invoke-RestMethod -Uri "https://us.sentry.io/api/0/organizations/b2list/events/?field=id&field=title&field=timestamp&field=error.value&field=user.email&field=release&field=os.name&field=device.family&sort=-timestamp&per_page=30&project=sentry&query=level:error AxiosError&statsPeriod=7d" -Headers $headers -Method GET
$r.data | ForEach-Object { "$($_.timestamp.Substring(0,16).Replace('T',' ')) | $($_.'user.email') | $($_.title)" }

Buscar evento completo com breadcrumbs (causa raiz)

# Substituir {EVENT_ID} pelo ID do evento (campo "id" na listagem)
$raw = Invoke-RestMethod -Uri "https://us.sentry.io/api/0/organizations/b2list/eventids/{EVENT_ID}/?project=4510149568692224" -Headers $headers -Method GET

Add-Type -AssemblyName System.Web.Extensions
$serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$serializer.MaxJsonLength = 10000000
$obj = $serializer.DeserializeObject(($raw | ConvertTo-Json -Depth 20))
$ev = $obj["event"]

# Tags do evento
$ev["tags"] | ForEach-Object { "$($_['key']) = $($_['value'])" }

# Breadcrumbs (últimas 15 ações do usuário antes do erro)
$bc = $ev["entries"] | Where-Object { $_["type"] -eq "breadcrumbs" }
$bc["data"]["values"] | Select-Object -Last 15 | ForEach-Object {
    "$($_['timestamp'].Substring(0,16)) | $($_['category']) | $($_['message'])"
}

# Stack trace (frames in-app)
$exc = $ev["entries"] | Where-Object { $_["type"] -eq "exception" }
$exc["data"]["values"][0]["stacktrace"]["frames"] | Where-Object { $_["inApp"] -eq $true } | ForEach-Object {
    "  $($_['filename']):$($_['lineNo']) | $($_['function'])"
}

Campos importantes nos eventos

Campo O que mostra
user.email Email da transferencista/usuário
release Versão do app (ex: com.b2list.sentry@1.0.11+57)
os.name / device.family Android + modelo do dispositivo
error.value Mensagem de erro detalhada
tags[environment] production ou development
tags[provider] Operadora do celular

6. Fluxo Operacional Mensal

Ciclo do Panel de Cobertura

O Panel de Cobertura é um arquivo Excel enviado mensalmente pela Marco Marketing (Astrid Parra) com os dados de roteiro das transferencistas — quais farmácias visitar, metas, etc.

1. Marco Marketing (Astrid) envia o arquivo Excel atualizado
       ↓
2. B2List (Nathália) recebe e valida o arquivo
       ↓
3. ETL (etl-coopidrogas) processa o arquivo e carrega os dados no sistema
       ↓
4. Dados ficam disponíveis no app para as transferencistas
       ↓
5. Confirmação para P&G (Steven) de que a carga foi realizada

Atenção nas colunas do arquivo:
- Coluna AD → ID do transferencista (campo crítico; erro aqui causa need_sync = false nos pedidos)
- O arquivo validado chega com nome no formato: Panel de Cobertura - [Mês] - Sentry - ARCHIVO VALIDADO - [timestamp].xlsx

Ciclo de Pedidos (SFTP)

Transferencista cria pedido no app
       ↓
api-integration-coopidrogas envia CSV para SFTP da Coopidrogas
       ↓
API marca o pedido como enviado via PUT /orders/{codeOrder}
       ↓
Coopidrogas processa o pedido no ERP

Ponto de atenção: Se o upload SFTP for concluído, mas a marcação PUT /orders/{codeOrder} falhar, o pedido pode ser reenviado e duplicado no lado da Coopidrogas.


7. Canal de Comunicação e Escalonamento

Fluxo de atendimento

Demanda chega (P&G / Marco Marketing / Coopidrogas)
       ↓
Nathália Franqueiro (CS) recebe e triages
       ↓
Cria task no ClickUp (Infra > Sustentação > Incidentes)
       ↓
Linyker é notificado → investiga com apoio de Gabriel/Jaime
       ↓
Resolve ou escala para Dev (Matheus / João Pedro / Vitor)
       ↓
Fecha o card após validação (QA / CS)

Quem contatar em cada situação

Situação Contato primário Escalar para
Dúvida sobre dados no panel web Nathália Franqueiro Daniel
Erro no app (crash, tela branca) Linyker → Sentry.io Gabriel Marra / Matheus
Produto sem preço/estoque Gabriel Marra (ETL/integração) Nathália → P&G
Pedido duplicado / não enviado Gabriel Marra (api-integration) Jaime Leite
Acesso ao painel web (senha etc.) Nathália Franqueiro Linyker
Arquivo do Panel de Cobertura incorreto Nathália → Astrid (Marco Marketing) P&G (Steven / Eliana)
Código de autorização Coopidrogas Nathália Franqueiro Linyker

Canais

Canal Para que serve
Google Chat Comunicação interna B2List — incidentes urgentes
Email Comunicação com P&G, Marco Marketing, Coopidrogas
ClickUp Registro e rastreio de todos os incidentes
Microsoft Teams Reuniões com P&G (Steven usa convite via Teams)
Google Meet Reuniões internas (Nathália usa Meet)

8. Gestão de Incidentes no ClickUp

Onde ficam os cards

  • Workspace ID: 9007146481
  • Lista principal: Infra > Sustentação > Incidentes (List ID: 900701893516)
  • Pasta do projeto: Produto B2List > P&G Latam
  • Sales (coopidrogas) — List ID: 901307756115
  • Loyalty (grandes aliados) — List ID: 901311332048
  • Fase 2 — List ID: 901321304309

Convenção de nomenclatura dos cards

Os cards de incidente seguem o padrão:

[P&G LATAM] - Descrição do problema
[P&G LATAM] [Nome da Farmácia] - Descrição do problema
[Sentry App] - Descrição do erro
PGCOL{número}: Descrição (tickets vindos do cliente)

Status dos cards

Status Significado
aberto Recém criado, aguardando triagem
em progresso Dev investigando/corrigindo
code review PR aberto aguardando revisão
aguardando testes Fix feito, aguardando validação QA
aguardando cliente Aguarda informação ou confirmação da P&G/Coopidrogas
validado QA aprovou a correção
fechado Resolvido e confirmado

Cards ativos (referência — 19/06/2026)

ID Card Status
B2INFRA-3836 [P&G Latam] - Produtos P&G sem preço/estoque cadastrado em product_list_price (Coopidrogas) aguardando cliente
B2INFRA-3719 [P&G LATAM] - Erro "Farmacia no encontrada" ao acessar missão aguardando cliente
B2INFRA-3721 [P&G LATAM] - Missão bloqueada – Período da missão PAGO configurado incorretamente aguardando cliente
86aj4mr1k [Sentry App] AxiosError 400 — Sessão expirada sem redirecionamento para login

9. Incidentes Recorrentes e Como Resolver


INCIDENTE 1 — AxiosError 400 / Refresh Token Inválido

Sintoma: O app exibe erro de requisição sem redirecionar para tela de login. A transferencista fica "presa" na sessão.

Mensagem no Sentry:

AxiosError 400
breadcrumb: /refreshToken → BAD_REQUEST

Afeta: Usuários reais (@xper-heymarco.com)

Causa raiz: A sessão Keycloak expira em background. Quando o app tenta renovar o token (/refreshToken), o refresh token já é inválido e o servidor retorna 400 BAD_REQUEST. O app não captura corretamente esse erro para redirecionar ao login.

Como investigar:
1. No Sentry.io, buscar por AxiosError no projeto sentry
2. Verificar breadcrumbs: procurar a chamada /refreshToken com status 400
3. Confirmar email do usuário afetado no campo user.email

Resolução:
- Pedir para a transferencista deslogar e logar novamente no app
- Se for recorrente, escalar para dev (fix no tratamento do 400 no fluxo de refresh)
- Card de referência: https://app.clickup.com/t/86aj4mr1k


INCIDENTE 2 — Error -10 / WebView bloqueando autenticação

Sintoma: App exibe: "Login WebView: falha ao carregar pagina de autenticacao" ou "Error loading page - Domain undefined - Error Code -10"

Afeta: Dispositivos com Android System WebView desatualizado (ex: ONEPLUS com release 1.0.9+1)

Causa raiz: O Android System WebView do dispositivo está bloqueando o fluxo OAuth2 do Keycloak.

Como resolver:
1. Pedir para a transferencista atualizar o Android System WebView na Play Store
2. Se não resolver, verificar versão do Android e dispositivo
3. Escalar para dev caso seja problema de configuração do WebView no app


INCIDENTE 3 — Produto sem preço/estoque (product_list_price)

Sintoma: Transferencista vê a mensagem "Este producto no está disponible en este momento" ao tentar comprar um produto.

Causa raiz: A Coopidrogas não está registrando o estoque/preço desse produto na interface deles, então o arquivo enviado via SFTP vem com dados inválidos para o produto.

Como investigar:
1. Identificar o código do produto e a farmácia (EAN / ID do produto)
2. Verificar na tabela product_list_price no banco do ambiente PRD (via MongoDB ou PostgreSQL com VPN)
3. Checar o arquivo SFTP mais recente recebido da Coopidrogas para o produto em questão

Resolução:
- Comunicar para Nathália → Eliana Guzmán (P&G) → Coopidrogas que precisam corrigir o cadastro do produto no ERP deles
- Aguardar retorno da Coopidrogas com o arquivo corrigido
- Card de referência: B2INFRA-3836 / PGCOL17180


INCIDENTE 4 — Pedidos duplicados via integração SFTP

Sintoma: O mesmo pedido aparece duas vezes no sistema da Coopidrogas.

Causa raiz estrutural (em sends/order/order.js):

1. Upload do CSV para o SFTP da Coopi  ← ponto sem retorno
2. Chamada PUT /orders/{codeOrder}  ← marca o pedido como enviado

Se o upload (passo 1) for bem-sucedido mas a marcação (passo 2) falhar ou o processo reiniciar, o pedido é reenviado na próxima execução.

Como investigar:
1. Checar logs da api-integration-coopidrogas
2. Identificar o codeOrder duplicado nos logs do SFTP
3. Verificar se o PUT /orders/{codeOrder} foi chamado para o pedido

Resolução:
- Escalar para Gabriel Marra (backend integration)
- Contatar Coopidrogas para cancelar o pedido duplicado manualmente se necessário


INCIDENTE 5 — Pedidos não sincronizam (need_sync = false)

Sintoma: Pedidos registrados no app não aparecem no sistema da Coopidrogas.

Causa raiz já identificada (histórico): A Coopidrogas enviou o arquivo COVER PANEL com a coluna AD (ID transferencista) com dados incorretos. Isso faz com que os pedidos fiquem com need_sync = false e não sejam enviados.

Como investigar:
1. Verificar coluna AD no arquivo mais recente enviado pela Marco Marketing/Coopidrogas
2. Checar no banco o campo need_sync dos pedidos afetados

Resolução:
- Contatar Nathália → Astrid (Marco Marketing) para corrigir o arquivo Panel de Cobertura
- Após arquivo corrigido, reprocessar via ETL
- Verificar se pedidos voltam a sincronizar após a correção


INCIDENTE 6 — Farmácia "no encontrada" ao acessar missão

Sintoma: App exibe "Farmacia no encontrada" ao tentar acessar uma missão de uma farmácia.

Causa raiz possível: A farmácia existe no Panel de Cobertura mas não está corretamente registrada no sistema (ou foi excluída/alterada na última carga).

Como investigar:
1. Identificar o código da farmácia no card do ClickUp
2. Verificar se a farmácia existe nas coleções do MongoDB em PRD
3. Comparar com o Panel de Cobertura mais recente

Card ativo: B2INFRA-3719


INCIDENTE 7 — Erro nos alertas do app (ExpoUpdates OTA)

Sintoma no Sentry:

ExpoUpdates.checkForUpdateAsync — rejected

Afeta apenas: Contas de teste (@sentry.dev, @ellbit.com)

Causa: App em ambiente DEV/teste tentando checar atualizações OTA sem acesso ao canal de produção.

Ação: Ignorar — não afeta usuários reais em produção.


INCIDENTE 8 — Missão Pago / partial_checkout

Sintoma: Missão do tipo "pago" influenciando indevidamente o campo partial_checkout no app.

Status histórico: Já houve ocorrência em 17/06/2026 — resolvido e validado.

Como investigar: Verificar cards no ClickUp com tag missão pago ou buscar partial_checkout na lista de Incidentes.


INCIDENTE 9 — Error Code -10 / "Error loading page - Domain undefined" (Vila Nova / App geral)

Sintoma: App exibe tela de erro:

Error loading page
Domain: undefined
Error Code: -10

Após o erro, ao fechar e reabrir o app, ele fica carregando indefinidamente e não inicializa.

Afeta: Usuários em produção. Relatado pelo Aldemar (Marco Marketing), Linyker e Nathália. Também ocorreu durante treinamento do Super Seller.

Causa raiz: Android System WebView bloqueando o fluxo OAuth2. Diferente do incidente Vila Nova (que foi corrigido via deploy), este pode reaparecer em dispositivos com WebView desatualizado.

Resolução:
1. Pedir para o usuário forçar parada do app (não só fechar) e reabrir
2. Pedir para atualizar Android System WebView na Play Store
3. Se persistir, coletar: modelo do dispositivo, versão Android, versão do app → abrir card no ClickUp
- Card de referência: B2INFRA-3846 (https://app.clickup.com/t/86aj45hhg)


INCIDENTE 10 — Bug de segurança: escrita cross-seller nos endpoints (B2INFRA-3730)

Severidade: URGENTE. Este bug foi identificado e já foi corrigido (status: validado). Documentado aqui caso reapareça.

O que era: Um seller com JWT válido conseguia ler e alterar dados de farmácias e usuários de outros sellers via API, sem validação de vínculo.

Endpoints que eram afetados (api-integration-coopidrogas):

Verbo Endpoint Problema
GET /v1/sellers/pharmacies?seller.codeSeller=<outro> Retornava farmácias de outros sellers
GET /v1/sellers/{outroSeller}/pharmacies/{codePharmacy} Retornava dados de outro seller
PUT /v1/users/{codeUser} (user de outro seller) Persistia alteração cross-seller
PATCH /v1/users/{codeUser}/inactive (idem) Inativava user de outro seller

Impactos potenciais:
- Vazamento de dados pessoais (LGPD)
- Sabotagem: um seller poderia alterar o phoneSeller Master de farmácias de outro seller, redirecionando tokens P&G e autenticando número errado no chatbot

Fix aplicado: Validação do vínculo seller → farmácia → usuário extraindo codeSeller do JWT e verificando em seller_pharmacy antes de qualquer operação.

Card: B2INFRA-3730 (https://app.clickup.com/t/86ahe7xgm)

Se suspeitar de regressão: Testar com JWT de um seller tentando fazer PUT /v1/users/{codeUser_de_outro_seller} — deve retornar 403.


INCIDENTE 11 — Edição de "user master" no painel web não funcionava (B2INFRA-3738)

Sintoma: No painel web (b2app-coopidrogas-panel), ao tentar editar ou excluir um usuário, a ação falhava silenciosamente ou usava o endpoint errado.

Causa raiz: O painel lista usuários de duas origens: tabela user_education e tabela users. O sistema não identificava corretamente a origem do registro, usando sempre o mesmo endpoint para ambos.

Fix: O painel agora identifica a tabela de origem de cada usuário e chama o endpoint correto (/v1/users ou /v1/user-education) conforme o tipo.

Card: B2INFRA-3738 (https://app.clickup.com/t/86ahfackf)


INCIDENTE 12 — Bug ao navegar entre múltiplas listas no app (B2INFRA-3807)

Sintoma: Quando uma transferencista tem mais de 1 lista no app e tenta rolar/navegar entre elas, as listas "quebram" — exibem estado incorreto ou param de funcionar.

Afeta: Transferencistas com múltiplas listas ativas no app Sentry.

Status: Corrigido (validado). Se reportado novamente, verificar se a versão instalada é a mais recente.

Card: B2INFRA-3807 (https://app.clickup.com/t/86ahy8g36)


INCIDENTE 13 — Visitas de maio aparecendo nas vistas planejadas de junho

Sintoma: Visitas registradas em maio estavam aparecendo incorretamente nas vistas planejadas de junho no painel web.

Status: Fechado. Corrigido internamente.

Como verificar se recorreu: No painel web, comparar as datas das visitas exibidas com o mês atual. Se uma visita do mês anterior aparecer como "planejada" no mês corrente, abrir novo card.


INCIDENTE 14 — Missões "Pago" e "Detailing" com mal funcionamento

Sintoma: Missões do tipo Pago e Detailing exibiam comportamento incorreto no app (3 pontos afetados reportados).

Resolução: Linyker confirmou para Jaime que os pontos 1 e 3 se resolveram e o ponto 2 subiu para produção. Card fechado em 17/06/2026.

Card: Fechado (https://app.clickup.com/t/86ahe7xgm buscar no ClickUp por "Missões pago e detailing")

Se recorrer: Abrir novo card em Infra > Sustentação > Incidentes com título [P&G LATAM] Missões pago e detailing com mal funcionamento e escalar para Vitor Emmanuel / Gabriel Marra.


10. Reuniões Recorrentes

Weekly Progress Check — P&G LATAM

  • Organizador: Steven Sevilla (sevilla.s@pg.com)
  • Participantes B2List: Linyker, Nathália, Daniel, Sabrina, Heloisy, Murillo
  • Participantes P&G: Steven, Daniel Delgado
  • Plataforma: Microsoft Teams
  • Assunto no email: (SENTRY) Weekly progress check
  • Pauta: Progresso do app, incidentes abertos, métricas de uso

Weekly Prioritization Meeting — P&G LATAM

  • Organizador: Steven Sevilla
  • Participantes: Steven, Daniel (B2List), Nathália, Sabrina, Linyker, Daniel Delgado
  • Plataforma: Microsoft Teams
  • Assunto no email: (SENTRY) Weekly Prioritization meeting

Reuniões ad-hoc (Google Meet — internas)

  • "Dados dash - P&G" — Nathália convoca Linyker para alinhar dados do dashboard
  • "Documentos Coopidrogras" — Nathália + Gabriel + Linyker para alinhar sobre arquivos/integração
  • "Visitas parciais" — Nathália convoca Linyker para tratar regras de visitas parciais


11. URLs e Ambientes

Todos os acessos externos exigem VPN B2List conectada.

Painel Web (b2app-coopidrogas-panel)

Ambiente URL
DEV https://dev-coopidrogas.b2list.com
HML https://hml-coopidrogas.b2list.com
PRD https://coopidrogas.b2list.com

Painel de Mensageria

Ambiente URL
DEV https://dev-sentry-mensageria.b2list.com
HML https://hml-sentry-mensageria.b2list.com
PRD https://sentry-mensageria.b2list.com

API de Integração Coopidrogas (api-integration-coopidrogas)

Ambiente Base URL
DEV https://dev-services.b2list.com/integration/coopidrogas
HML https://hml-services.b2list.com/integration/coopidrogas
PRD https://services.b2list.com/integration/coopidrogas

API de Autenticação (Keycloak / Security)

Ambiente Base URL
DEV https://dev-services.b2list.com/security
HML https://hml-services.b2list.com/security
PRD https://services.b2list.com/security

Keycloak Admin

Ambiente URL
DEV https://dev-keycloak.b2list.com
HML https://hml-keycloak.b2list.com
  • Realm: coopidrogas
  • Client ID: api-core-auth

API Keys (para uso em chamadas internas / Postman)

Ambiente Chave da Integration API Chave da Security API
DEV jEo4jI1VgNShAWatAVfIfcDJL2ko8m5I 5XYVsVYS1qIRDMC0a7P87Y9gLu95Iey5
HML WKdEVNBtzym9rVY3zlgeNwKXYUzUGr1v DYqG2Jahy7i6AfKR7jsNs2fP3VIKtyDQ
PRD kraQxF0Ve0dpJiwSBGWc3jNC1mIeLgV5 ErVWdUQvbvgp5iyOjy7gIhwXbBmKf2Qn

12. Keycloak — Gestão de Usuários e Sessões

O Keycloak é o servidor de autenticação usado pelo app e pelo painel web. O realm relevante é coopidrogas.

Acessar o console admin

  1. Acesse https://dev-keycloak.b2list.com (DEV) ou https://hml-keycloak.b2list.com (HML)
  2. Clique em "Administration Console"
  3. Faça login com as credenciais de admin (pedir ao Arvelos ou Daniel)
  4. Selecione o realm coopidrogas no dropdown superior esquerdo

Operações comuns

Resetar senha de um usuário

  1. Admin Console → Users → buscar pelo email da transferencista
  2. Clique no usuário → aba Credentials
  3. Clique em Reset password → definir nova senha temporária → enviar para o usuário

Verificar/encerrar sessões ativas

  1. Admin Console → Users → selecionar o usuário
  2. Aba Sessions → ver sessões ativas
  3. Clicar em Logout all sessions para forçar novo login (útil quando sessão fica travada)

Criar novo usuário (transferencista / supervisor)

Normalmente o ETL cria os usuários via processo automatizado. Criação manual só em emergências.

  1. Admin Console → UsersCreate new user
  2. Preencher: Username (email), Email, First name, Last name
  3. Aba Credentials → definir senha temporária
  4. Aba Role mapping → atribuir roles necessárias

Verificar token expirado (causa do AxiosError 400)

O token JWT do Keycloak pode ser decodificado em https://jwt.io para verificar:
- Campo exp → timestamp de expiração
- Campo iss → confirma qual realm/ambiente gerou o token
- Campo email → identifica o usuário

Roles do realm coopidrogas

As roles identificadas nos tokens:

Role O que permite
BUYERS_READ Leitura de compradores (farmácias)
PRODUCTS_READ Leitura de produtos
ORDERS_READ Leitura de pedidos
LIST Acesso às listas
LIST_AUTOMATIC Listas automáticas
BROADCAST_LIST / BROADCAST_SEND Mensageria
CONFIG_WHATSAPP Configuração WhatsApp
CONFIG_PROVIDER Configuração de provider

13. ETL Coopidrogas — Como Funciona e Como Reprocessar

O que é

O ETL (etl-coopidrogas) é uma aplicação Python/Flask que:
1. Conecta ao SFTP da Coopidrogas e baixa arquivos .txt de inventário de /datos/transferencias/inventario
2. Processa o Panel de Cobertura (Excel) vindo do S3
3. Chama uma série de endpoints internos em sequência para carregar os dados no sistema

Sequência de execução (main.py)

O ETL executa as seguintes rotas em ordem, com retry automático (3 tentativas):

1.  pharmacy_priceList        → preços por farmácia
2.  priceList                 → tabela de preços
3.  product_listPrice         → preço/estoque de produtos (product_list_price)
4.  product_promotion         → promoções de produtos
5.  pharmacy                  → cadastro de farmácias
6.  user                      → cadastro de usuários/transferencistas
7.  pharmacy_user             → vínculo farmácia ↔ usuário
8.  cover_panel               → Panel de Cobertura (missões por farmácia)
9.  mission_customer_seller   → missões por cliente/vendedor
10. plans                     → planos de cobertura
11. attraction_pharmacy       → farmácias de atração
12. seller                    → cadastro de vendedores
13. pharmacy_seller           → vínculo farmácia ↔ vendedor
14. education                 → conteúdos educativos
15. mission_customer_seller_detailing → missões detailing
16. metrics                   → métricas

Como reprocessar o ETL manualmente

Quando um arquivo chega com erro e precisa ser recarregado após correção:

Opção 1 — Reexecutar via Bitbucket Pipelines (recomendado)
1. Acessar o repositório etl-coopidrogas no Bitbucket
2. Ir em PipelinesRun pipeline
3. Selecionar a branch correta (trunk = HML / tag = PRD)
4. Aguardar execução

Opção 2 — Reprocessar apenas um módulo específico

Se apenas um módulo falhou (ex: product_listPrice), chamar o endpoint diretamente:

# Em DEV (precisar estar com o serviço rodando localmente)
curl http://127.0.0.1:5000/dados/product_listPrice

# Para outros módulos, substituir o sufixo:
# /dados/pharmacy_priceList
# /dados/cover_panel
# /dados/mission_customer_seller
# ... etc.

Scripts do ETL (referência rápida)

Script O que processa
cover_panel.py Panel de Cobertura (arquivo Excel do S3)
product_listPrice.py Preço e estoque por produto/farmácia
pharmacy.py Cadastro de farmácias
pharmacy_user.py Vínculo farmácia ↔ usuário
mission_customer_seller.py Missões por cliente/vendedor
plans.py Planos de visita
seller.py Cadastro de vendedores
education.py Conteúdo educativo
metrics.py Métricas de cobertura
download_cover_s3.py Download do Panel de Cobertura do S3

14. SFTP da Coopidrogas

O ETL se conecta ao SFTP da Coopidrogas para baixar arquivos de inventário (.txt).

Configuração de conexão

As credenciais vêm de variáveis de ambiente (não ficam no código):

Variável Descrição
SFTP_HOST Host do servidor SFTP da Coopidrogas
SFTP_PORT Porta (geralmente 22)
SFTP_USER Usuário SFTP
SFTP_PASSWORD Senha SFTP

Para obter as credenciais, consultar o Arvelos ou o vault seguro do time. Elas ficam configuradas nas variáveis de ambiente do container ECS.

Diretório remoto

/datos/transferencias/inventario

O ETL lista todos os arquivos .txt nesse diretório e os baixa para ./arquivos_txt/ localmente.

Ciphers suportados

O servidor SFTP da Coopidrogas usa ciphers legados. O ETL já está configurado para aceitar:
aes128-ctr, aes192-ctr, aes256-ctr, aes128-cbc, aes192-cbc, aes256-cbc, 3des-cbc

E key types legados: ssh-rsa, ssh-dss

Como verificar se os arquivos foram enviados

Se suspeitar que a Coopidrogas não enviou o arquivo correto:
1. Acessar o servidor SFTP com as credenciais acima
2. Navegar até /datos/transferencias/inventario
3. Verificar datas de modificação dos arquivos .txt
4. Comparar com a data esperada de envio


15. Deploy — App Mobile (b2mobile-sentry)

Tecnologia

  • Framework: React Native 0.79.6 + Expo SDK 53
  • Build/Deploy: EAS (Expo Application Services)
  • CI/CD: Bitbucket Pipelines
  • Versionamento: semântico (X.Y.Z), gerenciado automaticamente pela pipeline

Perfis de build (eas.json)

Perfil Tipo Canal OTA Distribuição
development Dev client development internal
development-apk APK development internal
preview APK preview internal
production AAB (Play Store) production store
production-apk APK production internal

Comandos locais

npm start                  # Iniciar em modo desenvolvimento
npx expo run:android       # Build debug no Android conectado
npm run apk                # APK de release local (gradle)
npm run update             # OTA update para canal de produção (mais rápido, sem Play Store)

Quando usar OTA vs. nova versão na Play Store

Tipo de mudança Como fazer
Correção de bug no JS/TS (sem mudança nativa) npm run update — OTA, disponível em minutos
Mudança em código nativo (Android/iOS) Pipeline deploy-release → nova versão na Play Store
Mudança de dependência nativa Pipeline deploy-release → nova versão na Play Store

OTA: o app verifica atualizações ao abrir. A nova versão é baixada em background e aplicada no próximo restart.

Pipeline de release (Bitbucket)

Para gerar uma nova versão na Play Store:

  1. Acessar o repositório b2mobile-sentry no Bitbucket
  2. Ir em PipelinesRun pipeline → selecionar custom: deploy-release
  3. Escolher o tipo de versão: patch (bug fix) / minor (nova funcionalidade) / major
  4. A pipeline:
  5. Lê a última tag Git
  6. Incrementa a versão no app.json
  7. Executa eas build --platform android no perfil production
  8. Cria uma tag Git com o novo número de versão
  9. Após o build finalizar no EAS, fazer o submit para a Play Store via eas submit

Formato da versão

com.b2list.sentry@X.Y.Z+buildNumber

Exemplo: com.b2list.sentry@1.0.11+57


16. Deploy — Serviços Backend e Frontend

Todos os serviços usam Bitbucket Pipelines + AWS ECS + ECR.

Regra geral de branches

Branch Ambiente alvo Trigger
trunk DEV Automático ao fazer merge
release HML Automático ao fazer merge
Tag via pipeline deploy-release PRD Manual no Bitbucket

api-integration-coopidrogas

Ação Como fazer
Deploy em DEV Merge para trunk → pipeline automática
Deploy em HML Merge para release → pipeline automática
Deploy em PRD Bitbucket → Pipelines → custom: deploy-release → escolher versão
  • Cluster ECS DEV: dev-coopidrogas
  • Cluster ECS HML: hml-coopidrogas
  • ECR PRD: 518581536082.dkr.ecr.us-east-2.amazonaws.com

b2app-coopidrogas-panel (Painel Web)

Mesma lógica de branches. Usa Dockerfiles separados:
- Dockerfile.development → DEV
- Dockerfile.staging → HML
- Dockerfile.production → PRD

etl-coopidrogas

  • trunk → HML
  • Pipeline deploy-release → PRD

Como verificar se um deploy foi bem-sucedido

  1. Acessar o Bitbucket → repositório → aba Pipelines
  2. Verificar o status do último pipeline (verde = sucesso, vermelho = falhou)
  3. Clicar no pipeline para ver logs detalhados em caso de falha

17. Testes com Postman

O repositório api-integration-coopidrogas tem uma collection Postman completa em postman/.

Arquivos disponíveis

postman/
├── LATAM.postman_collection.json   ← collection com todas as rotas
├── DEV.postman_environment.json    ← variáveis de ambiente DEV
├── HML.postman_environment.json    ← variáveis de ambiente HML
└── LOCAL.postman_environment.json  ← variáveis para rodar localmente

Como importar no Postman

  1. Abrir o Postman
  2. Import → selecionar LATAM.postman_collection.json
  3. Import → selecionar o environment desejado (ex: DEV.postman_environment.json)
  4. Selecionar o environment no dropdown superior direito do Postman

Variáveis configuradas por ambiente

Variável DEV HML
URL_COOPIDROGAS http://dev-services.b2list.com/integration/coopidrogas https://hml-services.b2list.com/integration/coopidrogas
API_KEY_COOPIDROGAS jEo4jI1VgNShAWatAVfIfcDJL2ko8m5I WKdEVNBtzym9rVY3zlgeNwKXYUzUGr1v
API-CORE-AUTH https://dev-services.b2list.com/security https://hml-services.b2list.com/security

O campo TOKEN_COOPIDROGAS nos arquivos de environment pode estar expirado. Gere um novo token via Keycloak antes de usar.

Gerar novo token para usar no Postman

curl -X POST https://dev-keycloak.b2list.com/realms/coopidrogas/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=api-core-auth&client_secret=PukRWSpE7mMCRbRGnFuXrie16l8XfmWE"

Substituir client_secret pelo valor correto do ambiente (consultar .env do painel ou pedir ao Arvelos).


18. Glossário

Termo Definição
Sentry (projeto) Nome do app mobile P&G LATAM Colômbia (não confundir com Sentry.io, a ferramenta de monitoramento)
Coopidrogas / Coopi Cooperativa de drogarias colombiana — ERP do cliente que recebe os pedidos via SFTP
Transferencista Promotora de campo da Marco Marketing que usa o app para visitar farmácias e gerar pedidos
Panel de Cobertura Planilha Excel mensal enviada pela Marco Marketing com o roteiro das transferencistas
Marco Marketing / HeyMarco Agência colombiana responsável pelas operações de campo (gerencia as transferencistas)
SFTP Protocolo de transferência de arquivos usado para enviar pedidos CSV da B2List para a Coopidrogas
ETL Processo automatizado que lê o Panel de Cobertura e carrega os dados no banco
need_sync Flag no banco que indica se um pedido precisa ser enviado para a Coopidrogas (true = precisa enviar)
product_list_price Tabela/coleção que armazena preço e estoque de produtos por farmácia
Keycloak Servidor de autenticação OAuth2 usado pelo app e pelo painel web
Refresh Token Token usado para renovar a sessão sem pedir login novamente; expira após certo tempo
OTA Over-the-air update — atualização do app sem passar pela Play Store (via Expo Updates)
breadcrumb No Sentry.io, são as ações do usuário registradas antes de um crash
ClickBot Bot do ClickUp que cria automaticamente cards de incidente a partir de tickets recebidos
B2INFRA Prefixo dos tickets da fila de infraestrutura/sustentação no ClickUp
PGCOL Prefixo dos tickets vindos do cliente P&G Colômbia