Voltar ao Blog
AI & Development25 de janeiro de 20269 min de leitura

Usando Assistentes de Código com IA (Copilot, Claude Code) no Fluxo de Trabalho com Angular

DR

Doug Ribeiro

9 min de leitura

Nos três primeiros meses usando Copilot, eu aceitava sugestões demais. Era um desenvolvedor sênior com cerca de uma década em front-end na época, trabalhando com Angular desde 2017, e mesmo assim mergei bugs sutis porque o código gerado parecia plausível. Uma cadeia RxJS que usava switchMap onde eu precisava de exhaustMap. Uma atualização de signal que ignorava o contrato de imutabilidade. Um componente com uma subscription que nunca era limpa. O código compilava. Os testes passavam porque foram gerados pela mesma ferramenta e testavam o mesmo comportamento errado. Depois disso comecei a ser mais seletivo.

GitHub CopilotAutocompletar inline no editor …Modo agente no VS Code, com edi…Um agente de código que trabalh…Instruções customizadas do repo…Code review e resumos de PR no …Claude CodeRoda no terminal, não dentro de…Lê o repositório em si em vez d…Um arquivo de instruções do pro…Trabalho em várias etapas: edit…Scriptável, então dá para rodar…VS

Os dois não competem tanto em funcionalidades quanto no lugar que ocupam. O Copilot mora no editor e completa o que estou digitando. O Claude Code mora no terminal e trabalha no repositório: ele lê arquivos que eu não abri, faz uma alteração espalhada por vários deles, roda a suíte de testes e reage ao que falhou. A outra diferença é onde a política mora. O Copilot Business responde ao admin de uma organização, que é por isso que era ele que eu usava no trabalho. Nos meus próprios projetos ninguém define essa política além de mim.

Para Que Ferramentas de IA São Realmente Boas

Os ganhos são reais nas categorias certas. Qualquer tarefa que seja estrutural e repetitiva, onde o formato da saída é bem definido e eu estaria apenas preenchendo um padrão que já conheço, a IA é mais rápida do que eu. Qualquer tarefa que exija julgamento sobre arquitetura, regras de negócio ou correção comportamental sutil, a IA é uma distração.

  • Scaffolding de novos componentes e serviços que seguem padrões já existentes no codebase
  • Escrita de casos de teste Jest para um componente quando a implementação já existe
  • Geração de interfaces TypeScript a partir de respostas de API ou exemplos JSON
  • Criação de padrões regex e funções de formatação de data
  • Refatoração de blocos de código repetitivos em utilitários compartilhados
  • Sugestão de operadores RxJS quando você descreve o comportamento desejado em linguagem natural

O ganho de scaffolding em um serviço Angular típico é fácil de sentir. Em um codebase Angular atual, escrever um novo serviço com signals, tratamento de erros e padrões takeUntilDestroyed, seguindo as convenções do codebase, é um trabalho lento e cuidadoso sem IA. Com Copilot referenciando um serviço existente como template, vira uma passada curta com uma rodada de correções. Isso é tempo real economizado, e se acumula a cada serviço que um time adiciona.

O Problema das Versões do Angular

Angular mudou mais entre a v14 e a v19 do que em qualquer outro momento da sua história. Standalone components, signals, a nova sintaxe de control flow, inject() substituindo injeção por construtor na maioria dos padrões, guards funcionais, e do lado do NgRx, o Signal Store. Ferramentas de IA treinadas em código anterior à v16 vão gerar os padrões antigos com total confiança. Parecem corretos. Compilam. Só não são como se escreve Angular hoje.

  • Declarações de componentes baseadas em NgModule em vez de standalone: true
  • Injeção por construtor em vez de inject()
  • Teardown com Subject no ngOnDestroy em vez de takeUntilDestroyed
  • ngIf e ngFor em vez de @if e @for no control flow
  • Padrões antigos do NgRx em vez de Signal Store para estado de features
  • Injeção de ActivatedRoute por construtor em vez da nova abordagem com input binding

Eu reviso cada trecho de Angular gerado por IA para esses pontos antes de aceitar. Leva cerca de 15 segundos. Se a ferramenta gera um construtor com dependências injetadas, eu converto. Isso não é culpa da IA. É um problema de data de corte de conhecimento e dados de treinamento. A solução é conhecer os padrões atuais bem o suficiente para identificar as lacunas.

Como Eu Uso o Claude Code nos Meus Próprios Projetos

Nos meus próprios projetos, ou seja, o meu SaaS e qualquer projeto paralelo vivo no momento, o que eu quero é código que combine com o projeto, não código que combine com a documentação do framework. Então eu mantenho um arquivo de instruções do projeto no repositório descrevendo as convenções, e aponto para os arquivos específicos com os quais eu quero que uma peça nova se pareça. O prompt abaixo é o formato que funciona: nomear o arquivo de referência, nomear os padrões, nomear os serviços compartilhados.

typescript
// Prompt approach that produces consistent results
// (illustrative; paths and names are generic):
// "Generate a JobApplicationService following the same patterns as
// src/app/features/inbox/services/inbox.service.ts
// Use inject() for dependencies, expose state via signals,
// handle errors with the ErrorHandlerService already in core,
// and include takeUntilDestroyed where needed."

// The output follows the project's conventions rather than
// the generic Angular answer, which is what you want
// in a codebase that already has standards.

@Injectable({ providedIn: 'root' })
export class JobApplicationService {
  private http = inject(HttpClient);
  private errorHandler = inject(ErrorHandlerService);

  private _applications = signal<JobApplication[]>([]);
  private _saving = signal(false);

  readonly applications = this._applications.asReadonly();
  readonly saving = this._saving.asReadonly();

  track(postingId: string, stage: ApplicationStage): Observable<JobApplication> {
    this._saving.set(true);

    return this.http
      .post<JobApplication>('/api/applications', { postingId, stage })
      .pipe(
        tap(application => {
          this._applications.update(list => [...list, application]);
          this._saving.set(false);
        }),
        catchError(err => {
          this._saving.set(false);
          return this.errorHandler.handle(err);
        })
      );
  }
}

Usando IA em um Banco: Como São as Regras

Em um banco, a conversa sobre ferramentas de IA não é opcional. Bancos definem políticas sobre qual código pode ser enviado para serviços externos de IA, e a versão curta costuma ser a mesma: nada de lógica de negócio proprietária, nada de dados de clientes, nada de contratos de API internos. No BMO, o assistente do time era o GitHub Copilot Business, que tem as garantias de privacidade de dados empresariais. Eu não usava a interface de chat para colar código de serviços internos ou modelos de dados.

Na prática, isso significava que a IA me ajudava com padrões Angular e mecânicas de TypeScript, não com a lógica de domínio de crédito. Eu não pedia ajuda para implementar um algoritmo de decisão de crédito ou uma verificação de conformidade regulatória. Esses exigem julgamento e revisão humana, e enviá-los para uma IA de terceiros é um risco de governança de dados mesmo com planos enterprise.

  • Use assinaturas de nível enterprise com acordos de processamento de dados
  • Nunca cole credenciais, strings de conexão, segredos JWT ou PII em qualquer interface de IA
  • Nunca cole lógica de negócio proprietária ou schemas de API internos em chat de IA público
  • Revise código gerado da mesma forma que revisaria o PR de um desenvolvedor júnior: assuma erros, leia com atenção

As Barreiras de Proteção, e Qual Delas Realmente Bloqueia um Merge

Barreiras de proteção vêm em camadas e elas não são intercambiáveis. A camada de instruções vem primeiro: um arquivo de instruções no repositório que diz ao assistente o que é o codebase e o que ele nunca deve sugerir, e no Copilot Business, o content exclusion, que mantém caminhos inteiros fora do contexto do modelo desde o começo. Essa camada molda o que é gerado, e é a que eu detalhei no post sobre barreiras de proteção para IA em ambiente bancário. Ela não decide o que entra no merge. Quem decide isso é a pipeline. ESLint com regras do angular-eslint, Jest com threshold de cobertura, quality gates do SonarQube, tudo isso em todo pull request. Se a IA gera um padrão obsoleto, o lint falha e o merge é bloqueado. Repare no que não acontece automaticamente: se ela te entrega um método de serviço sem tratamento de erro, nada pega isso a menos que alguém tenha escrito a regra de lint ou o teste antes. As duas camadas são complementares, e a ordem é o ponto. Instruções são um pedido que o modelo é livre para ignorar. Um quality gate vermelho não é negociável. Se você só consegue construir uma das duas neste trimestre, construa a pipeline.

javascript
// eslint.config.js
// angular-eslint ships flat config from v18, and a v19 workspace
// generates this file instead of .eslintrc.json. These are the rules
// that catch what an AI assistant gets wrong most often in Angular.
// @ts-check
const eslint = require('@eslint/js');
const tseslint = require('typescript-eslint');
const angular = require('angular-eslint');

module.exports = tseslint.config({
  files: ['**/*.ts'],
  extends: [
    eslint.configs.recommended,
    ...tseslint.configs.recommended,
    ...angular.configs.tsRecommended,
  ],
  processor: angular.processInlineTemplates,
  rules: {
    '@angular-eslint/prefer-standalone': 'error',
    '@angular-eslint/no-lifecycle-call': 'error',
    '@angular-eslint/use-injectable-provided-in': 'error',
    '@typescript-eslint/no-explicit-any': 'warn',
    '@typescript-eslint/explicit-function-return-type': 'warn',
    'no-console': ['error', { allow: ['warn', 'error'] }],
  },
});

Ferramentas de IA dão alavancagem ao desenvolvedor que já conhece o framework. Dão falsa confiança ao desenvolvedor que não conhece.

Minha avaliação geral após dois anos de uso diário: o Copilot é o que fica aberto enquanto eu digito, e o Claude Code é para quem eu entrego uma tarefa inteira quando o trabalho atravessa vários arquivos e precisa rodar os testes. Os ganhos de velocidade em trabalho estrutural repetitivo são reais e se acumulam ao longo de um trimestre. A chave é tratar cada sugestão como um ponto de partida, não como uma solução. A revisão leva segundos. Pular essa etapa custa minutos para corrigir depois, se é que você percebe.

Referências

AIAngularClaude CodeCopilotDeveloper Tools