Skip to content

docs(web-push): guia de configuração do projeto Firebase do web push - #20

Open
daniloleonecarneiro wants to merge 5 commits into
etusdigital:mainfrom
daniloleonecarneiro:docs/web-push-fcm-setup
Open

docs(web-push): guia de configuração do projeto Firebase do web push#20
daniloleonecarneiro wants to merge 5 commits into
etusdigital:mainfrom
daniloleonecarneiro:docs/web-push-fcm-setup

Conversation

@daniloleonecarneiro

@daniloleonecarneiro daniloleonecarneiro commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Adiciona um guia operacional para apontar o web push de uma instalação para um projeto Firebase próprio, e o indexa na tabela de Operations do docs/README.md. O gatilho foi configurar uma instalação do zero: o caminho funciona, mas três comportamentos só ficam evidentes lendo o código e dois deles falham em silêncio.

Changes

  • docs/operations/web-push-fcm.md: o que pegar no Firebase Console, onde guardar a service account, o save na Super Admin UI, a instalação no site do cliente (shim na raiz + snippet), verificação por curl e problemas comuns.
  • docs/README.md: entrada na tabela de Operations.

Os pontos que o guia registra e que não são óbvios pelo código:

  • Salvar a web config sem a chave VAPID quebra o push sem emitir erro. A troca do firebaseConfig exige os seis campos obrigatórios; a da vapidKey não passa por essa checagem. O resultado é firebaseConfig de um projeto com vapidKey de outro, e o getToken cunha contra esse par sem reclamar.
  • POST /admin/integrations/fcm/test-connection não valida a credencial: faz JSON.parse e devolve o project_id. Chave revogada, expirada ou de outro projeto passa verde.
  • A rota servida, e não o upload para o S3, é a fonte da verdade. Uma instalação nova não precisa de BMS_ASSETS_URL nem de bucket público; a falha do regeneratePlatformServiceWorker é não-fatal e o PUT devolve 200 assim mesmo.
  • A substituição no web-push.js acontece nos literais do bundle porque o construtor do bmsPush chama initializeApp(this.firebaseConfig) num field initializer, antes da linha que aplica o override vindo do snippet. Config passada pela página chega tarde demais.

Type of change

  • Bug fix (fix:)
  • New feature (feat:)
  • Refactor (refactor:)
  • Docs only (docs:)
  • Tooling / chore (chore:)
  • Breaking change

Testing

Só documentação, sem mudança de comportamento — não rodei a suíte. Os comandos do guia foram executados contra uma instalação local configurada com um projeto Firebase novo:

  • GET /bms/web-push.js e GET /bms/push/:accountHash.js passam a servir o projectId configurado, sem resíduo dos literais do bundle, nas duas contas da instalação.

  • O web-push.js sai com a chave VAPID configurada. O service worker não a contém, o que é esperado: ele recebe apenas a web config e a URL do tracker.

  • A query de system_config e o cálculo do accountHash conferem com o que as rotas devolvem.

  • pnpm type-check passes

  • pnpm lint passes

  • pnpm test passes

  • Manually verified the change end-to-end (descrito acima)

Screenshots

Não se aplica.

Notes for reviewers

O guia está em pt-BR, seguindo operations/whatsapp-cloud.md. A seção de reset de senha do super-admin cobre dev local e usa placeholders, sem valores reais.

Os comportamentos descritos aqui estão apenas documentados, não corrigidos. O PR #21 fixa os dois mais perigosos em teste, também sem alterá-los — se a decisão for exigir o VAPID junto da web config, os testes de lá são o primeiro lugar a mudar.

Documenta como apontar o web push de uma instalação para um projeto Firebase
próprio: o que pegar no console, onde guardar a service account, o save na
Super Admin UI e como verificar o resultado nos artefatos servidos.

Cobre os pontos que não são óbvios pelo código:

- os quatro artefatos são renderizados a partir de templates versionados, e a
  rota servida — não o upload para o S3 — é a fonte da verdade;
- a substituição no web-push.js acontece nos literais do bundle porque o
  initializeApp roda num field initializer, antes do override do snippet;
- o firebaseConfig só é trocado com os seis campos obrigatórios presentes,
  enquanto o VAPID é trocado fora desse portão — salvar a config sem o VAPID
  deixa a instância num estado quebrado que não emite erro;
- testar a conexão só faz JSON.parse, então uma credencial inválida passa.

Inclui verificação por curl nas rotas públicas e uma tabela de troubleshooting.
As quebras no meio das frases e as tabelas de coluna larga deixavam o texto
picotado e difícil de ler. O prettier do repo usa proseWrap preserve, então as
quebras eram deliberadas e sem motivo.

Reordena o guia pela tarefa — o que pegar, configurar, verificar — e desce a
explicação de como os arquivos são gerados para depois disso. Troca a tabela de
troubleshooting por parágrafos curtos e reduz a de artefatos para três colunas.
Configurar o FCM habilita a instalação, mas nada registra até que o shim e o
snippet estejam no site. O guia parava na configuração e deixava essa metade
implícita, que é justamente a que falha calada: com só um dos dois no ar, o site
não capta assinatura nenhuma e nada indica isso.

Registra por que o arquivo precisa estar na raiz — escopo de service worker não
sobe de diretório — e a conferência do cookieDomain, que sai do domínio padrão
da conta e costuma vir com o domínio da própria instalação em vez do domínio do
site do cliente.

@filipecrosk filipecrosk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes before merge.

  1. The default_domain guidance needs to require an absolute URL, e.g. https://www.example.com. A bare domain makes the current new URL() path fall back to an empty cookie domain, creating a host-only cookie and breaking cross-subdomain identity.

  2. The verification command uses GNU-only sha256sum, but our documented development environment is macOS. Use shasum -a 256, or document both portable variants.

Um domínio configurado sem http(s):// (ex. www.shop.example.com) fazia
new URL() lançar, o catch vazio engolia o erro e o snippet saía com
cookieDomain vazio — cookie host-only, identidade quebrada entre
subdomínios, sem nenhum sinal do que houve. Prefixa http:// quando o
valor não tem esquema (mesmo fallback usado em mail.utils.ts) e loga
quando o domínio ainda assim não parseia.
Documenta explicitamente que default_domain precisa de esquema
(https://www.example.com), e a consequência de um domínio sem
esquema — cookie host-only e identidade quebrada entre subdomínios.

sha256sum é GNU-only e o ambiente de dev documentado é macOS; passa a
mostrar as duas variantes (sha256sum e shasum -a 256) no comando de
verificação do service worker.

@filipecrosk filipecrosk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two original requests are implemented, and the focused account-service tests pass. The runbook is now inconsistent with the code and with the related PR set:\n\n1. The new runtime path explicitly normalizes a schemeless by prefixing , but the runbook says a bare domain is parsed as a relative path and produces an empty/host-only cookie domain. Keep the absolute-URL recommendation, but document the actual compatibility behavior instead of a failure that no longer occurs.\n\n2. The “save all three at once” warning says Firebase config and VAPID replacement happen independently and can produce a mixed project/key. PR #21 now intentionally makes those substitutions atomic. Because these PRs are being reviewed and merged as one related set, update this runbook section and troubleshooting text to describe the final behavior after #21 (an incomplete pair leaves the bundle defaults unchanged).\n\nValidation at :\n- : 17 tests passed\n- msgops-api type-check passed\n- No GitHub checks are configured

@filipecrosk filipecrosk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two original requests are implemented, and the focused account-service tests pass. The runbook is now inconsistent with the code and with the related PR set:

  1. The new runtime path explicitly normalizes a schemeless default_domain by prefixing http://, but the runbook says a bare domain is parsed as a relative path and produces an empty/host-only cookie domain. Keep the absolute-URL recommendation, but document the actual compatibility behavior instead of a failure that no longer occurs.

  2. The “save all three at once” warning says Firebase config and VAPID replacement happen independently and can produce a mixed project/key. PR #21 now intentionally makes those substitutions atomic. Because these PRs are being reviewed and merged as one related set, update this runbook section and troubleshooting text to describe the final behavior after #21 (an incomplete pair leaves the bundle defaults unchanged).

Validation at b13a7c07e353fac52b217f4810a7fd6f3c49599a:

  • accounts.service.spec.ts: 17 tests passed
  • msgops-api type-check passed
  • No GitHub checks are configured

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.

2 participants