melhorias em compoenentes de numero

This commit is contained in:
Luiz Silva 2026-04-30 12:19:36 -03:00
parent 5124844773
commit 303eda1b99
27 changed files with 3056 additions and 55 deletions

View file

@ -0,0 +1,185 @@
---
name: diagnosticar-erros-build
scope: global
description: >
Guia operacional para diagnosticar e resolver erros de build em cascata em monorepos TypeScript.
---
# Skill: Diagnosticar Erros de Build em Monorepo TypeScript
Use esta skill quando o build de um monorepo TypeScript falha — especialmente quando erros aparecem em pacotes que não foram diretamente modificados (erros em cascata).
---
## PASSO 1 — Capturar o Erro Completo
Executar o build com output completo e sem truncamento:
```bash
# pnpm (monorepo completo)
pnpm build 2>&1 | head -200
# Pacote específico
pnpm --filter <pacote> build 2>&1
# tsc direto (se disponível)
npx tsc --noEmit --pretty 2>&1 | head -100
```
Identificar:
- **Qual pacote falhou primeiro** (nem sempre é o que aparece no topo)
- **Código do erro** (`TS2304`, `TS2345`, `TS7006`, etc.)
- **Arquivo e linha** do erro original
---
## PASSO 2 — Classificar o Tipo de Erro
### Erros de dependência entre pacotes (cascata)
| Sintoma | Causa provável | Solução |
|---------|---------------|---------|
| `Cannot find module '@org/xxx'` | Pacote não foi buildado antes | Buildar na ordem correta ou usar `references` |
| `Module has no exported member 'X'` | Tipo renomeado/removido no pacote origem | Atualizar import no consumidor |
| Tipos `any` infiltrados | Pacote exporta sem `.d.ts` | Verificar `declaration: true` no tsconfig |
| `The inferred type cannot be named` | Dependência circular de tipos | Extrair tipo para pacote compartilhado |
### Erros de configuração
| Sintoma | Causa provável | Solução |
|---------|---------------|---------|
| `Cannot use import statement` | `module` errado no tsconfig | Alinhar `module`/`moduleResolution` |
| `Relative import paths need extensions` | Node16/NodeNext resolution | Adicionar `.js` nos imports ou mudar para `bundler` |
| `rootDir is expected to contain all source files` | Arquivo fora do `rootDir` | Ajustar `rootDir` ou mover arquivo |
| `Referenced project must have setting composite` | Project references sem `composite` | Adicionar `composite: true` no tsconfig referenciado |
### Erros de tipagem
| Sintoma | Causa provável | Solução |
|---------|---------------|---------|
| `TS2304: Cannot find name` | Tipo global não declarado | Criar `d.ts` ou importar explicitamente |
| `TS2345: Argument not assignable` | Tipos incompatíveis entre versões | Alinhar versão da dependência |
| `TS7006: Parameter implicitly has 'any'` | `noImplicitAny` ativado | Tipar o parâmetro explicitamente |
| `TS18046: is of type 'unknown'` | Narrowing ausente | Fazer type guard antes de usar |
---
## PASSO 3 — Identificar a Raiz do Problema
O erro que aparece **primeiro** nem sempre é a raiz. Seguir esta estratégia:
### 3.1. Verificar ordem de build
```bash
# Listar dependências internas para entender ordem correta
rg '"workspace:' --include='package.json' -l | sort
# Se usar turbo, verificar o pipeline
cat turbo.json | jq '.pipeline.build'
```
### 3.2. Rebuild isolado do pacote raiz
```bash
# Buildar APENAS o pacote mais baixo na hierarquia que apresenta erro
pnpm --filter <pacote-raiz> build
# Se esse buildar com sucesso, subir na hierarquia
pnpm --filter <pacote-consumidor> build
```
### 3.3. Verificar checagem de tipos isolada
```bash
# Verificar se a tipagem está correta sem produzir output
npx tsc --noEmit -p <caminho>/tsconfig.json
```
---
## PASSO 4 — Resolver Erros em Cascata
### Estratégia: de baixo para cima
1. Identificar o pacote **mais fundamental** (aquele que não depende de outros internos)
2. Resolver TODOS os erros nesse pacote
3. Rebuildar
4. Subir para o próximo pacote na cadeia de dependência
5. Repetir até o topo
### Armadilhas comuns
```typescript
// ❌ ERRADO: "resolver" com any (viola typescript-sem-any)
const dados = resultado as any
// ✅ CORRETO: tipar adequadamente
const dados: ResultadoEsperado = resultado
// ❌ ERRADO: ignorar erro com @ts-ignore
// @ts-ignore
import { funcao } from '@org/pacote'
// ✅ CORRETO: investigar por que o import falha
// O pacote '@org/pacote' foi buildado? O export existe?
```
---
## PASSO 5 — Verificar Alinhamento de Configuração
Quando erros persistem entre pacotes, verificar alinhamento de tsconfig:
```bash
# Comparar configurações críticas entre pacotes
for f in $(fd tsconfig.json --max-depth 2 --type f); do
echo "=== $f ==="
jq '{target, module, moduleResolution, strict, composite, declaration}' "$f" 2>/dev/null
done
```
Campos que **devem** ser consistentes entre pacotes do mesmo monorepo:
| Campo | Recomendação |
|-------|-------------|
| `target` | Mesmo alvo para todos (ex: `ES2022`) |
| `module` | Consistente (ex: `ESNext` ou `Node16`) |
| `moduleResolution` | Consistente (ex: `bundler` ou `node16`) |
| `strict` | `true` em todos |
| `declaration` | `true` em libs, opcional em apps |
| `composite` | `true` em libs referenciadas |
---
## PASSO 6 — Limpar e Rebuildar
Quando a investigação não revela causa óbvia:
```bash
# Limpar artefatos de build de todos os pacotes
fd -t d 'dist|build|.tsbuildinfo' --exclude node_modules | xargs rm -rf
# Limpar node_modules (último recurso)
fd -t d node_modules --max-depth 2 | xargs rm -rf
# Reinstalar e rebuildar do zero
pnpm install && pnpm build
```
---
## Checklist Final
- [ ] O pacote raiz do erro em cascata foi identificado?
- [ ] O erro original (não o efeito cascata) foi localizado?
- [ ] A solução não usa `any`, `as any` ou `@ts-ignore`?
- [ ] Todos os pacotes na cadeia foram rebuildados após a correção?
- [ ] As configurações de tsconfig estão alinhadas entre pacotes?
- [ ] O build completo passa sem erros?
## Referências
- Rules: `.agent/rules/typescript-sem-any.global.md`
- Workflow: `.agent/workflows/documentar-codigo.global.md`
- Skill: `.agent/skills/mapear-codigo-fonte/SKILL.md`

View file

@ -0,0 +1,160 @@
---
name: documentar-decisao-tecnica
scope: global
description: >
Guia operacional para registrar decisões técnicas e arquiteturais como ADRs (Architecture Decision Records).
---
# Skill: Documentar Decisão Técnica (ADR)
Use esta skill sempre que uma decisão técnica significativa for tomada — escolha de biblioteca, mudança de arquitetura, padrão de código, migração, ou qualquer decisão que afete múltiplos pacotes ou desenvolvedores.
O objetivo é garantir que **nenhuma decisão fique apenas na cabeça** ou perdida em conversas.
---
## Quando usar
- Nova dependência adicionada ao monorepo
- Mudança de padrão arquitetural (ex: de REST para GraphQL)
- Escolha de ferramenta ou lib entre alternativas
- Decisão de breaking change
- Migração de tecnologia
- Mudança de estratégia de deploy ou CI/CD
- Qualquer decisão que alguém pode questionar daqui 3 meses
---
## PASSO 1 — Criar o Diretório de ADRs (se não existir)
```bash
mkdir -p .docs/adrs
```
Convenção de diretório: `.docs/adrs/` na raiz do monorepo.
---
## PASSO 2 — Criar o Arquivo ADR
Nomenclatura: `NNN-titulo-em-kebab-case.md`
```bash
# Encontrar o próximo número
NEXT=$(ls .docs/adrs/*.md 2>/dev/null | wc -l | xargs -I{} expr {} + 1)
NEXT=$(printf "%03d" $NEXT)
echo "Próximo ADR: $NEXT"
```
---
## PASSO 3 — Preencher o Template
```markdown
# ADR-NNN: Título Descritivo da Decisão
**Data:** YYYY-MM-DD
**Status:** proposto | aceito | substituído por ADR-XXX | descontinuado
**Autores:** Nome(s)
## Contexto
Descreva a situação que levou à necessidade de uma decisão.
Inclua:
- O problema enfrentado
- Restrições técnicas ou de negócio
- O que motivou a discussão
## Decisão
Descreva a decisão tomada de forma clara e direta.
Use voz ativa: "Decidimos usar X para Y porque Z."
## Alternativas Consideradas
### Alternativa A: [Nome]
- **Prós:** ...
- **Contras:** ...
- **Motivo da rejeição:** ...
### Alternativa B: [Nome]
- **Prós:** ...
- **Contras:** ...
- **Motivo da rejeição:** ...
## Consequências
### Positivas
- O que melhora com essa decisão
### Negativas
- O que fica mais complexo ou limitado
- Débitos técnicos introduzidos
### Neutras
- Mudanças que não são boas nem ruins, mas afetam o workflow
## Impacto no Monorepo
Listar quais pacotes/módulos são afetados:
- `@org/pacote-a` — precisa migrar de X para Y
- `@org/pacote-b` — sem impacto
```
---
## PASSO 4 — Conectar com o Sistema de Conhecimento
Após criar o ADR, avaliar se a decisão deve gerar:
| A decisão... | Ação |
|-------------|------|
| Cria uma **restrição** permanente (ex: "nunca usar lib X") | Criar/atualizar uma **Rule** em `.agent/rules/` |
| Define um **processo** repetível (ex: "para migrar, faça X, Y, Z") | Criar/atualizar um **Workflow** em `.agent/workflows/` |
| Refina um **padrão operacional** (ex: "queries agora usam pool separado") | Atualizar a **Skill** correspondente em `.agent/skills/` |
| Não gera artefato adicional | Apenas o ADR é suficiente |
---
## PASSO 5 — Validar o ADR
Antes de considerar completo:
- **Teste do "daqui a 6 meses"**: alguém que não participou da conversa consegue entender a decisão?
- **Teste da reversibilidade**: está claro o que seria necessário para reverter essa decisão?
- **Teste do impacto**: todos os pacotes afetados estão listados?
---
## Exemplos de ADRs Reais
### Bom ✅
> **ADR-003: Usar Zod para validação de schemas em vez de Joi**
>
> **Contexto:** O projeto usava Joi para validação no backend, mas ao compartilhar schemas entre back e front em um monorepo, Joi se mostrou pesado para o bundle do frontend (280KB gzipped).
>
> **Decisão:** Migrar para Zod em todos os pacotes. Zod oferece inferência nativa de tipos TypeScript, é 10x menor, e elimina a necessidade de manter tipos e schemas separados.
### Ruim ❌
> **ADR-003: Usar Zod**
>
> Decidimos usar Zod porque é melhor.
---
## Checklist Final
- [ ] O contexto explica o "porquê" da decisão?
- [ ] As alternativas consideradas estão documentadas?
- [ ] As consequências (positivas e negativas) estão claras?
- [ ] Os pacotes impactados estão listados?
- [ ] O status está definido (proposto/aceito)?
- [ ] A decisão gerou rules/workflows/skills quando aplicável?
- [ ] Alguém de fora do contexto entenderia este ADR?
## Referências
- Workflow: `.agent/workflows/aprimorar-IA.global.md` (seção de classificação de artefatos)
- Workflow: `.agent/workflows/documentar-codigo.global.md`

View file

@ -0,0 +1,212 @@
---
name: documentar-regras-negocio.global
description: >
Guia operacional para criar, preencher e manter arquivos {modulo}.regras-negocio.md
co-localizados com módulos TypeScript de lógica de negócio complexa.
---
# Skill: Documentar Regras de Negócio em Módulos
Use esta skill sempre que um módulo TypeScript contiver lógica de decisão não-trivial
que precise ser rastreável por produto, suporte e desenvolvimento sem exigir leitura de código.
---
## Quando usar esta skill
- Módulo com 3+ critérios de decisão distintos
- Lógica de eleição/priorização entre registros
- Processamento que pode resultar em revisão manual
- Worker/CRON consumindo dados com estratégias diferenciadas por tipo
- Importador automático com regras de aceite/rejeição
---
## PASSO 1 — Identificar o escopo das regras
Antes de escrever o `.md`, percorrer o módulo e identificar:
| Categoria | O que procurar |
|---|---|
| **Critérios de entrada** | Filtros de query (excluido, vencimento, etc.) |
| **Critérios de bloqueio** | Condições que bloqueiam o fluxo automático |
| **Estratégia por tipo de dado** | Concatenação vs. primeiro-não-nulo vs. outros |
| **Eleição de principal** | Regras de prioridade entre registros |
| **Estado contraditório** | Combinações de campos mutuamente exclusivas |
| **Dependências externas** | Tabelas, filas, serviços tocados |
---
## PASSO 2 — Criar o arquivo
Nomenclatura: `{nome-do-modulo-sem-underline-inicial}.regras-negocio.md`
Localizar **na mesma pasta** do arquivo TypeScript:
```
modulo/
_meuModulo.ts
meu-modulo.regras-negocio.md ← co-localizado
```
Se o módulo for arquivo isolado (não pasta):
```
CRONS/
_cron_nome.ts
_cron_nome.regras-negocio.md ← mesmo diretório
```
---
## PASSO 3 — Preencher com o template
```markdown
# Regras de Negócio — [Nome Legível do Módulo]
Módulo: `_arquivo.ts`
Localização: `caminho/relativo/ao/workspace`
---
## Contexto
[Por que este módulo existe. Qual problema de negócio resolve.
Inclua o cenário que levou à sua criação — ex: "O sistema pode gerar duplicatas
por importações simultâneas..."]
---
## Critérios de Entrada
[O que aciona o módulo. Filtros aplicados na query de identificação.
Ex: `excluido = false`, mesmo `(codigo_origem, vencimento)`, etc.]
---
## Regras de Processamento
[Numeradas em ordem de avaliação. Cada regra deve incluir:
- Condição de ativação
- O que acontece quando ativada
- Se bloqueia ou direciona]
### Regra 1 — [Nome]
...
### Regra 2 — [Nome]
...
---
## Casos de Revisão Manual
[Quando o fluxo automático não pode prosseguir.
Liste as condições que enviam para revisão manual.
Se aplicável: como o caso é reportado (e-mail, log, fila de revisão).]
> **`null` é neutro** quando aplicável: descrever aqui se a lógica usa null como ausência neutra.
---
## Estratégia de Saída / Fusão de Campos
[Como os dados são combinados ou qual resultado é produzido.
Usar tabela para clareza:]
| Campo | Estratégia |
|---|---|
| `campo_textual` | Concatenação sem repetição |
| `campo_data` | Primeiro valor não-nulo vence |
| `campo_booleano` | Primeiro valor não-nulo vence |
---
## Dependências Externas
[Tabelas lidas/escritas, filas disparadas, serviços externos.
Incluir colunas de relacionamento quando relevante.]
- Tabelas de negócio: `tabela_a`, `tabela_b`
- Relacionamentos re-apontados: `tabela_c` via `(codigo_origem, tabela_origem)`
- Filas: nenhuma / `nome-da-fila`
- E-mails: nenhum / destinatários e gatilho
```
---
## PASSO 4 — Adicionar referência no módulo TypeScript
Na **primeira linha útil** do arquivo `.ts` (após shebang ou licença, se houver):
```typescript
// Regras de negócio: ver {modulo}.regras-negocio.md
import { ... } from "..."
```
---
## PASSO 5 — Limpar JSDoc duplicados
Percorrer os JSDoc do módulo e:
| Se encontrar | Ação |
|---|---|
| JSDoc listando as regras de negócio | Substituir por referência ao `.md` |
| JSDoc descrevendo critérios de bloqueio | Simplificar para "ver `.md`" |
| JSDoc com listas de condições | Manter apenas `@param` e `@returns` |
| Comentário inline explicando uma regra | Manter — comentários de linha são aceitáveis |
Exemplo de simplificação:
```typescript
// ❌ Antes — JSDoc duplicando as regras
/**
* Retorna false quando:
* - vencimentos divergentes
* - executada com datas distintas e não-nulas
* - vencimento_prorrogado distintos
* - estado contraditório: nao_executada=true + executada!=null
*/
// ✅ Depois — referência ao .md
/**
* Verifica se o grupo pode ser fundido e elege o registro principal.
* Critérios de bloqueio e regras de eleição: ver regras-negocio.md
*
* @param execs - Registros do grupo, ordenados do mais antigo para o mais recente
* @returns Código do eleito, ou `undefined` quando o grupo vai para revisão manual
*/
```
---
## PASSO 6 — Verificar consistência código ↔ `.md`
Percorrer cada regra listada no `.md` e verificar que há código correspondente:
- [ ] Cada critério de bloqueio tem um `if (...) return undefined / return retornoVazio`
- [ ] Cada estratégia de campo tem implementação em `fundirCampos` ou equivalente
- [ ] A ordem de avaliação no código bate com a ordem no `.md`
- [ ] Campos exclusivos de certas tabelas estão guardados pelo `if (tabela === ...)`
- [ ] queries têm `orderBy` quando a posição dos resultados tem significado (ver skill `consultar-banco-knex`)
---
## Checklist Final
- [ ] Arquivo `.md` criado co-localizado com o módulo
- [ ] Referência `// Regras de negócio: ver ...` na primeira linha do `.ts`
- [ ] JSDoc simplificados — sem duplicar conteúdo do `.md`
- [ ] Todas as regras do `.md` têm implementação correspondente no código
- [ ] Código e `.md` estão consistentes (separadores, campos, condições)
- [ ] `tsc --noEmit` passa sem erros após qualquer mudança de código
---
## Referências
- Rule: `.agent/rules/regras_negocio_md.global.md`
- Workflow: `.agent/workflows/documentar-regras-negocio.global.md`
- Skill: `.agent/skills/consultar-banco-knex/SKILL.md` (orderBy em whereIn)
- ADR: `.agent/memoria/adr-003-crons-complexos-compilacao-execucao.md`

View file

@ -0,0 +1,159 @@
---
name: mapear-codigo-fonte
scope: global
description: >
Guia operacional para mapear, navegar e compreender a estrutura de um monorepo TypeScript.
---
# Skill: Mapear Código-Fonte de Monorepo TypeScript
Use esta skill ao iniciar trabalho em um monorepo desconhecido, ao onboardar em novo projeto, ou quando precisar localizar rapidamente onde uma funcionalidade vive no código.
---
## PASSO 1 — Identificar a Raiz e o Gerenciador de Pacotes
Localize os arquivos que definem a estratégia de monorepo:
```bash
# Identificar o gerenciador e workspace config
ls -la package.json pnpm-workspace.yaml lerna.json turbo.json nx.json tsconfig.base.json 2>/dev/null
```
Elementos a extrair:
- **Gerenciador**: `pnpm` (workspaces em `pnpm-workspace.yaml`), `npm/yarn` (workspaces em `package.json`), ou `nx`/`turbo`
- **Pacotes compartilhados**: diretórios listados em `packages:` ou `workspaces:`
- **Apps/serviços**: diretórios de aplicações deployáveis
- **TSConfig base**: herança de configuração TypeScript entre pacotes
---
## PASSO 2 — Mapear a Árvore de Pacotes
```bash
# Listar todos os pacotes do workspace com nomes e caminhos
# pnpm
pnpm ls --depth -1 -r --json 2>/dev/null | jq '.[].name'
# Alternativa genérica: encontrar todos os package.json
fd package.json --max-depth 3 --type f --exec sh -c 'echo "$(dirname {}): $(jq -r .name {})"'
```
Organizar os pacotes em categorias:
| Categoria | Padrão de nome | Exemplo |
|-----------|---------------|---------|
| **Libs compartilhadas** | `@org/common`, `*-comuns`, `*-shared` | Tipos, utils, schemas |
| **Backend** | `*-back`, `*-api`, `*-server` | Serviços Node/Express/Fastify |
| **Frontend** | `*-front`, `*-web`, `*-app` | Apps Vue/React/Angular |
| **Ferramentas** | `*-cli`, `*-scripts`, `*-tools` | Scripts de build, migrations |
| **Configs** | `*-config`, `*-eslint-config` | Configs compartilhadas |
---
## PASSO 3 — Mapear Dependências Internas
Identificar o grafo de dependências entre pacotes internos:
```bash
# Para cada package.json, listar deps internas (que apontam para workspace:)
rg '"workspace:' --include='package.json' -l | while read f; do
echo "=== $(jq -r .name "$f") ==="
jq -r '.dependencies // {} | to_entries[] | select(.value | startswith("workspace:")) | .key' "$f"
jq -r '.devDependencies // {} | to_entries[] | select(.value | startswith("workspace:")) | .key' "$f"
done
```
Anotar:
- Quais pacotes são **folha** (não dependem de outros internos)
- Quais são **raiz** (ninguém depende deles — geralmente apps)
- Quais são **núcleo** (muitos dependem deles — geralmente libs compartilhadas)
---
## PASSO 4 — Mapear Arquitetura de Cada Pacote
Para cada pacote relevante, identificar a estrutura interna:
```bash
# Visão geral rápida (2 níveis de profundidade)
eza --tree --level=2 --icons --group-directories-first <caminho-do-pacote>/src/
# ou
tree -L 2 -I node_modules <caminho-do-pacote>/src/
```
Padrões comuns a procurar:
| Diretório | Responsabilidade típica |
|-----------|----------------------|
| `src/routes/` ou `src/api/` | Endpoints/rotas HTTP |
| `src/services/` | Lógica de negócio |
| `src/models/` ou `src/entities/` | Modelos de dados |
| `src/utils/` ou `src/helpers/` | Funções utilitárias |
| `src/types/` ou `src/typings/` | Definições de tipos TS |
| `src/schemas/` | Schemas de validação (Zod, Joi) |
| `src/migrations/` | Migrações de banco |
| `src/components/` | Componentes de UI (frontend) |
| `src/composables/` ou `src/hooks/` | Lógica reutilizável (Vue/React) |
| `src/stores/` | Gerenciamento de estado |
---
## PASSO 5 — Identificar Pontos de Entrada e Exportações
```bash
# Encontrar exports públicos de cada pacote
rg "export " --include='index.ts' --include='index.tsx' -l
# Encontrar entry points no package.json
fd package.json --max-depth 3 --type f --exec sh -c 'echo "$(jq -r .name {}):" && jq "{main, module, types, exports}" {}'
```
---
## PASSO 6 — Documentar o Mapa
Produzir um resumo estruturado com:
```markdown
# Mapa do Monorepo: <nome>
## Gerenciador: pnpm | npm | yarn
## Build System: tsc | turbo | nx
## Pacotes
### Libs Compartilhadas
- `@org/types` → tipos compartilhados (depende de: nenhum)
- `@org/utils` → funções utilitárias (depende de: @org/types)
### Aplicações
- `@org/api` → backend Express (depende de: @org/types, @org/utils)
- `@org/web` → frontend Vue (depende de: @org/types)
## Fluxo de dados
Descrever como os dados fluem entre pacotes.
## Scripts importantes
- `pnpm build` → Build de todos os pacotes
- `pnpm dev` → Inicia dev server
- `pnpm test` → Roda testes
```
---
## Checklist Final
- [ ] O gerenciador de pacotes e workspace strategy estão identificados?
- [ ] Todos os pacotes foram categorizados (lib/app/tool)?
- [ ] O grafo de dependências internas foi mapeado?
- [ ] Os pontos de entrada de cada pacote estão claros?
- [ ] A arquitetura interna dos pacotes principais foi documentada?
- [ ] Scripts de build/dev/test foram identificados?
## Referências
- Rules: `.agent/rules/typescript-sem-any.global.md`
- Workflow: `.agent/workflows/documentar-codigo.global.md`