Skip to content

feat(apps): Integração com Bling ERP na plataforma - #802

Open
vitorrgg wants to merge 2 commits into
mainfrom
bling
Open

feat(apps): Integração com Bling ERP na plataforma#802
vitorrgg wants to merge 2 commits into
mainfrom
bling

Conversation

@vitorrgg

@vitorrgg vitorrgg commented Aug 5, 2026

Copy link
Copy Markdown
Member

Porta o app Bling ERP (app_id 102418) do repositório app-bling-erp-v2 para o monorepo, usando a API v3 do Bling.

Funções

Função Papel
blingerp-onStoreEvent Eventos da loja: exporta pedidos e produtos, e processa a fila manual em applications-dataSet
blingerp-callback Callbacks de estoque e pedidos configurados no Bling
blingerp-authCallback Recebe o code do fluxo OAuth e grava os tokens
blingerp-cronRefreshToken Renova o access_token antes de expirar

Mudanças de arquitetura em relação ao app v1

  • A fila em Firestore (queue/{storeId}/events + running_events + handle-queue) deu lugar ao PubSub de eventos do monorepo (maxInstances: 1) com a fila em data do app;
  • appSdk multi-loja substituído por @cloudcommerce/api com as credenciais da própria loja;
  • Tokens OAuth em blingTokens/{storeId} e cache das situações de venda em blingStatuses/{storeId}, no projeto Firebase da loja;
  • Busca de produto por SKU usa products/skus:{sku} no lugar do ElasticSearch.

Correções sobre o comportamento do v1

Encontradas ao portar e ao validar contra a API real:

  1. Atualização de produto com variações falhava com HTTP 400 — a listagem /produtos?codigo= devolve o produto resumido, sem variacoes, então o PUT ia sem os IDs e o Bling rejeitava como se fossem novas variações;
  2. Preço por variação era perdido na exportação (o Bling aplica o preço do produto pai a todas) — corrigido com PUT /produtos/{idVariacao} apenas para as divergentes;
  3. Callback de estoque de variação sem SKU no Bling era descartado em silêncio — agora usa o ID do Bling como referência, que é o SKU gravado na importação;
  4. Configuração "Importar produto" não tinha efeito — o callback forçava canCreateNew: false;
  5. Falhas em exportação automática não apareciam no painel do lojista, só no log da função;
  6. Status "Devolvido" era enviado como fulfillment_status inválido;
  7. Limite diário da API gravava a flag invertida, liberando novas chamadas em vez de bloquear;
  8. other_config era lido como outher_config (typo), então o tipo de contato nunca era aplicado;
  9. Comparação de estoque usava um campo inexistente no Bling (quantity), causando lançamento redundante a cada exportação;
  10. Sem situação correspondente no Bling, o pedido falhava — agora registra aviso e segue exportado.

Grades de variação importadas passam a mapear para size/age_group/gender (antes só Cor era normalizada), mantendo o round-trip estável com a exportação.

Testes

packages/apps/bling-erp/tests/ — 37 testes com node --test, offline, sem credenciais: pedido e produto nos dois sentidos, mapeamento de status (incluindo parse_status customizado), endereço/CEP, parcelamento, prazo de entrega com dias úteis e feriados, variações sem SKU e normalização de grades.

scripts/bling-smoke.mjs faz uma varredura read-only na API do Bling validando credenciais e todos os endpoints usados.

Validação em produção

Loja de teste (1011) + conta Bling de teste, com as funções deployadas em um projeto Firebase real:

  • Fluxo OAuth completo: autorização no Bling → blingerp-authCallback → tokens no Firestore;
  • Callback público: estoque alterado no Bling refletiu na loja (99 → 10);
  • Pedido pago na loja → evento → PubSub → blingerp-onStoreEvent → pedido criado no Bling com contato, item vinculado, frete, etiqueta e parcela;
  • Atualização de situação (delivered → "Atendido") e round-trip de status;
  • Produto com variações nos dois sentidos, incluindo um criado pela interface do Bling (sem SKU nas variações);
  • Importação de produto com imagem migrada do S3 do Bling para o storage da e-com.plus, e categoria criada na loja;
  • blingerp-cronRefreshToken executando e validando o token.

Notas

  • O registro do app no marketplace (título e admin_settings) continua no repositório app-bling-erp-v2; este pacote traz apenas o runtime;
  • Ao migrar uma loja que já usa o app v1, definir ignore_triggers nas configurações do app para o app central parar de processá-la;
  • pnpm-lock.yaml não foi atualizado neste PR — o CI instala com --no-frozen-lockfile.

🤖 Generated with Claude Code

vitorrgg and others added 2 commits August 4, 2026 14:31
Porta o app Bling ERP (app_id 102418) do repositório app-bling-erp-v2 para
o monorepo, usando a API v3 do Bling: exportação de pedidos e produtos,
importação de estoque, pedidos e categorias, e renovação automática dos
tokens OAuth.

Funções: `blingerp-onStoreEvent` (eventos da loja), `blingerp-callback`
(callbacks de estoque/pedidos do Bling), `blingerp-authCallback` (fluxo de
autorização OAuth) e `blingerp-cronRefreshToken`.

A fila do app v1 em Firestore (`queue/{storeId}/events` + `running_events`)
foi substituída pelo PubSub de eventos do monorepo, e o `appSdk` multi-loja
pelo `@cloudcommerce/api`. Tokens ficam em `blingTokens/{storeId}` e o cache
de situações de venda em `blingStatuses/{storeId}`.

Correções sobre o comportamento do app v1:
- atualização de produto com variações falhava com 400 no Bling, porque as
  variações eram enviadas sem ID (a listagem `/produtos?codigo=` devolve o
  produto resumido);
- preço por variação era perdido na exportação (o Bling aplica o preço do
  produto pai), agora corrigido com PUT por variação divergente;
- callback de estoque de variação sem SKU no Bling era descartado, agora usa
  o ID do Bling como referência;
- configuração "Importar produto" não tinha efeito, pois o callback forçava
  `canCreateNew: false`;
- status "Devolvido" era enviado como fulfillment inválido;
- limite diário da API gravava a flag invertida, liberando novas chamadas;
- grades de variação importadas viram `size`/`age_group`/`gender` como no
  sentido inverso, em vez de slug do rótulo;
- sem situação correspondente no Bling, o pedido não falha mais: registra
  aviso e segue exportado.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Erros em exportações disparadas por evento da loja (não pela fila manual) só
apareciam no log do Cloud Functions, ficando invisíveis para o lojista no
painel. Sucessos de importação continuam fora do log para não inundá-lo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant