feat(ui): adicionar serviço de telemetria opt-in para rastreamento de uso de componentes#2756
feat(ui): adicionar serviço de telemetria opt-in para rastreamento de uso de componentes#2756pedrodominguesp wants to merge 1 commit intomasterfrom
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Co-Authored-By: domingues.pedro <pehdomingues96@gmail.com>
816127d to
9ed2a79
Compare
There was a problem hiding this comment.
Pull request overview
Adiciona um serviço/módulo de telemetria opt-in ao @po-ui/ng-components para permitir rastreamento anônimo de uso de componentes (com consentimento), além de documentação e integrações no portal de guias.
Changes:
- Cria
PoTelemetryService+PoTelemetryModule.forRoot()com configuração, consentimento vialocalStoragee envio em batch via HTTP. - Adiciona constante
PO_UI_VERSION(placeholder substituído no build) para compor payload de telemetria. - Inclui guia de telemetria e atualiza menu/rotas do portal para expor a nova documentação.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| projects/ui/src/lib/utils/po-version.ts | Adiciona constante de versão do PO UI para uso em telemetria/build. |
| projects/ui/src/lib/services/services.module.ts | Exporta/importa PoTelemetryModule no agregador de serviços. |
| projects/ui/src/lib/services/po-telemetry/po-telemetry.service.ts | Implementa coleta, consentimento e envio batch/retry. |
| projects/ui/src/lib/services/po-telemetry/po-telemetry.service.spec.ts | Testes unitários de consentimento, envio em batch e retry. |
| projects/ui/src/lib/services/po-telemetry/po-telemetry.module.ts | Disponibiliza API forRoot para ativação/configuração opt-in. |
| projects/ui/src/lib/services/po-telemetry/po-telemetry.injection-token.ts | Injection token para configuração. |
| projects/ui/src/lib/services/po-telemetry/po-telemetry-config.interface.ts | Contrato de configuração do serviço. |
| projects/ui/src/lib/services/po-telemetry/index.ts | Barrel exports do pacote de telemetria. |
| projects/ui/src/lib/services/index.ts | Reexporta telemetria no índice de services. |
| projects/portal/src/app/guide/menu-guides.service.ts | Adiciona item “Telemetria” no menu de guias. |
| projects/portal/src/app/guide/guide.module.ts | Registra GuideTelemetryComponent no módulo de guias. |
| projects/portal/src/app/guide/guide-routing.module.ts | Adiciona rota guides/telemetry. |
| docs/guides/telemetry.md | Guia de uso/configuração e política de telemetria. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @Optional() @Inject(PO_TELEMETRY_CONFIG) private config: PoTelemetryConfig, | ||
| @Optional() private httpClient: HttpClient, | ||
| @Optional() private poDialogService: PoDialogService, |
There was a problem hiding this comment.
Os parâmetros marcados com @Optional() (config/httpClient/poDialogService) estão tipados como obrigatórios. Com strictInjectionParameters: true, o Angular espera que injeções opcionais aceitem null/undefined (ex.: usando ? ou | null); caso contrário pode falhar na checagem de injeção/compilação. Ajuste os tipos para config?: PoTelemetryConfig (ou PoTelemetryConfig | null) e o mesmo para httpClient e poDialogService.
| @Optional() @Inject(PO_TELEMETRY_CONFIG) private config: PoTelemetryConfig, | |
| @Optional() private httpClient: HttpClient, | |
| @Optional() private poDialogService: PoDialogService, | |
| @Optional() @Inject(PO_TELEMETRY_CONFIG) private config: PoTelemetryConfig | null, | |
| @Optional() private httpClient: HttpClient | null, | |
| @Optional() private poDialogService: PoDialogService | null, |
| private enabled: boolean; | ||
| private showConsentDialog: boolean; | ||
| private sessionId: string; | ||
| private intervalId: any; |
There was a problem hiding this comment.
intervalId está como any, o que perde type-safety e dificulta o uso correto de clearInterval. Tipar como ReturnType<typeof setInterval> | null (ou equivalente) evita casts e reduz risco de uso incorreto.
| private intervalId: any; | |
| private intervalId: ReturnType<typeof setInterval> | null = null; |
| private sendEvents(): void { | ||
| if (!this.httpClient || !this.endpointUrl) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
sendEvents retorna cedo quando HttpClient não está disponível ou endpointUrl está vazio. Se o consumidor configurar enabled: true e conceder consentimento nessa condição, o buffer pode crescer indefinidamente e nunca será drenado. Considere falhar rápido ao habilitar sem capacidade de envio (tornar HttpClient não-opcional e/ou validar endpointUrl), ou pausar coleta/intervalo até haver um endpoint e HTTP disponíveis.
| /** Se a telemetria está habilitada (default: false — opt-in). */ | ||
| enabled: boolean; | ||
|
|
||
| /** URL do endpoint que receberá os eventos. */ | ||
| endpointUrl: string; |
There was a problem hiding this comment.
Como enabled e endpointUrl são obrigatórios, não dá para usar PoTelemetryModule.forRoot({ enabled: false }) sem fornecer uma URL “dummy”. Para suportar desabilitar por config/env sem URL, considere tornar endpointUrl opcional quando enabled for false (union type) ou validar em runtime apenas quando enabled for true.
| | Campo | Descrição | | ||
| |---|---| | ||
| | `componentName` | Nome do componente utilizado (ex: `po-button`, `po-table`) | | ||
| | `libraryVersion` | Versão da biblioteca `@po-ui/ng-components` | |
There was a problem hiding this comment.
As linhas de tabela estão começando com || (ex.: || Campo | ...), o que geralmente impede a renderização correta em Markdown. Trocar para a sintaxe padrão | Campo | ... | melhora a leitura no portal e no GitHub.
| - Definir `enabled: false` na configuração | ||
|
|
There was a problem hiding this comment.
A doc indica que é possível desabilitar definindo apenas enabled: false, mas pela tipagem atual endpointUrl é obrigatório em PoTelemetryConfig. Ajustar a doc ou o tipo evita confusão para quem quer alternar telemetria via environment/config.
| - Definir `enabled: false` na configuração | |
| - Definir `enabled: false` na configuração, mantendo um `endpointUrl` válido conforme a tipagem de `PoTelemetryConfig`: | |
| ```typescript | |
| PoTelemetryModule.forRoot({ | |
| enabled: false, | |
| endpointUrl: 'https://my-telemetry-api.example.com/events' | |
| }); |
| @@ -0,0 +1,300 @@ | |||
| import { HttpClient } from '@angular/common/http'; | |||
| import { TestBed, fakeAsync, tick } from '@angular/core/testing'; | |||
There was a problem hiding this comment.
fakeAsync e tick são importados mas não são usados neste spec. Remover os imports evita warnings de lint/TS e mantém o arquivo mais enxuto.
| import { TestBed, fakeAsync, tick } from '@angular/core/testing'; | |
| import { TestBed } from '@angular/core/testing'; |
| | Propriedade | Tipo | Padrão | Descrição | | ||
| |---|---|---|---| | ||
| | `enabled` | `boolean` | `false` | Habilita ou desabilita a coleta de telemetria | | ||
| | `endpointUrl` | `string` | — | URL do endpoint que receberá os eventos | |
There was a problem hiding this comment.
A tabela de "Configurações disponíveis" também está usando || no início das linhas, o que costuma quebrar a renderização em Markdown. Ajustar para a sintaxe padrão com | garante que a tabela seja exibida corretamente.
| }; | ||
|
|
||
| this.buffer.push(event); | ||
| } |
There was a problem hiding this comment.
Não há limite para o tamanho do buffer; se o endpoint ficar indisponível por muito tempo, os eventos acumulam sem bound (impacto de memória). Sugestão: adicionar maxBufferSize (configurável) e política de descarte/backoff para evitar crescimento indefinido.
| this.sessionId = this.generateSessionId(); | ||
|
|
||
| this.initConsent(); | ||
| this.startBatchInterval(); | ||
| } |
There was a problem hiding this comment.
initConsent() e o possível confirm() são acionados no construtor. Isso pode disparar UI (diálogo) assim que o serviço é instanciado, inclusive durante bootstrap/injeções indiretas, o que tende a ser difícil de controlar por apps consumidores. Uma alternativa mais previsível é expor um método explícito de inicialização (ou inicializar sob demanda no primeiro trackComponentUsage) e/ou usar APP_INITIALIZER/ApplicationRef.isStable para adiar o prompt.
feat(ui): adicionar serviço de telemetria opt-in para rastreamento de uso de componentes
Resumo
Implementação de um novo serviço de telemetria (
PoTelemetryService) e módulo (PoTelemetryModule) para coleta opt-in de dados anônimos sobre uso de componentes PO UI. O serviço inclui:PoTelemetryConfig— interface de configuração com suporte a endpoint, intervalo de batch, chave de consentimento e literais customizadas para o diálogoPoTelemetryService— serviço que armazena eventos em buffer, envia em batch via HTTP POST, gerencia consentimento do usuário vialocalStorageePoDialogServicePoTelemetryModule.forRoot()— método de configuração para ativação opt-inPO_UI_VERSION— constante com placeholder de versão substituída durante build (similar ao padrão existente)docs/guides/telemetry.mdTelemetria é desabilitada por padrão. Requer:
PoTelemetryModule.forRoot({ enabled: true, endpointUrl: '...' })— configuração explícita pelo desenvolvedorgrantConsent()/revokeConsent()O que foi implementado (conforme especificação)
✅ Seções 1-3, 5-8 da especificação original
❌ Seção 4 (instrumentação de componentes via decorator/classe base) não foi implementada — ficará como trabalho futuro
Checklist de Revisão e Testes
npm run test:uipara verificar se os testes dopo-telemetry.service.spec.tspassamnpm run build:portal:docspara confirmar que o guia de telemetria é gerado corretamentepo-telemetry.service.ts). Isso significa que o diálogo aparece assim que o serviço é instanciado. Confirmar se esse é o comportamento desejado ou se deveria ser adiado (ex:APP_INITIALIZER).intervalId: any— linha 45 depo-telemetry.service.tsusaany, o que viola as diretrizes do projeto. Considerar substituir porReturnType<typeof setInterval> | null.Plano de Teste Sugerido
PoTelemetryModule.forRoot({ enabled: true, endpointUrl: 'http://localhost:3000/telemetry', showConsentDialog: true })po-button,po-table)Observações
guide-routing.module.ts,guide.module.tsemenu-guides.service.tsforam editados manualmente para incluir a rota de telemetria, mas esses arquivos são normalmente regenerados durantegulp build:guides. As edições são consistentes com o padrão existente (outros guias também estão commitados dessa forma), mas serão sobrescritas no próximo build do portal.PO_UI_VERSION = '0.0.0-PLACEHOLDER'é substituída automaticamente durante o build peloscripts/version-replace.js(padrão existente).@PoTrackUsage()ou classe base para instrumentar componentes automaticamente. Isso foi deliberadamente deixado de fora desta PR inicial — a API detrackComponentUsage()está pronta, mas cabe ao consumidor chamá-la manualmente ou implementar o decorator em follow-up.Link para Sessão Devin: https://totvs.devinenterprise.com/sessions/db6c7993d59d46d780ca1ad5a7973959
Solicitado por: @pedrodominguesp