Desenvolvimento de Software com IA
Domine as ferramentas, técnicas e workflows para desenvolver software de alta qualidade com assistência de inteligência artificial — desde a configuração do ambiente até testes, debugging e segurança.
Fundamentos do Desenvolvimento IA Driven
A nova mentalidade para construir software na era da IA
O desenvolvimento de software assistido por IA não é apenas adicionar um autocomplete mais inteligente ao seu editor. É uma mudança fundamental na forma como você pensa, planeja e executa código. Desenvolvedores que tratam ferramentas de IA como simples utilitários perdem 80% do potencial — aqueles que as integram ao fluxo cognitivo multiplicam sua produtividade.
Princípios Fundamentais
Seja específico sobre o que quer. A IA performa proporcionalmente à qualidade da instrução. Prompts vagos geram código genérico.
Trate cada resposta como um rascunho. Refine, questione e itere. O primeiro output raramente é o final.
Quanto mais contexto relevante você fornece (arquivos, padrões, exemplos), melhor o output. Context-stuffing estratégico é uma habilidade.
Nunca aceite código gerado sem revisão. A IA pode criar bugs sutis, problemas de segurança e lógica incorreta com confiança alta.
Use IA para gerar código dentro de uma arquitetura já definida. Deixar a IA definir a arquitetura leva a inconsistências.
IA acelera geração de código mas não dispensa revisão, testes e documentação. Velocidade sem qualidade gera dívida técnica.
A Nova Mentalidade do Desenvolvedor
O desenvolvedor moderno opera como um arquiteto e curador de código, não apenas como um escritor. Você define intenções claras, avalia outputs, refina iterativamente e integra soluções em um sistema coerente.
1. Intenção → Defina claramente o que precisa ser construído.
2. Contextualização → Forneça arquivos relevantes, padrões e restrições.
3. Geração → Deixe a IA produzir o código inicial.
4. Avaliação → Revise criticamente: lógica, segurança, performance.
5. Refinamento → Itere com feedback específico.
6. Integração → Integre no codebase com testes.
Apps Novas vs Apps Existentes
A abordagem de desenvolvimento com IA difere substancialmente dependendo se você está criando algo novo ou trabalhando em um codebase existente.
| Aspecto | Aplicação Nova (Greenfield) | Aplicação Existente (Brownfield) |
|---|---|---|
| Ponto de partida | Scaffolding completo via prompts | Exploração e mapeamento do codebase |
| Contexto inicial | Especificações, stack escolhida, padrões desejados | Arquivos existentes, CLAUDE.md ou README, estilos de código |
| Principal desafio | Manter consistência à medida que o projeto cresce | Respeitar padrões existentes sem introduzir inconsistências |
| Rules/Memories | Criar rules desde o início, antes de escrever código | Criar rules que refletem os padrões já existentes no código |
| Testes | TDD com geração de testes antes do código | Geração de testes para código legado, identificar cobertura |
| Risco principal | Divergência de arquitetura entre sessões | Quebra de funcionalidades existentes, conflito de estilos |
Ao trabalhar com código legado, a IA tende a propor refactoring não solicitado. Sempre instrua explicitamente: "Modifique apenas o que é necessário para esta feature. Não refatore código não relacionado."
Comparativo de Ferramentas
Cursor vs Windsurf vs GitHub Copilot — quando usar cada um
O mercado de IDEs e ferramentas com IA evoluiu rapidamente. Cada ferramenta tem uma filosofia diferente: Cursor aposta em autonomia e edição inline profunda; Windsurf foca na experiência fluída com "Flows"; GitHub Copilot é onipresente e integrado ao ecossistema Microsoft/GitHub. Escolher a ferramenta certa para o contexto certo é fundamental.
- Cmd+K para edição inline contextual em qualquer arquivo
- Composer para mudanças multi-arquivo com autonomia
- Rules (.cursorrules) com contexto persistente por projeto
- Indexação completa do codebase para contexto semântico
- Suporte a Claude 3.5/3.7, GPT-4o, Gemini Pro
- Agent mode com execução de terminal e navegação em arquivos
- Notepads para contexto reutilizável entre conversas
- Cascade: agente com memória de fluxo longo ("Flows")
- Experiência mais fluida e menos interruptiva que o Cursor
- Melhor para sessões longas de desenvolvimento contínuo
- Context awareness automático sem necessidade de @-mencionar
- Plano gratuito generoso para desenvolvedores iniciantes
- Integração nativa com a Codeium Cloud e modelos próprios
- Integração nativa com VS Code, JetBrains, Neovim, Xcode
- Copilot Chat com context de PR, issues e código
- Copilot Workspace para planning e execução de tasks de issues
- Melhor integração com GitHub Actions e CI/CD
- Revisão automática de PRs com sugestões de qualidade
- Disponível em planos GitHub existentes (menos fricção corporativa)
Quando Usar Cada Ferramenta
| Cenário | Recomendação | Motivo |
|---|---|---|
| Projeto novo com muita autonomia | Cursor (Agent Mode) | Composer lida com múltiplos arquivos, rules definem padrões desde o início |
| Exploração de codebase desconhecido | Windsurf (Cascade) | Context awareness automático reduz fricção de contextualização |
| Time usando GitHub + CI/CD | GitHub Copilot | Integração nativa com PRs, issues, Actions e segurança corporativa |
| Refactoring pesado em codebase grande | Cursor (Composer) | Melhor controle sobre quais arquivos são alterados |
| Desenvolvimento educacional / aprendizado | Windsurf | Plano gratuito generoso, experiência mais fluida para iniciantes |
| Ambientes JetBrains (IntelliJ, PyCharm) | GitHub Copilot | Único com suporte nativo profissional para IDEs JetBrains |
Muitos desenvolvedores senior usam combinações: Cursor para desenvolvimento principal + Copilot no pipeline CI/CD para revisão de PRs. Não se prenda a uma única ferramenta — avalie pelo caso de uso.
Biblioteca de Prompts para Desenvolvimento
Templates e padrões para maximizar a qualidade do código gerado
Uma biblioteca de prompts bem estruturada é um ativo de produtividade tão valioso quanto um bom conjunto de snippets. Ao padronizar como você instrui a IA, você obtém outputs mais consistentes e reduz o tempo de refinamento.
Prompts Essenciais para Desenvolvimento
1. Prompt de Implementação com Contexto
2. Prompt para Code Review
3. Prompt para Debugging com Stack Trace
Estruturação de Documentação como Contexto
Documentação estruturada como contexto é uma das técnicas mais subutilizadas. Em vez de explicar o projeto a cada sessão, crie arquivos de contexto que a IA pode ler automaticamente via rules ou @-menção.
ARCHITECTURE.md — decisões de arquitetura, padrões, restrições
CODING_STANDARDS.md — naming, formatação, padrões de projeto
API_REFERENCE.md — contratos de API, tipos, exemplos
.cursorrules ou CLAUDE.md — instruções diretas para a IA
# Arquitetura do Projeto
## Stack Tecnológico
- Runtime: Node.js 20 LTS + TypeScript 5.x
- Framework: Fastify v4 (NÃO Express — já decidido e documentado em ADR-001)
- ORM: Prisma com PostgreSQL 15
- Cache: Redis 7 via ioredis
- Fila: BullMQ para jobs assíncronos
- Testes: Vitest + Supertest
## Padrões de Código
- Arquitetura: Feature-based modules (não layers)
- Nomenclatura: camelCase para variáveis, PascalCase para tipos/classes
- Erro handling: Result pattern (never throw, return { data, error })
- Logs: Pino com structured logging, sempre incluir requestId
## Estrutura de Pastas
src/
├── features/ # Módulos por domínio de negócio
│ ├── users/
│ │ ├── users.service.ts
│ │ ├── users.repository.ts
│ │ ├── users.routes.ts
│ │ └── users.schema.ts
├── shared/ # Utilitários compartilhados
├── infra/ # Config, DB, cache, queues
└── types/ # Types globais
## Restrições Importantes
- NUNCA usar `any` em TypeScript
- Toda query ao banco deve passar pelo repository
- Autenticação via JWT — tokens de 15min + refresh 7d
- Rate limiting obrigatório em endpoints públicos
Rules e Memories
Persistência de contexto e personalização do comportamento da IA
Rules e Memories são mecanismos para ensinar à IA os padrões específicos do seu projeto sem precisar repetir instruções a cada sessão. São a diferença entre uma IA que "conhece" seu projeto e uma que começa do zero toda vez.
Cursor Rules — Anatomia e Boas Práticas
O arquivo .cursorrules (ou .cursor/rules/ na versão mais recente) é um arquivo de texto que define o comportamento global do Cursor dentro do projeto. É lido automaticamente em todo contexto de conversa.
- Identidade e Role: Defina o papel da IA (ex: "Você é um desenvolvedor senior TypeScript especializado em APIs REST").
- Stack e Versões: Liste as tecnologias, versões e restrições de upgrade.
- Padrões de Código: Naming, estrutura, padrões de projeto que o código deve seguir.
- Regras de Comportamento: O que a IA deve e não deve fazer (refatorar, adicionar dependências, etc.).
- Exemplos de Código: Inclua snippets de código que representam o padrão desejado.
- Contexto de Negócio: Breve descrição do domínio para melhorar a relevância das sugestões.
# Cursor Rules — Sistema de Gestão Financeira (FinanceOS)
## Identidade
Você é um desenvolvedor TypeScript senior especializado em sistemas financeiros.
Seu código é seguro, tipado, testável e segue os padrões estabelecidos.
## Stack Tecnológico
- TypeScript 5.4 (strict mode SEMPRE ativado)
- Node.js 20 LTS + Fastify v4
- Prisma 5 + PostgreSQL 15
- Vitest para testes unitários e de integração
- Zod para validação de schemas
## Padrões de Código Obrigatórios
### Nomenclatura
- Funções: camelCase, verbos descritivos (getUserById, calculateTax)
- Interfaces: PascalCase, prefixo 'I' NÃO usado (User, não IUser)
- Types: PascalCase (UserCreateInput, not CreateUserDTO)
- Enums: PascalCase com valores SCREAMING_SNAKE (UserRole.ADMIN)
- Arquivos: kebab-case (user-service.ts, not userService.ts)
### Error Handling (CRÍTICO)
NUNCA use try-catch direto. Use o Result pattern:
```typescript
type Result = { data: T; error: null } | { data: null; error: E };
// Correto:
async function getUser(id: string): Promise> {
try {
const user = await prisma.user.findUnique({ where: { id } });
if (!user) return { data: null, error: new Error('User not found') };
return { data: user, error: null };
} catch (err) {
return { data: null, error: err as Error };
}
}
```
### Validação de Input
Sempre use Zod para validação. Nunca confie em dados externos:
```typescript
const CreateUserSchema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
role: z.nativeEnum(UserRole).default(UserRole.USER),
});
```
### Logging
Use structured logging com Pino. Sempre inclua requestId:
```typescript
logger.info({ requestId, userId, action: 'user.created' }, 'User created successfully');
```
## Regras de Comportamento
### O que fazer:
- Sempre inferir tipos explicitamente quando não é óbvio
- Incluir comentários JSDoc para funções públicas
- Criar testes para toda lógica de negócio
- Seguir o padrão Repository para acesso a dados
### O que NÃO fazer:
- NUNCA usar `any` — use `unknown` se necessário
- NUNCA fazer refactoring de código não relacionado à tarefa
- NUNCA adicionar dependências novas sem perguntar
- NUNCA expor dados sensíveis (senha, token) em logs ou respostas
- NUNCA usar `console.log` — use o logger Pino
## Contexto do Negócio
FinanceOS é um sistema de gestão financeira para PMEs brasileiras.
Opera com entidades: Company, User, Transaction, Account, Category.
Compliance: LGPD (dados pessoais devem ser tratados com cuidado).
Moeda padrão: BRL. Fuso horário: America/Sao_Paulo.
Memories em Ferramentas de IA
Além das rules de projeto, ferramentas como Cursor têm o conceito de "Memories" — informações que persistem entre sessões a nível de usuário (não projeto). São úteis para preferências pessoais de desenvolvimento.
Preferências pessoais: linguagem preferida de resposta, nível de explicação, tom da comunicação (formal/casual), preferência por comentários no código.
Padrões técnicos específicos do projeto, stack, naming conventions. Versionadas junto ao código no repositório.
Blocos de contexto reutilizável que você pode @-mencionar. Ideal para especificações, padrões de API, documentação de domínio.
Arquivos do projeto que você inclui sistematicamente: ARCHITECTURE.md, schema.prisma, types/index.ts. Contexto semântico consistente.
Use a própria IA para gerar suas rules iniciais: "Analise estes 5 arquivos de código do meu projeto e gere um .cursorrules que capture os padrões de estilo, nomenclatura, error handling e arquitetura que você identificou." Depois refine manualmente o resultado.
Testes e Debugging com IA
Automação de testes, cobertura de edge cases e debugging inteligente
Testes Automatizados
A geração de testes com IA é uma das aplicações mais valiosas e menos exploradas. A IA não apenas escreve os testes óbvios — quando bem instruída, ela identifica edge cases, condições de contorno e cenários de falha que desenvolvedores humanos frequentemente ignoram.
Peça à IA para gerar os testes antes da implementação. Isso força clareza nos requisitos e produz uma especificação executável. Depois peça para implementar o código que passa nos testes.
Gere testes unitários completos para a seguinte função/classe usando Vitest.
**Código a testar:**
```typescript
[COLE O CÓDIGO AQUI]
```
**Requisitos para os testes:**
1. **Happy path:** Teste todos os fluxos de sucesso com dados válidos realistas.
2. **Edge cases obrigatórios:**
- Valores null e undefined para cada parâmetro
- Strings vazias e strings com apenas espaços
- Arrays/objetos vazios
- Valores nos limites (0, -1, MAX_INT para números)
- Caracteres especiais e Unicode em strings
3. **Error cases:**
- Cada condição de erro documentada no código
- Erros de rede/IO mockados (se aplicável)
- Timeout e comportamento assíncrono
4. **Estrutura dos testes:**
- Use describe/it aninhados para organização
- Nomes descritivos: "should return null when user not found"
- Setup com beforeEach para dados compartilhados
- Mocks isolados por teste (vi.clearAllMocks no afterEach)
5. **Cobertura esperada:** >= 90% de branches e statements
**Framework:** Vitest + @testing-library (se UI) ou supertest (se API)
**Evite:** Testes que testam implementação interna; teste comportamento externo.
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { calculateDiscount } from './pricing.service';
describe('calculateDiscount', () => {
describe('Happy path', () => {
it('should apply percentage discount correctly', () => {
expect(calculateDiscount(100, { type: 'percentage', value: 10 })).toBe(90);
});
it('should apply fixed discount correctly', () => {
expect(calculateDiscount(100, { type: 'fixed', value: 15 })).toBe(85);
});
it('should handle decimal prices', () => {
expect(calculateDiscount(99.99, { type: 'percentage', value: 5 }))
.toBeCloseTo(94.99, 2);
});
});
describe('Edge cases', () => {
it('should return 0 when discount >= price (fixed)', () => {
expect(calculateDiscount(50, { type: 'fixed', value: 50 })).toBe(0);
expect(calculateDiscount(50, { type: 'fixed', value: 100 })).toBe(0);
});
it('should return 0 when 100% percentage discount', () => {
expect(calculateDiscount(200, { type: 'percentage', value: 100 })).toBe(0);
});
it('should not allow negative result', () => {
const result = calculateDiscount(10, { type: 'fixed', value: 999 });
expect(result).toBeGreaterThanOrEqual(0);
});
});
describe('Error cases', () => {
it('should throw for negative price', () => {
expect(() => calculateDiscount(-10, { type: 'fixed', value: 5 }))
.toThrow('Price must be positive');
});
it('should throw for negative discount value', () => {
expect(() => calculateDiscount(100, { type: 'percentage', value: -10 }))
.toThrow('Discount value must be positive');
});
it('should throw for percentage > 100', () => {
expect(() => calculateDiscount(100, { type: 'percentage', value: 101 }))
.toThrow('Percentage discount cannot exceed 100%');
});
it('should throw for unknown discount type', () => {
expect(() => calculateDiscount(100, { type: 'unknown' as any, value: 10 }))
.toThrow('Unknown discount type');
});
});
});
Debugging Otimizado com IA
O debugging com IA é mais eficiente quando você fornece contexto estruturado. A IA é particularmente boa em identificar problemas em stack traces, analisar padrões de erro em logs e sugerir hipóteses de causa raiz.
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '20'
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
quality:
name: Code Quality
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- name: TypeScript Check
run: npx tsc --noEmit
- name: Lint
run: npm run lint
- name: Format Check
run: npm run format:check
test:
name: Tests
runs-on: ubuntu-latest
needs: quality
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- name: Run Database Migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: postgresql://postgres:test@localhost:5432/testdb
- name: Run Tests with Coverage
run: npm run test:coverage
env:
DATABASE_URL: postgresql://postgres:test@localhost:5432/testdb
- name: Upload Coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
security:
name: Security Scan
runs-on: ubuntu-latest
needs: quality
steps:
- uses: actions/checkout@v4
- run: npm audit --audit-level=high
- name: SAST Scan
uses: github/codeql-action/analyze@v3
with:
languages: javascript-typescript
deploy:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [test, security]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Build and Push Docker Image
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
Para debugging de produção, colete logs estruturados em JSON e cole um conjunto de linhas relevantes pedindo à IA: "Analise estes logs e identifique padrões de erro, correlacione requestIds e indique o momento exato da falha." Logs estruturados são muito mais úteis que text logs.
MCPs e Docker
Servidores MCP para desenvolvimento e Docker MCP Catalog
O protocolo MCP (Model Context Protocol) permite que ferramentas de IA se conectem a servidores externos que fornecem capacidades adicionais — acesso a banco de dados, execução de código, leitura de sistemas de arquivos, APIs externas. Para desenvolvimento de software, os MCPs transformam a IA em um parceiro com acesso real ao ambiente.
Permite que a IA leia e escreva no banco de dados diretamente. Cursor pode executar queries, inspecionar schema e sugerir migrações com dados reais.
Acesso controlado ao sistema de arquivos com permissões granulares. A IA pode criar, ler e modificar arquivos fora do contexto do editor.
Acesso à API do GitHub para criar issues, PRs, ler comentários, acessar histórico de commits. A IA vira um colaborador com contexto de repositório completo.
Navegação web e screenshot. A IA pode verificar URLs, testar fluxos de usuário visualmente e extrair informações de páginas web.
Catálogo oficial de servidores MCP containerizados. Instale e configure MCPs como containers Docker sem dependências locais.
Grafo de conhecimento persistente. A IA armazena fatos sobre o projeto, decisões e contexto que persiste entre sessões de forma estruturada.
{
"mcpServers": {
"postgres": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"--network", "host",
"mcp/postgres",
"postgresql://localhost:5432/mydb"
]
},
"filesystem": {
"command": "npx",
"args": [
"-y", "@modelcontextprotocol/server-filesystem",
"/Users/dev/projects/my-app/src"
]
},
"github": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"mcp/github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
},
"memory": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-memory"]
}
}
}
O Docker MCP Catalog (hub.docker.com) oferece servidores MCP prontos para uso: mcp/postgres, mcp/github, mcp/brave-search, mcp/puppeteer. Use docker run mcp/[servidor] para executá-los sem instalação de dependências locais.
Refactoring e Segurança
Boas práticas de refactoring com IA e verificação de vulnerabilidades
Boas Práticas de Refactoring com IA
Refactoring assistido por IA é poderoso mas requer disciplina. A IA tende a fazer mais do que pedido — refactorings não solicitados introduzem riscos desnecessários. O princípio fundamental é: refactore em pequenos passos verificáveis.
Use IA para identificar code smells e priorize por impacto. Defina o escopo exato: "Apenas a função X" ou "Apenas o módulo Y".
Gere testes para o código atual ANTES de refatorar. Os testes documentam o comportamento existente e protegem contra regressões.
Faça uma mudança por vez. Rode os testes após cada mudança. Não refatore, renomeie e reorganize em um único passo.
Após cada refactoring, peça à IA: "Confirme que o comportamento externo desta função permanece idêntico ao original."
Verificação de Vulnerabilidades com IA
A IA pode realizar security reviews razoavelmente boas, especialmente para os padrões de vulnerabilidade mais comuns. Não substitui uma auditoria de segurança profissional, mas é uma primeira camada de defesa excelente no dia a dia.
Realize uma revisão de segurança do seguinte código com foco nas vulnerabilidades do OWASP Top 10.
**Código:**
```
[COLE O CÓDIGO]
```
**Contexto:**
- Stack: [Node.js/Python/etc.]
- Tipo: [API REST / Web App / CLI / etc.]
- Dados sensíveis processados: [descreva]
- Autenticação: [JWT / OAuth / Session / etc.]
**Checklist de verificação:**
1. **A01 - Broken Access Control**
- Verificação de autorização em cada endpoint
- Prevenção de escalação de privilégios
- Referências diretas a objetos (IDOR)
2. **A02 - Cryptographic Failures**
- Dados sensíveis em trânsito (HTTPS)
- Armazenamento seguro de senhas (bcrypt/argon2)
- Chaves/secrets hardcoded
3. **A03 - Injection**
- SQL injection (queries parametrizadas?)
- Command injection (exec, eval?)
- XSS (sanitização de output?)
4. **A05 - Security Misconfiguration**
- Headers de segurança (CORS, CSP, HSTS)
- Error messages que expõem detalhes internos
- Dependências desatualizadas
5. **A07 - Authentication Failures**
- Rate limiting em login
- Validação de tokens JWT
- Timeout de sessão
Para cada vulnerabilidade encontrada:
- Localização exata no código
- CVSS Score estimado
- Prova de conceito de exploração
- Remediação com código corrigido
A IA é eficaz em padrões conhecidos mas pode perder vulnerabilidades lógicas complexas, problemas de race condition e vulnerabilidades específicas do domínio. Para aplicações que processam dados financeiros, de saúde ou infraestrutura crítica, contrate uma auditoria de segurança profissional em complemento.
Use IA para auditar o codebase em busca de secrets hardcoded: API keys, passwords, tokens em código, configs e histórico git.
Peça à IA para analisar o output do npm audit ou pip-audit e priorizar correções por criticidade e facilidade de atualização.
Revise todos os pontos de entrada de dados externos. A IA pode identificar parâmetros não validados, tipos incorretos e schemas faltantes.
Para LGPD/GDPR, use IA para mapear onde dados pessoais são coletados, processados e armazenados, identificando pontos que precisam de consentimento.