Documentação de Suporte
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
- Visão Geral do Ecossistema
- Stakeholders e Contatos
- Repositórios e Tecnologias
- Infraestrutura e Acessos
- Monitoramento com Sentry.io
- Fluxo Operacional Mensal
- Canal de Comunicação e Escalonamento
- Gestão de Incidentes no ClickUp
- Incidentes Recorrentes e Como Resolver
- Reuniões Recorrentes
- URLs e Ambientes
- Keycloak — Gestão de Usuários e Sessões
- ETL Coopidrogas — Como Funciona e Como Reprocessar
- SFTP da Coopidrogas
- Deploy — App Mobile (b2mobile-sentry)
- Deploy — Serviços Backend e Frontend
- Testes com Postman
- Glossário
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 | 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 | 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 | 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 |
| 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
- Acesse
https://dev-keycloak.b2list.com(DEV) ouhttps://hml-keycloak.b2list.com(HML) - Clique em "Administration Console"
- Faça login com as credenciais de admin (pedir ao Arvelos ou Daniel)
- Selecione o realm coopidrogas no dropdown superior esquerdo
Operações comuns
Resetar senha de um usuário
- Admin Console → Users → buscar pelo email da transferencista
- Clique no usuário → aba Credentials
- Clique em Reset password → definir nova senha temporária → enviar para o usuário
Verificar/encerrar sessões ativas
- Admin Console → Users → selecionar o usuário
- Aba Sessions → ver sessões ativas
- 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.
- Admin Console → Users → Create new user
- Preencher: Username (email), Email, First name, Last name
- Aba Credentials → definir senha temporária
- 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 Pipelines → Run 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:
- Acessar o repositório
b2mobile-sentryno Bitbucket - Ir em Pipelines → Run pipeline → selecionar
custom: deploy-release - Escolher o tipo de versão:
patch(bug fix) /minor(nova funcionalidade) /major - A pipeline:
- Lê a última tag Git
- Incrementa a versão no
app.json - Executa
eas build --platform androidno perfilproduction - Cria uma tag Git com o novo número de versão
- 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
- Acessar o Bitbucket → repositório → aba Pipelines
- Verificar o status do último pipeline (verde = sucesso, vermelho = falhou)
- 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
- Abrir o Postman
- Import → selecionar
LATAM.postman_collection.json - Import → selecionar o environment desejado (ex:
DEV.postman_environment.json) - 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_COOPIDROGASnos 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 |