Skip to content

feat(ng-add): adicionar opção de telemetria anônima no schematic ng-add#2757

Open
pedrodominguesp wants to merge 2 commits intomasterfrom
devin/1772744369-telemetry-ng-add
Open

feat(ng-add): adicionar opção de telemetria anônima no schematic ng-add#2757
pedrodominguesp wants to merge 2 commits intomasterfrom
devin/1772744369-telemetry-ng-add

Conversation

@pedrodominguesp
Copy link
Copy Markdown
Member

@pedrodominguesp pedrodominguesp commented Mar 5, 2026

feat(ng-add): adicionar opção de telemetria anônima no schematic ng-add

Summary

Adiciona suporte a telemetria anônima opt-in durante o fluxo de ng add @po-ui/ng-components. As alterações incluem:

  • schema.json: Nova propriedade enableTelemetry (boolean, default false) com x-prompt em PT-BR. Também renomeia $id/title para seguir padrão PO UI.
  • index.ts: Nova regra configureTelemetry() na chain do ng-add que cria .po-ui-telemetry.json na raiz do projeto consumidor com { enabled, consentDate, version }.
  • telemetry-notice.js: Script informativo de postinstall (não interativo) que exibe mensagem sobre telemetria. Suprimido em ambientes CI.
  • telemetry-prompt.js: Alternativa interativa com readline (não ativada por padrão) com timeout de 30s e detecção de CI/TTY.
  • package.json: Registra o postinstall script apontando para telemetry-notice.js.
  • Testes: 4 novos testes cobrindo cenários de enableTelemetry: true, false, não informado, e validação da estrutura JSON.

Updates since last revision

  • Corrigida formatação prettier nos dois scripts postinstall (telemetry-notice.js, telemetry-prompt.js), que causava falha no CI lint.

Review & Testing Checklist for Human

  • BREAKING: configSideMenu mudou de default: true para default: false e perdeu x-prompt e x-user-analytics. Isso altera o comportamento do ng add para todos os usuários existentes — o sidemenu não será mais oferecido por padrão. Verificar se isso é intencional.
  • tree.create() em configureTelemetry falha se o arquivo já existe (ex: rodar ng add duas vezes). Considerar usar tree.exists() + tree.overwrite() como fallback.
  • Todos os testes estão dentro de xdescribe (linha 14 do spec), ou seja, são ignorados pelo test runner. Os novos testes de telemetria nunca serão executados em CI. Avaliar se o xdescribe deve ser convertido para describe.
  • Validar que o caminho node ./schematics/postinstall/telemetry-notice.js no postinstall resolve corretamente quando o pacote está instalado em node_modules/@po-ui/ng-components/.
  • Testar manualmente o fluxo completo: ng new app && cd app && ng add @po-ui/ng-components — verificar que o prompt de telemetria aparece e que .po-ui-telemetry.json é criado com o conteúdo correto.

Notes

  • O filtro de cópia em scripts/schematics.js já copia arquivos .js, então postinstall/telemetry-notice.js deve ser incluído automaticamente no dist, mas isso não foi verificado com um build real.
  • O arquivo .po-ui-telemetry.json criado no projeto consumidor pode precisar ser adicionado ao .gitignore dos projetos — considerar mencionar na documentação.
  • A heurística findProjectRoot() em telemetry-prompt.js usa !dir.includes('node_modules') como string check, que pode ter edge cases.
  • CI Status: O lint check inicial falhou devido à formatação prettier dos scripts JS, mas foi corrigido. Há 1 teste falhando (PoPageContentComponent: should call recalculateHeaderSize), mas é um teste flaky pré-existente não relacionado às mudanças deste PR.

Link to Devin Session: https://totvs.devinenterprise.com/sessions/805932f3424449d1922d9126868a3c21
Requested by: @pedrodominguesp

- Atualizar schema.json com propriedade enableTelemetry e x-prompt em PT-BR
- Adicionar função configureTelemetry no index.ts para criar .po-ui-telemetry.json
- Criar script postinstall informativo (telemetry-notice.js)
- Criar script postinstall interativo alternativo (telemetry-prompt.js)
- Registrar postinstall no package.json do @po-ui/ng-components
- Adicionar testes unitários para a configuração de telemetria

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an opt-in anonymous telemetry option to the ng add @po-ui/ng-components flow, plus a postinstall notice to inform users about telemetry.

Changes:

  • Adds enableTelemetry option to the ng-add schema and wires a new configureTelemetry() rule into the schematic chain.
  • Introduces postinstall scripts (telemetry-notice.js and an alternative interactive telemetry-prompt.js) and registers the notice in projects/ui/package.json.
  • Adds schematic tests intended to validate creation/structure of .po-ui-telemetry.json.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
projects/ui/schematics/postinstall/telemetry-prompt.js Adds an interactive telemetry prompt script (currently not wired by default).
projects/ui/schematics/postinstall/telemetry-notice.js Adds a non-interactive postinstall notice about telemetry.
projects/ui/schematics/ng-add/schema.json Adds enableTelemetry option and changes existing configSideMenu defaults/prompt metadata.
projects/ui/schematics/ng-add/index.ts Adds configureTelemetry() rule to create .po-ui-telemetry.json.
projects/ui/schematics/ng-add/index.spec.ts Adds tests for telemetry config creation/structure.
projects/ui/package.json Registers a postinstall script to run telemetry-notice.js.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

process.env.CIRCLECI ||
process.env.JENKINS_URL;

if (isCI) {
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

The comment says the notice should not be shown in CI or when stdin is non-interactive, but the code only checks CI env vars. Either add a process.stdin.isTTY (and/or process.env.npm_config_yes) guard, or update the comment so it matches the actual behavior.

Suggested change
if (isCI) {
const isNonInteractive = !process.stdin.isTTY || process.env.npm_config_yes;
if (isCI || isNonInteractive) {

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +41
function configureTelemetry(options: any): Rule {
return (tree: Tree) => {
const telemetryConfig = {
enabled: options.enableTelemetry === true,
consentDate: new Date().toISOString(),
version: '0.0.0-PLACEHOLDER'
};

tree.create('.po-ui-telemetry.json', JSON.stringify(telemetryConfig, null, 2));

Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

configureTelemetry() is always creating .po-ui-telemetry.json and always writing a consentDate, even when enableTelemetry is false/undefined. For an opt-in flow this records a consent timestamp without consent and also leaves a new file in the consumer project even when telemetry is disabled. Consider only creating the file (and setting consentDate) when options.enableTelemetry === true, and otherwise skipping the rule (or writing only { enabled: false } without a timestamp).

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +41
tree.create('.po-ui-telemetry.json', JSON.stringify(telemetryConfig, null, 2));

Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

tree.create('.po-ui-telemetry.json', ...) will throw if the file already exists (e.g. running ng add twice or if the user already has a config). This would break the schematic execution. Consider checking tree.exists() and using tree.overwrite() (or skipping) as a fallback.

Suggested change
tree.create('.po-ui-telemetry.json', JSON.stringify(telemetryConfig, null, 2));
const telemetryConfigContent = JSON.stringify(telemetryConfig, null, 2);
if (tree.exists('.po-ui-telemetry.json')) {
tree.overwrite('.po-ui-telemetry.json', telemetryConfigContent);
} else {
tree.create('.po-ui-telemetry.json', telemetryConfigContent);
}

Copilot uses AI. Check for mistakes.
"x-prompt": "Would you like to configure Sidemenu?",
"x-user-analytics": 17
"description": "Configure side menu layout",
"default": false
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

configSideMenu changed from default true with x-prompt/x-user-analytics to default false without any prompt/analytics. This is a behavioral change for all ng add users (the side menu option will no longer be offered and will default off). If this wasn’t intentional for this telemetry feature, consider restoring the previous default and prompt/analytics fields.

Suggested change
"default": false
"default": true,
"x-prompt": "Deseja configurar o layout de menu lateral?",
"x-user-analytics": {
"featureName": "configSideMenu"
}

Copilot uses AI. Check for mistakes.
"type": "boolean",
"description": "Enable anonymous telemetry to help the PO UI team improve components",
"default": false,
"x-prompt": "Deseja habilitar telemetria anônima para ajudar a equipe do PO UI a melhorar os componentes?"
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

The new enableTelemetry prompt text is in PT-BR, but existing schematic x-prompt messages in this repo are in English (e.g. projects/ui/schematics/ng-generate/po-page-*/schema.json). To keep CLI prompts consistent, consider using English here as well (or standardize prompts repo-wide if PT-BR is the new desired convention).

Suggested change
"x-prompt": "Deseja habilitar telemetria anônima para ajudar a equipe do PO UI a melhorar os componentes?"
"x-prompt": "Enable anonymous telemetry to help the PO UI team improve components?"

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +108
describe('Telemetry configuration:', () => {
it('should create .po-ui-telemetry.json with enabled true when enableTelemetry is true', async () => {
const tree = await runner.runSchematic('ng-add', { ...componentOptions, enableTelemetry: true }, appTree);

const telemetryConfig = JSON.parse(getFileContent(tree, '.po-ui-telemetry.json'));
expect(telemetryConfig.enabled).toBe(true);
expect(telemetryConfig.consentDate).toBeDefined();
expect(telemetryConfig.version).toBe('0.0.0-PLACEHOLDER');
});

it('should create .po-ui-telemetry.json with enabled false when enableTelemetry is false', async () => {
const tree = await runner.runSchematic('ng-add', { ...componentOptions, enableTelemetry: false }, appTree);

const telemetryConfig = JSON.parse(getFileContent(tree, '.po-ui-telemetry.json'));
expect(telemetryConfig.enabled).toBe(false);
expect(telemetryConfig.consentDate).toBeDefined();
expect(telemetryConfig.version).toBe('0.0.0-PLACEHOLDER');
});

it('should create .po-ui-telemetry.json with enabled false when enableTelemetry is not provided', async () => {
const tree = await runner.runSchematic('ng-add', componentOptions, appTree);

const telemetryConfig = JSON.parse(getFileContent(tree, '.po-ui-telemetry.json'));
expect(telemetryConfig.enabled).toBe(false);
expect(telemetryConfig.consentDate).toBeDefined();
expect(telemetryConfig.version).toBe('0.0.0-PLACEHOLDER');
});

it('should have correct JSON structure in .po-ui-telemetry.json', async () => {
const tree = await runner.runSchematic('ng-add', { ...componentOptions, enableTelemetry: true }, appTree);

const telemetryConfig = JSON.parse(getFileContent(tree, '.po-ui-telemetry.json'));

const keys = Object.keys(telemetryConfig);
expect(keys).toContain('enabled');
expect(keys).toContain('consentDate');
expect(keys).toContain('version');
expect(keys.length).toBe(3);
});
});
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

These telemetry tests are added under an xdescribe(...) suite, so they will be skipped by Jasmine and won’t run in CI (including via npm run test:ui:schematics). If these tests are meant to validate the new behavior, switch to describe(...) so the suite executes.

Copilot uses AI. Check for mistakes.
Comment on lines +42 to +47
// Timeout de 30 segundos para não travar a instalação
setTimeout(() => {
console.log('\nTimeout atingido. Telemetria não habilitada.');
rl.close();
process.exit(0);
}, 30000);
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

The 30s setTimeout is never cleared when the user answers the question. This keeps the process alive for 30 seconds even after input, and will later print the timeout message / call process.exit(0) after the prompt already completed. Store the timeout handle and clearTimeout(...) before closing the readline interface.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +35
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));

if (enabled) {
console.log('\u2705 Telemetria habilitada. Obrigado por ajudar!');
} else {
console.log('Telemetria não habilitada. Você pode habilitar depois com: ng add @po-ui/ng-components');
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

fs.writeFileSync(...) in a postinstall script can throw (permissions, read-only FS, etc.) and would fail the installation. Consider wrapping the file write (and JSON stringify) in a try/catch and exiting gracefully (status 0) if writing the config isn’t possible.

Suggested change
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
if (enabled) {
console.log('\u2705 Telemetria habilitada. Obrigado por ajudar!');
} else {
console.log('Telemetria não habilitada. Você pode habilitar depois com: ng add @po-ui/ng-components');
try {
const configJson = JSON.stringify(config, null, 2);
fs.writeFileSync(configPath, configJson);
if (enabled) {
console.log('\u2705 Telemetria habilitada. Obrigado por ajudar!');
} else {
console.log('Telemetria não habilitada. Você pode habilitar depois com: ng add @po-ui/ng-components');
}
} catch (err) {
// Falha ao gravar o arquivo de configuração não deve quebrar a instalação
console.warn('Aviso: não foi possível salvar a preferência de telemetria.', err && err.message ? `Detalhes: ${err.message}` : '');

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Teste IA PR geradas por IA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants