ajustes na tabela de consulta
This commit is contained in:
parent
aea3da6585
commit
1446d6225b
78 changed files with 17921 additions and 17580 deletions
|
|
@ -5,13 +5,25 @@ BASE="https://paiol.idz.one/desenvolvimento/agent-ia"
|
|||
ERROS=0
|
||||
|
||||
baixar() {
|
||||
TMP=$(mktemp)
|
||||
echo "baixando $1"
|
||||
ERRO_CURL="$(curl -sSfL --create-dirs "$1" -o "$2" 2>&1)" || {
|
||||
ERRO_CURL="$(curl -sSfL --create-dirs "$1" -o "$TMP" 2>&1)" || {
|
||||
echo " ⚠ $1"
|
||||
echo " $ERRO_CURL"
|
||||
rm -f "$TMP"
|
||||
ERROS=$((ERROS + 1))
|
||||
return 1
|
||||
}
|
||||
# Rejeitar arquivos menores que 50 bytes (prováveis erros de proxy/WAF)
|
||||
TAMANHO=$(wc -c < "$TMP" | tr -d ' ')
|
||||
if [ "$TAMANHO" -lt 50 ]; then
|
||||
echo " ⚠ $1 — arquivo muito pequeno ($TAMANHO bytes), ignorado"
|
||||
rm -f "$TMP"
|
||||
ERROS=$((ERROS + 1))
|
||||
return 1
|
||||
fi
|
||||
mkdir -p "$(dirname "$2")"
|
||||
mv "$TMP" "$2"
|
||||
}
|
||||
|
||||
# ignorar se não auto atualizar
|
||||
|
|
@ -27,7 +39,14 @@ fi
|
|||
baixar "$BASE/rules/carta-principios-agente-azteca.global.md" "$DIR/rules/carta-principios-agente-azteca.global.md"
|
||||
baixar "$BASE/rules/escrita-natural.global.md" "$DIR/rules/escrita-natural.global.md"
|
||||
baixar "$BASE/rules/typescript-sem-any.global.md" "$DIR/rules/typescript-sem-any.global.md"
|
||||
baixar "$BASE/rules/regras_negocio_md.global.md" "$DIR/rules/regras_negocio_md.global.md"
|
||||
baixar "$BASE/rules/regras-negocio-md.global.md" "$DIR/rules/regras-negocio-md.global.md"
|
||||
baixar "$BASE/rules/zod-validacao-padrao.global.md" "$DIR/rules/zod-validacao-padrao.global.md"
|
||||
baixar "$BASE/rules/limite-linhas.global.md" "$DIR/rules/limite-linhas.global.md"
|
||||
baixar "$BASE/rules/estrutura-vue.global.md" "$DIR/rules/estrutura-vue.global.md"
|
||||
baixar "$BASE/rules/jsdoc-padrao.global.md" "$DIR/rules/jsdoc-padrao.global.md"
|
||||
baixar "$BASE/rules/autonomia-agente.global.md" "$DIR/rules/autonomia-agente.global.md"
|
||||
baixar "$BASE/rules/fronteiras-monorepo.global.md" "$DIR/rules/fronteiras-monorepo.global.md"
|
||||
baixar "$BASE/rules/mensagens-usuario.global.md" "$DIR/rules/mensagens-usuario.global.md"
|
||||
|
||||
# workflows
|
||||
baixar "$BASE/workflows/aprimorar-IA.global.md" "$DIR/workflows/aprimorar-IA.global.md"
|
||||
|
|
@ -48,8 +67,11 @@ baixar "$BASE/skills/mapear-codigo-fonte.global/SKILL.md" "$DIR/sk
|
|||
baixar "$BASE/skills/diagnosticar-erros-build.global/SKILL.md" "$DIR/skills/diagnosticar-erros-build.global/SKILL.md"
|
||||
baixar "$BASE/skills/documentar-decisao-tecnica.global/SKILL.md" "$DIR/skills/documentar-decisao-tecnica.global/SKILL.md"
|
||||
baixar "$BASE/skills/documentar-regras-negocio.global/SKILL.md" "$DIR/skills/documentar-regras-negocio.global/SKILL.md"
|
||||
baixar "$BASE/skills/criar-schema-zod.global/SKILL.md" "$DIR/skills/criar-schema-zod.global/SKILL.md"
|
||||
baixar "$BASE/skills/documentar-dominio-modulo.global/SKILL.md" "$DIR/skills/documentar-dominio-modulo.global/SKILL.md"
|
||||
|
||||
# raiz (.agent)
|
||||
baixar "$BASE/tools.md" "$DIR/tools.md"
|
||||
baixar "$BASE/verificar-linhas.sh" "$DIR/verificar-linhas.sh"
|
||||
|
||||
exit "$ERROS"
|
||||
60
.agent/rules/autonomia-agente.global.md
Normal file
60
.agent/rules/autonomia-agente.global.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
type: rule
|
||||
name: autonomia-agente
|
||||
description: Define limites de autonomia do agente — o que pode fazer sozinho, o que requer confirmação e o que é proibido
|
||||
scope: global
|
||||
trigger: always_on
|
||||
priority: alta
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Regra: Limites de Autonomia do Agente
|
||||
|
||||
## Contexto
|
||||
|
||||
O agente existe para **ampliar a capacidade humana**, não para substituir decisões. Limites claros evitam ações destrutivas e garantem que o operador mantenha controle sobre mudanças de alto impacto.
|
||||
|
||||
## Ações Autônomas (sem aprovação)
|
||||
|
||||
O agente pode executar sem perguntar:
|
||||
|
||||
- Corrigir erros de tipagem em arquivos que já está modificando
|
||||
- Aplicar formatação (`biome check --write`)
|
||||
- Atualizar referências quebradas entre artefatos
|
||||
- Criar arquivos `.regras-negocio.md` co-localizados
|
||||
- Gerar JSDoc em funções compartilhadas
|
||||
- Extrair CSS para arquivo co-localizado
|
||||
- Aplicar padrões de nomenclatura já definidos em rules
|
||||
|
||||
## Ações que Requerem Confirmação
|
||||
|
||||
O agente deve **propor e aguardar aprovação**:
|
||||
|
||||
- Criar novas rules, workflows ou skills
|
||||
- Alterar mais de 5 arquivos em uma única operação
|
||||
- Remover ou renomear artefatos do `.agent/`
|
||||
- Mudar contratos de API (parâmetros, retornos, rotas)
|
||||
- Alterar schemas Zod compartilhados no pacote `*-comuns`
|
||||
- Propor novas dependências ao `package.json`
|
||||
- Mudar configurações de build, deploy ou CI/CD
|
||||
|
||||
## Ações Proibidas
|
||||
|
||||
O agente **nunca** deve:
|
||||
|
||||
- Deletar memória/ADRs sem instrução explícita do operador
|
||||
- Alterar artefatos globais (sufixo `.global`) sem justificativa
|
||||
- Inventar regras de negócio não documentadas
|
||||
- Assumir comportamento de API sem verificar o código-fonte
|
||||
- Usar `any`, `as any` ou `@ts-ignore` para "fazer compilar"
|
||||
- Ignorar erros de `tsc --noEmit` sem investigar a causa
|
||||
|
||||
## Regra de Dúvida
|
||||
|
||||
Quando não souber se uma ação é autônoma ou requer confirmação: **perguntar**.
|
||||
|
||||
O custo de uma pergunta é zero. O custo de uma ação destrutiva é alto.
|
||||
|
||||
## Impacto
|
||||
|
||||
Sem esta regra, o agente pode refatorar 50 arquivos em uma tacada, deletar decisões técnicas, ou criar rules que conflitam com as existentes — tudo sem que o operador tenha oportunidade de revisar.
|
||||
|
|
@ -3,9 +3,10 @@ trigger: always_on
|
|||
type: rule
|
||||
name: carta-principios-agente-azteca
|
||||
description: Princípios morais e operacionais que orientam o comportamento de agentes de IA no ecossistema Azteca
|
||||
version: 1.0
|
||||
version: "1.0"
|
||||
scope: global
|
||||
priority: alta
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Carta de Princípios do Agente de IA da Azteca
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
---
|
||||
trigger: always_on
|
||||
description: Garantir escrita natural, fluida e humana em textos técnicos e comerciais, evitando linguagem robótica ou excessivamente genérica.
|
||||
type: rule
|
||||
name: escrita-natural
|
||||
trigger: context_match
|
||||
description: Garantir escrita natural, fluida e humana em textos comerciais e de comunicação, evitando linguagem robótica ou excessivamente genérica.
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
ativacao: >
|
||||
Aplicar quando o agente estiver produzindo textos comerciais, de marketing,
|
||||
orçamentos, propostas, reels ou qualquer comunicação voltada ao público externo.
|
||||
NÃO aplicar em documentação técnica (ADRs, rules, JSDoc, regras de negócio).
|
||||
---
|
||||
|
||||
# Regra: Escrita Estratégica e Natural
|
||||
|
|
|
|||
86
.agent/rules/estrutura-vue.global.md
Normal file
86
.agent/rules/estrutura-vue.global.md
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
---
|
||||
type: rule
|
||||
name: estrutura-vue
|
||||
description: Padrões obrigatórios de estrutura para componentes Vue 3 (defineComponent, setup, CSS, dispatch)
|
||||
scope: global
|
||||
trigger: file_match
|
||||
globs:
|
||||
- "**/*.vue"
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Regra: Estrutura de Componentes Vue
|
||||
|
||||
## 1. `defineComponent` obrigatório
|
||||
|
||||
Todo componente Vue deve usar `defineComponent`:
|
||||
|
||||
```vue
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'MeuComponente',
|
||||
setup() {
|
||||
// lógica aqui
|
||||
}
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
## 2. `setup()` não pode ser externo
|
||||
|
||||
O `setup()` deve estar sempre dentro do `.vue`. Nunca delegar para arquivo externo.
|
||||
|
||||
```ts
|
||||
// ❌ Proibido — setup esvaziado
|
||||
export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
return useEliTabela(props, emit) // proxy vazio
|
||||
}
|
||||
})
|
||||
|
||||
// ✅ Correto — setup com lógica própria
|
||||
export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
const estado = ref(null)
|
||||
const carregar = async () => { ... }
|
||||
return { estado, carregar }
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
> Composables `use*.ts` podem encapsular lógica reutilizável pontual, mas nunca substituir o `setup()`. Se ultrapassar 250 linhas → extrair subcomponentes, CSS ou Dispatch Table.
|
||||
|
||||
## 3. CSS co-localizado
|
||||
|
||||
Separação de estilos em arquivo externo quando o CSS contribui para o total de linhas:
|
||||
|
||||
```
|
||||
MeuComponente.vue
|
||||
MeuComponente.css
|
||||
```
|
||||
|
||||
Importar via `import './MeuComponente.css'` ou `<style src="./MeuComponente.css" />`.
|
||||
|
||||
## 4. Dispatch Table
|
||||
|
||||
Uso de mapa de funções para eliminar `if/else` ou `switch` longos:
|
||||
|
||||
```ts
|
||||
// handlers.ts
|
||||
export const acaoHandlers: Record<string, () => void> = {
|
||||
salvar: () => { ... },
|
||||
cancelar: () => { ... },
|
||||
excluir: () => { ... },
|
||||
}
|
||||
```
|
||||
|
||||
## Impacto
|
||||
|
||||
Sem estes padrões, componentes perdem inferência de tipos, lógica fica inauditável em composables externos, e CSS cresce inline sem controle.
|
||||
|
||||
## Referências
|
||||
|
||||
- Rule: `.agent/rules/limite-linhas.global.md`
|
||||
- Rule: `.agent/rules/typescript-sem-any.global.md`
|
||||
120
.agent/rules/fronteiras-monorepo.global.md
Normal file
120
.agent/rules/fronteiras-monorepo.global.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
---
|
||||
type: rule
|
||||
name: fronteiras-monorepo
|
||||
description: Define a convenção de pacotes e regras de importação entre módulos do monorepo
|
||||
scope: global
|
||||
trigger: always_on
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Regra: Fronteiras de Pacote no Monorepo
|
||||
|
||||
## Contexto
|
||||
|
||||
Cada módulo SaaS do ecossistema é organizado em até 4 pacotes dentro de um monorepo. O agente **deve** respeitar as fronteiras de importação entre pacotes para evitar acoplamento indevido.
|
||||
|
||||
## Convenção de Pacotes
|
||||
|
||||
Cada módulo segue a estrutura:
|
||||
|
||||
```
|
||||
<modulo>-back ← Servidor: rotas, serviços, filas, CRON
|
||||
<modulo>-front ← Interface: páginas Vue, componentes, composables
|
||||
<modulo>-comuns ← Compartilhado: tipos, schemas Zod, enums, utils puros
|
||||
<modulo>-migracao ← Banco de dados: migrations, seeds, scripts de carga
|
||||
```
|
||||
|
||||
Nem todo módulo terá os 4 pacotes. O mínimo funcional é `back` + `front` + `comuns`.
|
||||
|
||||
## Regras de Importação
|
||||
|
||||
### Permitido ✅
|
||||
|
||||
```
|
||||
<modulo>-front → pode importar de → <modulo>-comuns
|
||||
<modulo>-back → pode importar de → <modulo>-comuns
|
||||
<modulo>-migracao → pode importar de → <modulo>-comuns
|
||||
```
|
||||
|
||||
### Proibido ❌
|
||||
|
||||
```
|
||||
<modulo>-front ✗ nunca importar de → <modulo>-back
|
||||
<modulo>-back ✗ nunca importar de → <modulo>-front
|
||||
<modulo>-migracao ✗ nunca importar de → <modulo>-front
|
||||
<modulo>-front ✗ nunca importar de → <outro-modulo>-back
|
||||
<outro-modulo> ✗ nunca importar de → <modulo>-back (direto)
|
||||
```
|
||||
|
||||
### Comunicação entre módulos
|
||||
|
||||
Módulos diferentes **nunca** importam código um do outro diretamente. Comunicação entre módulos deve ocorrer via:
|
||||
|
||||
- **API HTTP** (chamada de serviço entre backs)
|
||||
- **Fila** (BullMQ, Redis) para processamento assíncrono
|
||||
- **Banco compartilhado** com schemas/tabelas separados por módulo
|
||||
- **Pacote `*-comuns` compartilhado** apenas para tipos e schemas de contrato
|
||||
|
||||
## O que vive em cada pacote
|
||||
|
||||
### `<modulo>-comuns`
|
||||
|
||||
O pacote comuns é a **única fonte de verdade** para tipos e schemas compartilhados:
|
||||
|
||||
```
|
||||
<modulo>-comuns/src/
|
||||
├── tabelas/ ← schemas Zod por entidade (zEntidadeCriar, etc.)
|
||||
├── enums/ ← enums de domínio do módulo
|
||||
├── tipos/ ← tipos derivados dos schemas
|
||||
└── utils/ ← funções puras sem side-effect
|
||||
```
|
||||
|
||||
**Proibido** no comuns:
|
||||
- Componentes Vue ou React
|
||||
- Código com `import` de Node.js (`fs`, `path`, `http`)
|
||||
- Código com `import` de bibliotecas de frontend (`vue`, `vuetify`)
|
||||
- Lógica de negócio que depende de banco ou serviço externo
|
||||
|
||||
### `<modulo>-back`
|
||||
|
||||
```
|
||||
<modulo>-back/src/
|
||||
├── rotas/ ← endpoints Express/Fastify
|
||||
├── servicos/ ← lógica de negócio
|
||||
├── banco/ ← queries (Knex, Prisma, etc.)
|
||||
├── filas/ ← processadores de fila
|
||||
├── cron/ ← tarefas agendadas
|
||||
└── utils/ ← helpers exclusivos do back
|
||||
```
|
||||
|
||||
### `<modulo>-front`
|
||||
|
||||
```
|
||||
<modulo>-front/src/
|
||||
├── paginas/ ← páginas/views por rota
|
||||
├── componentes/ ← componentes reutilizáveis do módulo
|
||||
├── composables/ ← lógica reutilizável (use*.ts)
|
||||
└── utils/ ← helpers exclusivos do front
|
||||
```
|
||||
|
||||
### `<modulo>-migracao`
|
||||
|
||||
```
|
||||
<modulo>-migracao/src/
|
||||
├── migrations/ ← criação/alteração de tabelas
|
||||
├── seeds/ ← dados iniciais
|
||||
└── scripts/ ← scripts de carga/transformação
|
||||
```
|
||||
|
||||
## Impacto
|
||||
|
||||
Sem esta regra:
|
||||
- Front importa serviço de back (quebra em build de produção)
|
||||
- Módulo A acessa tabelas do Módulo B diretamente (acoplamento oculto)
|
||||
- Schemas ficam duplicados entre back e front
|
||||
- Mudança em um módulo quebra outro sem aviso
|
||||
|
||||
## Referências
|
||||
|
||||
- Rule: `.agent/rules/zod-validacao-padrao.global.md` (schemas no `*-comuns`)
|
||||
- Skill: `.agent/skills/mapear-codigo-fonte.global/SKILL.md`
|
||||
59
.agent/rules/jsdoc-padrao.global.md
Normal file
59
.agent/rules/jsdoc-padrao.global.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
type: rule
|
||||
name: jsdoc-padrao
|
||||
description: Padrões de documentação em código (JSDoc, casts temporários e TODOs estruturados)
|
||||
scope: global
|
||||
trigger: file_match
|
||||
globs:
|
||||
- "**/*.ts"
|
||||
- "**/*.tsx"
|
||||
- "**/*.vue"
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Regra: Documentação em Código
|
||||
|
||||
## 1. JSDoc — Princípios
|
||||
|
||||
- **Por que, não o Quê**: documente o raciocínio, não o mecanismo que o TypeScript já expressa.
|
||||
- **Nomenclatura limpa**: confie em nomes expressivos antes de comentários.
|
||||
|
||||
## 2. JSDoc obrigatório em funções compartilhadas
|
||||
|
||||
Toda função central ou de uso compartilhado deve ter cabeçalho JSDoc:
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Busca detalhes da entidade e calcula privilégios aplicáveis.
|
||||
* Não utilizar em processamento em lote para evitar sobrecarga.
|
||||
*
|
||||
* @param tenantId - Identificador do tenant no sistema
|
||||
* @param entityId - ID do registro na base de dados
|
||||
* @returns Objeto consolidado ou `null` se não encontrado
|
||||
*/
|
||||
export const obterDetalhes = async (tenantId: string, entityId: string) => { ... }
|
||||
```
|
||||
|
||||
## 3. Casts temporários — justificativa obrigatória
|
||||
|
||||
Coerções agressivas requerem comentário explicando o porquê:
|
||||
|
||||
```typescript
|
||||
// Necessário: biblioteca externa não provê tipagem genérica na versão atual
|
||||
const dados = payload.raw as unknown as RespostaFormatada
|
||||
```
|
||||
|
||||
## 4. TODOs estruturados
|
||||
|
||||
Dívida técnica ou dúvida de negócio deve seguir formato padronizado:
|
||||
|
||||
- **Tipagem**: `// TODO de tipagem: Criar interface para o retorno da API`
|
||||
- **Negócio**: `// TODO de regra: Validar com Produto se taxa se aplica a clientes antigos`
|
||||
|
||||
## Impacto
|
||||
|
||||
Sem este padrão, funções compartilhadas ficam sem documentação, casts aparecem sem justificativa, e TODOs são inconsistentes e difíceis de buscar.
|
||||
|
||||
## Referências
|
||||
|
||||
- Rule: `.agent/rules/typescript-sem-any.global.md`
|
||||
66
.agent/rules/limite-linhas.global.md
Normal file
66
.agent/rules/limite-linhas.global.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
type: rule
|
||||
name: limite-linhas
|
||||
description: Nenhum arquivo de código pode ultrapassar 250 linhas
|
||||
scope: global
|
||||
trigger: file_match
|
||||
globs:
|
||||
- "**/*.ts"
|
||||
- "**/*.tsx"
|
||||
- "**/*.vue"
|
||||
- "**/*.css"
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Regra: Limite de 250 Linhas por Arquivo
|
||||
|
||||
## Regra
|
||||
|
||||
Nenhum arquivo `*.vue`, `*.ts`, `*.tsx` ou `*.css` pode ultrapassar **250 linhas**.
|
||||
|
||||
> Validação automática: `.agent/verificar-linhas.sh`
|
||||
|
||||
## Estratégias de Decomposição
|
||||
|
||||
| Situação | Ação |
|
||||
|---|---|
|
||||
| Template longo | Extrair seções como subcomponentes |
|
||||
| CSS extenso | Mover para `<nome>.css` co-localizado |
|
||||
| `setup()` extenso | Extrair subcomponentes, CSS ou Dispatch Table |
|
||||
| Modal/Dialog embutido | Sempre em componente separado (`*Modal.vue`) |
|
||||
| Handlers e dispatch | Extrair para `handlers.ts` ou `dispatch.ts` |
|
||||
|
||||
## Divisão em Pasta
|
||||
|
||||
Quando um componente precisa de múltiplos sub-arquivos, converter em **pasta homônima** com `index.vue`:
|
||||
|
||||
```
|
||||
# Antes
|
||||
ComponenteGrande.vue ← monolítico (+250 linhas)
|
||||
|
||||
# Depois
|
||||
ComponenteGrande/
|
||||
├── index.vue ← orquestração (≤250 linhas)
|
||||
├── SecaoPrincipal.vue ← bloco de template extraído
|
||||
├── SecaoSecundaria.vue ← outro bloco extraído
|
||||
├── componenteGrande.mapeadores.ts ← lógica de eventos
|
||||
└── ComponenteGrande.css ← estilos co-localizados
|
||||
```
|
||||
|
||||
| Arquivo | Responsabilidade |
|
||||
|---|---|
|
||||
| `index.vue` | Orquestração: importa e compõe. Sem lógica densa. |
|
||||
| `Secao*.vue` | Template isolado. Props + eventos. |
|
||||
| `*.mapeadores.ts` | Funções de ação desacopladas. |
|
||||
| `*.css` | Estilos co-localizados. |
|
||||
|
||||
> Importações externas não mudam: `ComponenteGrande/` resolve para `index.vue`.
|
||||
|
||||
## Impacto
|
||||
|
||||
Sem esta regra, arquivos crescem silenciosamente até se tornarem intocáveis — ninguém quer revisar ou refatorar um componente de 800 linhas.
|
||||
|
||||
## Referências
|
||||
|
||||
- Script: `.agent/verificar-linhas.sh`
|
||||
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||
123
.agent/rules/mensagens-usuario.global.md
Normal file
123
.agent/rules/mensagens-usuario.global.md
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
---
|
||||
type: rule
|
||||
name: mensagens-usuario
|
||||
description: Toda mensagem visível ao usuário final deve ser escrita em linguagem do domínio, sem termos técnicos de TI
|
||||
scope: global
|
||||
trigger: file_match
|
||||
globs:
|
||||
- "**/*.vue"
|
||||
- "**/*.ts"
|
||||
- "**/*.tsx"
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Regra: Mensagens Orientadas ao Domínio
|
||||
|
||||
## Contexto
|
||||
|
||||
O usuário final dos módulos SaaS é profissional de **engenharia, ciência ou gestão ambiental**. Ele entende de legislação, processos técnicos e ciência aplicada — mas **não tem obrigação de entender tecnologia**.
|
||||
|
||||
Toda mensagem visível na interface — erro, validação, confirmação, tooltip, empty state, ajuda — deve ser escrita na linguagem do domínio do módulo.
|
||||
|
||||
## Regra
|
||||
|
||||
### 1. Erros de validação devem indicar O QUE preencher, não O QUE falhou
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — linguagem técnica
|
||||
"Campo obrigatório"
|
||||
"Erro de validação"
|
||||
"Formato inválido"
|
||||
"Payload inválido"
|
||||
|
||||
// ✅ CORRETO — linguagem do domínio
|
||||
"Informe a Área do Empreendimento (em hectares)"
|
||||
"Selecione o Tipo de Licença: LP, LI ou LO"
|
||||
"A Data da Vistoria deve ser anterior à data atual"
|
||||
"Informe o CNPJ no formato 00.000.000/0000-00"
|
||||
```
|
||||
|
||||
### 2. Erros de sistema devem ser traduzidos para o usuário
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — erro técnico exposto
|
||||
"Erro 500: Internal Server Error"
|
||||
"Timeout na requisição"
|
||||
"Network Error"
|
||||
"ECONNREFUSED"
|
||||
|
||||
// ✅ CORRETO — mensagem humanizada
|
||||
"Não foi possível salvar. Tente novamente em instantes."
|
||||
"A operação demorou mais que o esperado. Tente novamente."
|
||||
"Sem conexão com o servidor. Verifique sua internet."
|
||||
```
|
||||
|
||||
### 3. Estados vazios devem explicar o contexto
|
||||
|
||||
Quando uma lista ou tabela está vazia, a mensagem deve orientar o usuário:
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — genérico
|
||||
"Nenhum registro encontrado"
|
||||
"Lista vazia"
|
||||
|
||||
// ✅ CORRETO — explica o domínio e orienta
|
||||
"Nenhuma condicionante cadastrada para esta licença."
|
||||
"Nenhum relatório de monitoramento registrado neste período."
|
||||
"Nenhum empreendimento encontrado com os filtros aplicados. Tente ampliar a busca."
|
||||
```
|
||||
|
||||
### 4. Confirmações devem descrever a consequência
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — genérico
|
||||
"Tem certeza que deseja excluir?"
|
||||
"Confirmar operação?"
|
||||
|
||||
// ✅ CORRETO — descreve o impacto
|
||||
"Excluir esta condicionante? O prazo de cumprimento e os documentos vinculados serão removidos."
|
||||
"Arquivar esta licença? Ela não aparecerá mais nas listagens ativas."
|
||||
```
|
||||
|
||||
### 5. Labels e placeholders devem usar vocabulário do domínio
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — genérico
|
||||
label: "Nome"
|
||||
placeholder: "Digite aqui"
|
||||
|
||||
// ✅ CORRETO — específico do domínio
|
||||
label: "Razão Social do Empreendedor"
|
||||
placeholder: "Ex: Mineração Vale Verde Ltda."
|
||||
|
||||
label: "Área Total do Empreendimento"
|
||||
placeholder: "Em hectares (ex: 150,5)"
|
||||
```
|
||||
|
||||
### 6. Schemas Zod devem ter mensagens de domínio
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — mensagens padrão do Zod
|
||||
const zEmpreendimento = z.object({
|
||||
nome: z.string().min(1), // "String must contain at least 1 character(s)"
|
||||
area: z.number().positive(), // "Number must be greater than 0"
|
||||
})
|
||||
|
||||
// ✅ CORRETO — mensagens customizadas
|
||||
const zEmpreendimento = z.object({
|
||||
nome: z.string().min(1, "Informe o nome do empreendimento"),
|
||||
area: z.number({ invalid_type_error: "A área deve ser um número" })
|
||||
.positive("A área deve ser maior que zero"),
|
||||
cnpj: z.string().regex(/^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/,
|
||||
"CNPJ inválido. Use o formato 00.000.000/0000-00"),
|
||||
})
|
||||
```
|
||||
|
||||
## Impacto
|
||||
|
||||
Sem esta regra, o agente gera mensagens técnicas que confundem gestores ambientais, consultores e técnicos de campo — forçando a equipe de suporte a traduzir erros de sistema para o vocabulário do cliente.
|
||||
|
||||
## Referências
|
||||
|
||||
- Rule: `.agent/rules/zod-validacao-padrao.global.md` (schemas com mensagens customizadas)
|
||||
- Workflow: `.agent/workflows/ux.global.md` (design de interface)
|
||||
120
.agent/rules/regras-negocio-md.global.md
Normal file
120
.agent/rules/regras-negocio-md.global.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
---
|
||||
type: rule
|
||||
name: regras-negocio-md
|
||||
description: Arquivo {modulo}.regras-negocio.md obrigatório para módulos com lógica complexa
|
||||
scope: global
|
||||
trigger: always_on
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Regra: Arquivo `{modulo}.regras-negocio.md` Obrigatório para Módulos com Lógica Complexa
|
||||
|
||||
> **Escopo global** — aplica-se a todos os projetos do ecossistema Azteca.
|
||||
|
||||
## Contexto
|
||||
|
||||
Qualquer arquivo TypeScript que contenha lógica de negócio não-trivial — múltiplas regras de decisão, critérios de bloqueio, estratégias de processamento — deve ter suas regras documentadas em linguagem natural em um arquivo Markdown co-localizado.
|
||||
|
||||
Isso garante que produto, suporte e desenvolvimento possam entender as regras sem precisar ler TypeScript, e que o agente de IA encontre rapidamente os critérios corretos antes de alterar qualquer código.
|
||||
|
||||
## Regra
|
||||
|
||||
**Todo módulo com lógica de negócio não-trivial DEVE ter um arquivo `{modulo}.regras-negocio.md` co-localizado.**
|
||||
|
||||
Considera-se lógica não-trivial qualquer módulo que:
|
||||
- possui 3 ou mais critérios de decisão distintos
|
||||
- realiza eleição/priorização entre registros
|
||||
- aplica diferentes estratégias por tipo de dado
|
||||
- pode resultar em revisão manual (caminho alternativo ao fluxo automático)
|
||||
- é consumido por CRON, worker ou importador automático
|
||||
|
||||
O módulo TypeScript deve conter, na primeira linha do arquivo, a referência:
|
||||
|
||||
```typescript
|
||||
// Regras de negócio: ver {modulo}.regras-negocio.md
|
||||
```
|
||||
|
||||
O arquivo `.md` é a **fonte de verdade**. Os JSDoc do código devem referenciar o `.md`, não duplicá-lo.
|
||||
|
||||
## Estrutura Obrigatória do Arquivo
|
||||
|
||||
```markdown
|
||||
# Regras de Negócio — [Nome do Módulo]
|
||||
|
||||
Módulo: `_arquivo.ts`
|
||||
Localização: `caminho/relativo/ao/arquivo`
|
||||
|
||||
---
|
||||
|
||||
## Contexto
|
||||
Por que este módulo existe, qual problema resolve.
|
||||
|
||||
## Critérios de Entrada / Identificação
|
||||
O que aciona o módulo, quais dados recebe, filtros aplicados.
|
||||
|
||||
## Regras de Processamento
|
||||
As regras numeradas em ordem de avaliação.
|
||||
|
||||
## Casos de Revisão Manual (quando aplicável)
|
||||
Quando o processamento automático não pode prosseguir.
|
||||
|
||||
## Estratégia de Fusão / Resultado (quando aplicável)
|
||||
O que o módulo produz, como campos são combinados.
|
||||
|
||||
## Dependências Externas
|
||||
Tabelas, filas, serviços externos tocados pelo módulo.
|
||||
```
|
||||
|
||||
## Exemplos
|
||||
|
||||
✅ **Correto** — referência no topo do módulo, regras no `.md`:
|
||||
```typescript
|
||||
// Regras de negócio: ver juntar_execucoes.regras-negocio.md
|
||||
|
||||
import { ... } from "..."
|
||||
|
||||
export const compilarJuntarExecucoes = async (...) => {
|
||||
// implementação conforme regras-negocio.md
|
||||
}
|
||||
```
|
||||
|
||||
❌ **Errado** — regras embutidas no código como comentário de bloco:
|
||||
```typescript
|
||||
/**
|
||||
* Regras de negócio:
|
||||
* [x] Pode ter apenas uma execução por data de vencimento.
|
||||
* [x] Se tiver apenas uma execução consolidada → ela é a principal.
|
||||
* ...
|
||||
*/
|
||||
```
|
||||
|
||||
❌ **Errado** — JSDoc duplicando as regras em vez de referenciar o `.md`:
|
||||
```typescript
|
||||
/**
|
||||
* Retorna false quando:
|
||||
* - vencimentos divergentes
|
||||
* - executada com datas distintas
|
||||
* - vencimento_prorrogado distintos
|
||||
* ...
|
||||
*/
|
||||
```
|
||||
|
||||
## Impacto
|
||||
|
||||
Sem este padrão:
|
||||
- Regras de negócio ficam implícitas no código ou em JSDoc que envelhece sem controle
|
||||
- O agente de IA precisa inferir regras do código ao invés de lê-las diretamente
|
||||
- Produto e suporte não conseguem validar o comportamento sem ajuda técnica
|
||||
- Mudanças de regra geram JSDoc desatualizado espalhado pelo código
|
||||
|
||||
## Aplicação
|
||||
|
||||
- Módulos de CRON com lógica de auditoria/fusão
|
||||
- Importadores automáticos (ex: importação de licenças via IA)
|
||||
- Workers de processamento em lote
|
||||
- Qualquer utilitário com lógica de decisão multi-critério
|
||||
|
||||
## Referências
|
||||
|
||||
- Skill: `.agent/skills/documentar-regras-negocio.global/SKILL.md`
|
||||
- Workflow: `.agent/workflows/documentar-regras-negocio.global.md`
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
---
|
||||
type: rule
|
||||
name: typescript-sem-any
|
||||
trigger: always_on
|
||||
description: Proíbe uso de any, casts inseguros e padroniza uso de enums em código TypeScript
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
globs:
|
||||
- "**/*.ts"
|
||||
- "**/*.tsx"
|
||||
|
|
@ -68,6 +72,6 @@ Se encontrar uma string que represente um valor de domínio do sistema, o agente
|
|||
|
||||
## Referências
|
||||
|
||||
- Skill: `.agent/skills/diagnosticar-erros-build/SKILL.md` (quando erros de tipagem causam falhas de build em cascata)
|
||||
- Workflow: `.agent/workflows/documentar-codigo.global.md` (padrão de documentação para casts temporários)
|
||||
- Skill: `.agent/skills/diagnosticar-erros-build.global/SKILL.md` (quando erros de tipagem causam falhas de build em cascata)
|
||||
- Workflow: `.agent/workflows/otimizar-codigos.global.md` (padrão de documentação para casts temporários)
|
||||
|
||||
|
|
|
|||
315
.agent/rules/zod-validacao-padrao.global.md
Normal file
315
.agent/rules/zod-validacao-padrao.global.md
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
---
|
||||
type: rule
|
||||
name: zod-validacao-padrao
|
||||
description: Estabelece Zod como biblioteca obrigatória de validação em todo o ecossistema Azteca
|
||||
version: "1.0"
|
||||
scope: global
|
||||
priority: alta
|
||||
trigger: always_on
|
||||
globs:
|
||||
- "**/*.ts"
|
||||
- "**/*.tsx"
|
||||
- "**/*.vue"
|
||||
alwaysApply: true
|
||||
updatedAt: "2026-06-01"
|
||||
references:
|
||||
- .agent/rules/typescript-sem-any.global.md
|
||||
- .agent/skills/criar-schema-zod.global/SKILL.md
|
||||
---
|
||||
|
||||
# Regra: Zod como Validador Padrão
|
||||
|
||||
## Contexto
|
||||
|
||||
Todo projeto do ecossistema Azteca que receba dados externos — API, formulário, webhook, importação, fila, variáveis de ambiente — **deve** validar esses dados com [Zod](https://zod.dev).
|
||||
|
||||
Zod é a única biblioteca de validação autorizada porque:
|
||||
|
||||
- Inferência nativa de tipos TypeScript (`z.infer<>`) — elimina duplicação entre schema e tipo
|
||||
- Bundle pequeno (~13KB gzipped) — viável no frontend
|
||||
- Compartilhável entre back e front via pacotes `*-comuns`
|
||||
- Ecossistema maduro: `zod-to-json-schema`, `@anatine/zod-nestjs`, integração com `tRPC`
|
||||
|
||||
---
|
||||
|
||||
## Regra
|
||||
|
||||
### 1. Toda entrada externa deve ser validada com Zod
|
||||
|
||||
Entradas externas incluem:
|
||||
|
||||
- **Corpo de requisição** (API REST, webhook, GraphQL)
|
||||
- **Query params e path params**
|
||||
- **Formulários de frontend**
|
||||
- **Dados de fila** (BullMQ, Redis, etc.)
|
||||
- **Arquivos importados** (CSV, JSON, Excel)
|
||||
- **Variáveis de ambiente**
|
||||
- **Respostas de APIs externas** (quando a resposta não é confiável)
|
||||
|
||||
### 2. Schemas devem residir no pacote `*-comuns`
|
||||
|
||||
Para que front e back compartilhem os mesmos schemas, eles devem residir no pacote `<modulo>-comuns`:
|
||||
|
||||
```
|
||||
<modulo>-comuns/src/
|
||||
├── tabelas/
|
||||
│ ├── usuarios/
|
||||
│ │ ├── zUsuarioCriar.ts
|
||||
│ │ ├── zUsuarioEditar.ts
|
||||
│ │ └── index.ts
|
||||
│ ├── empresas/
|
||||
│ │ ├── zEmpresaCriar.ts
|
||||
│ │ └── index.ts
|
||||
│ └── index.ts
|
||||
```
|
||||
|
||||
### 3. Tipos devem ser derivados dos schemas (nunca o inverso)
|
||||
|
||||
```typescript
|
||||
// ✅ CORRETO — tipo derivado do schema
|
||||
export const zUsuarioCriar = z.object({
|
||||
nome: z.string().min(1),
|
||||
email: z.string().email(),
|
||||
ativo: z.boolean().default(true),
|
||||
})
|
||||
export type tipoUsuarioCriar = z.infer<typeof zUsuarioCriar>
|
||||
|
||||
// ❌ ERRADO — tipo manual separado do schema
|
||||
interface UsuarioCriar {
|
||||
nome: string
|
||||
email: string
|
||||
ativo?: boolean
|
||||
}
|
||||
const zUsuarioCriar = z.object({ ... }) // duplicação!
|
||||
```
|
||||
|
||||
### 4. Nomenclatura obrigatória de schemas
|
||||
|
||||
| Padrão | Uso | Exemplo |
|
||||
|--------|-----|---------|
|
||||
| `z{Entidade}Criar` | Criação de registro | `zUsuarioCriar` |
|
||||
| `z{Entidade}Editar` | Edição de registro | `zUsuarioEditar` |
|
||||
| `z{Entidade}Filtro` | Filtros de listagem | `zUsuarioFiltro` |
|
||||
| `z{Entidade}Resposta` | Resposta de API | `zUsuarioResposta` |
|
||||
| `z{Entidade}Params` | Parâmetros de rota | `zUsuarioParams` |
|
||||
| `z{Modulo}Config` | Configuração do módulo | `zGeeConfig` |
|
||||
| `z{Modulo}Ambiente` | Variáveis de ambiente | `zBackAmbiente` |
|
||||
|
||||
Prefixo `z` minúsculo + nome em `PascalCase`.
|
||||
|
||||
### 5. Usar `safeParse` em vez de `parse` para erros controlados
|
||||
|
||||
```typescript
|
||||
// ✅ CORRETO — erro controlado
|
||||
const resultado = zUsuarioCriar.safeParse(dados)
|
||||
if (!resultado.success) {
|
||||
return respostaComuns.erro(resultado.error.issues[0].message)
|
||||
}
|
||||
const usuario = resultado.data // tipado automaticamente
|
||||
|
||||
// ❌ ERRADO — throw não controlado
|
||||
const usuario = zUsuarioCriar.parse(dados) // lança ZodError
|
||||
```
|
||||
|
||||
A exceção é em contextos onde o throw é desejável (middleware global, início de pipeline).
|
||||
|
||||
### 6. Nunca usar validação manual quando Zod resolve
|
||||
|
||||
```typescript
|
||||
// ❌ ERRADO — validação manual
|
||||
if (!dados.nome || typeof dados.nome !== "string") {
|
||||
return erro("Nome é obrigatório")
|
||||
}
|
||||
if (!dados.email || !dados.email.includes("@")) {
|
||||
return erro("Email inválido")
|
||||
}
|
||||
|
||||
// ✅ CORRETO — Zod faz tudo
|
||||
const resultado = zUsuarioCriar.safeParse(dados)
|
||||
if (!resultado.success) {
|
||||
return erro(resultado.error.issues[0].message)
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Transformações e defaults pertencem ao schema
|
||||
|
||||
```typescript
|
||||
// ✅ CORRETO — transformação no schema
|
||||
export const zProdutoCriar = z.object({
|
||||
nome: z.string().trim().min(1),
|
||||
preco: z.coerce.number().positive(),
|
||||
ativo: z.boolean().default(true),
|
||||
codigo: z.string().toUpperCase().optional(),
|
||||
tags: z.array(z.string()).default([]),
|
||||
})
|
||||
|
||||
// ❌ ERRADO — transformação manual após validação
|
||||
const produto = zProdutoCriar.parse(dados)
|
||||
produto.nome = produto.nome.trim()
|
||||
produto.codigo = produto.codigo?.toUpperCase()
|
||||
```
|
||||
|
||||
### 8. Composição de schemas em vez de duplicação
|
||||
|
||||
```typescript
|
||||
// ✅ CORRETO — composição
|
||||
const zEndereco = z.object({
|
||||
rua: z.string(),
|
||||
cidade: z.string(),
|
||||
uf: z.string().length(2),
|
||||
})
|
||||
|
||||
const zEmpresaCriar = z.object({
|
||||
nome: z.string(),
|
||||
endereco: zEndereco,
|
||||
})
|
||||
|
||||
const zEmpresaEditar = zEmpresaCriar.partial() // todos opcionais
|
||||
|
||||
const zEmpresaResposta = zEmpresaCriar.extend({
|
||||
codigo: z.string().uuid(),
|
||||
criadoEm: z.string().datetime(),
|
||||
})
|
||||
|
||||
// ❌ ERRADO — copiar campos entre schemas
|
||||
const zEmpresaEditar = z.object({
|
||||
nome: z.string().optional(), // duplicou!
|
||||
endereco: z.object({ // duplicou!
|
||||
rua: z.string().optional(),
|
||||
cidade: z.string().optional(),
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
### 9. Enums Zod para valores de domínio
|
||||
|
||||
```typescript
|
||||
// ✅ CORRETO — enum Zod quando os valores vêm de dados externos
|
||||
export const zStatusLicenca = z.enum(["ativa", "vencida", "suspensa", "cancelada"])
|
||||
export type tipoStatusLicenca = z.infer<typeof zStatusLicenca>
|
||||
|
||||
// Usar em outros schemas
|
||||
const zLicencaCriar = z.object({
|
||||
status: zStatusLicenca,
|
||||
// ...
|
||||
})
|
||||
|
||||
// ✅ TAMBÉM CORRETO — TypeScript enum quando já existe no projeto
|
||||
// e o schema referencia o enum
|
||||
import { StatusLicenca } from "./enums"
|
||||
const zLicencaCriar = z.object({
|
||||
status: z.nativeEnum(StatusLicenca),
|
||||
})
|
||||
```
|
||||
|
||||
### 10. Bibliotecas proibidas para validação
|
||||
|
||||
| ❌ Proibido | Motivo |
|
||||
|-------------|--------|
|
||||
| `joi` | Não infere tipos TS, bundle pesado |
|
||||
| `yup` | Inferência fraca, API menos ergonômica |
|
||||
| `class-validator` | Decorators, não compartilhável com frontend |
|
||||
| `io-ts` | Verboso, curva de aprendizado alta |
|
||||
| `ajv` (direto) | JSON Schema — usar `zod-to-json-schema` se precisar de JSON Schema |
|
||||
| Validação manual com `if/typeof` | Quando Zod resolve o mesmo caso |
|
||||
|
||||
---
|
||||
|
||||
## Exemplos
|
||||
|
||||
### API backend (Express)
|
||||
|
||||
```typescript
|
||||
// ✅ Correto
|
||||
import { zUsuarioCriar } from "projeto-comuns/tabelas/usuarios"
|
||||
|
||||
app.post("/usuarios", async (req, res) => {
|
||||
const resultado = zUsuarioCriar.safeParse(req.body)
|
||||
if (!resultado.success) {
|
||||
return res.status(400).json({ erro: resultado.error.issues })
|
||||
}
|
||||
const usuario = await criarUsuario(resultado.data)
|
||||
return res.json(usuario)
|
||||
})
|
||||
```
|
||||
|
||||
### Webhook com fila
|
||||
|
||||
```typescript
|
||||
// ✅ Correto — valida antes de enfileirar
|
||||
const zPayloadWebhook = z.object({
|
||||
tabela: z.enum(["empreendedores", "empreendimentos", "usuarios"]),
|
||||
dados: z.array(z.unknown()).min(1),
|
||||
})
|
||||
|
||||
app.post("/webhook/:tabela", async (req, res) => {
|
||||
const resultado = zPayloadWebhook.safeParse({
|
||||
tabela: req.params.tabela,
|
||||
dados: req.body,
|
||||
})
|
||||
if (!resultado.success) {
|
||||
return res.status(400).json({ erro: "Payload inválido" })
|
||||
}
|
||||
await fila.add("sync", resultado.data)
|
||||
return res.json({ ok: true })
|
||||
})
|
||||
```
|
||||
|
||||
### Variáveis de ambiente
|
||||
|
||||
```typescript
|
||||
// ✅ Correto — validar no boot da aplicação
|
||||
const zAmbiente = z.object({
|
||||
DATABASE_URL: z.string().url(),
|
||||
REDIS_HOST: z.string().default("localhost"),
|
||||
REDIS_PORT: z.coerce.number().default(6379),
|
||||
BASE_URL: z.string().url(),
|
||||
SESSAO_BACK: z.string().uuid(),
|
||||
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
|
||||
})
|
||||
|
||||
export const ambiente = () => zAmbiente.parse(process.env)
|
||||
```
|
||||
|
||||
### Frontend (formulário Vue)
|
||||
|
||||
```typescript
|
||||
// ✅ Correto — schema compartilhado validando antes de enviar
|
||||
import { zUsuarioCriar } from "projeto-comuns/tabelas/usuarios"
|
||||
|
||||
const salvar = async () => {
|
||||
const resultado = zUsuarioCriar.safeParse(formulario.value)
|
||||
if (!resultado.success) {
|
||||
erros.value = resultado.error.flatten().fieldErrors
|
||||
return
|
||||
}
|
||||
await api.post("/usuarios", resultado.data)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impacto
|
||||
|
||||
Sem esta regra:
|
||||
|
||||
- Cada desenvolvedor escolhe uma estratégia diferente de validação (if/typeof, joi, yup, etc.)
|
||||
- Tipos e schemas ficam dessincronizados — mudança no schema não reflete no tipo e vice-versa
|
||||
- Validações manuais são incompletas e inconsistentes entre endpoints
|
||||
- Código de validação é duplicado entre front e back
|
||||
- Dados inválidos passam despercebidos e corrompem a base
|
||||
|
||||
Com esta regra:
|
||||
|
||||
- Uma única fonte de verdade: o schema Zod
|
||||
- Tipos TypeScript sempre sincronizados via `z.infer<>`
|
||||
- Validação consistente em todos os pontos de entrada
|
||||
- Reutilização entre front, back e workers via pacote `*-comuns`
|
||||
- Erros de validação estruturados e internacionalizáveis
|
||||
|
||||
---
|
||||
|
||||
## Referências
|
||||
|
||||
- Rule: `.agent/rules/typescript-sem-any.global.md` (narrowing com Zod mencionado como alternativa)
|
||||
- Skill: `.agent/skills/criar-schema-zod.global/SKILL.md` (guia prático para criar schemas)
|
||||
184
.agent/skills/criar-schema-zod.global/SKILL.md
Normal file
184
.agent/skills/criar-schema-zod.global/SKILL.md
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
---
|
||||
name: criar-schema-zod
|
||||
scope: global
|
||||
description: >
|
||||
Guia operacional para criar, organizar e manter schemas de validação Zod em projetos TypeScript.
|
||||
---
|
||||
|
||||
# Skill: Criar Schema Zod
|
||||
|
||||
Use esta skill ao adicionar validação de dados em qualquer ponto de entrada do sistema — API, formulário, webhook, importação, fila ou variáveis de ambiente.
|
||||
|
||||
---
|
||||
|
||||
## PASSO 1 — Identificar a Entrada Externa
|
||||
|
||||
Determinar qual dado externo precisa de validação:
|
||||
|
||||
| Tipo de entrada | Onde validar |
|
||||
|---|---|
|
||||
| Corpo de requisição (POST/PUT) | Handler da rota, antes de qualquer lógica |
|
||||
| Query/path params | Handler da rota |
|
||||
| Formulário frontend | Antes de chamar a API |
|
||||
| Dados de fila (BullMQ) | No processador da fila |
|
||||
| Arquivo importado (CSV/JSON) | No parser, linha a linha |
|
||||
| Variáveis de ambiente | No boot da aplicação |
|
||||
| Resposta de API externa | Após receber a resposta |
|
||||
|
||||
---
|
||||
|
||||
## PASSO 2 — Localizar ou Criar o Schema no Pacote Comuns
|
||||
|
||||
Schemas compartilhados vivem no pacote `*-comuns`:
|
||||
|
||||
```
|
||||
projeto-comuns/src/tabelas/
|
||||
├── usuarios/
|
||||
│ ├── zUsuarioCriar.ts
|
||||
│ ├── zUsuarioEditar.ts
|
||||
│ └── index.ts
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
### 2.1. Verificar se já existe
|
||||
|
||||
```bash
|
||||
rg "z{NomeDaEntidade}" --include='*.ts' -l
|
||||
```
|
||||
|
||||
Se já existir → reutilizar ou compor a partir dele (`.extend()`, `.pick()`, `.partial()`).
|
||||
|
||||
### 2.2. Criar o schema
|
||||
|
||||
```typescript
|
||||
import { z } from "zod"
|
||||
|
||||
export const zUsuarioCriar = z.object({
|
||||
nome: z.string().trim().min(1, "Nome é obrigatório"),
|
||||
email: z.string().email("E-mail inválido"),
|
||||
ativo: z.boolean().default(true),
|
||||
})
|
||||
```
|
||||
|
||||
### 2.3. Nomenclatura obrigatória
|
||||
|
||||
| Padrão | Uso |
|
||||
|---|---|
|
||||
| `z{Entidade}Criar` | Criação |
|
||||
| `z{Entidade}Editar` | Edição (geralmente `.partial()`) |
|
||||
| `z{Entidade}Filtro` | Filtros de listagem |
|
||||
| `z{Entidade}Resposta` | Resposta de API |
|
||||
| `z{Entidade}Params` | Parâmetros de rota |
|
||||
| `z{Modulo}Config` | Configuração |
|
||||
| `z{Modulo}Ambiente` | Variáveis de ambiente |
|
||||
|
||||
---
|
||||
|
||||
## PASSO 3 — Derivar o Tipo com `z.infer<>`
|
||||
|
||||
```typescript
|
||||
export type tipoUsuarioCriar = z.infer<typeof zUsuarioCriar>
|
||||
```
|
||||
|
||||
**Nunca** criar um `interface` ou `type` manual separado do schema. O tipo **sempre** deriva do schema.
|
||||
|
||||
---
|
||||
|
||||
## PASSO 4 — Implementar `safeParse` no Ponto de Entrada
|
||||
|
||||
### Backend (Express)
|
||||
|
||||
```typescript
|
||||
import { zUsuarioCriar } from "projeto-comuns/tabelas/usuarios"
|
||||
|
||||
app.post("/usuarios", async (req, res) => {
|
||||
const resultado = zUsuarioCriar.safeParse(req.body)
|
||||
if (!resultado.success) {
|
||||
return res.status(400).json({ erro: resultado.error.issues[0].message })
|
||||
}
|
||||
const usuario = await criarUsuario(resultado.data)
|
||||
return res.json(usuario)
|
||||
})
|
||||
```
|
||||
|
||||
### Frontend (Vue)
|
||||
|
||||
```typescript
|
||||
import { zUsuarioCriar } from "projeto-comuns/tabelas/usuarios"
|
||||
|
||||
const salvar = async () => {
|
||||
const resultado = zUsuarioCriar.safeParse(formulario.value)
|
||||
if (!resultado.success) {
|
||||
erros.value = resultado.error.flatten().fieldErrors
|
||||
return
|
||||
}
|
||||
await api.post("/usuarios", resultado.data)
|
||||
}
|
||||
```
|
||||
|
||||
### Variáveis de ambiente
|
||||
|
||||
```typescript
|
||||
const zAmbiente = z.object({
|
||||
DATABASE_URL: z.string().url(),
|
||||
REDIS_HOST: z.string().default("localhost"),
|
||||
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
|
||||
})
|
||||
|
||||
// Aqui o throw é desejável — a app não deve subir com env inválido
|
||||
export const ambiente = () => zAmbiente.parse(process.env)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PASSO 5 — Compor Schemas Derivados
|
||||
|
||||
Quando precisar de variações do mesmo schema, **compor** em vez de duplicar:
|
||||
|
||||
```typescript
|
||||
// Schema base
|
||||
const zProduto = z.object({
|
||||
nome: z.string().trim().min(1),
|
||||
preco: z.coerce.number().positive(),
|
||||
categoria: z.string(),
|
||||
})
|
||||
|
||||
// Edição: todos os campos opcionais
|
||||
const zProdutoEditar = zProduto.partial()
|
||||
|
||||
// Resposta: base + campos gerados
|
||||
const zProdutoResposta = zProduto.extend({
|
||||
codigo: z.string().uuid(),
|
||||
criadoEm: z.string().datetime(),
|
||||
})
|
||||
|
||||
// Filtro: subset de campos opcionais
|
||||
const zProdutoFiltro = zProduto.pick({ categoria: true }).partial()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PASSO 6 — Validar Tipagem
|
||||
|
||||
```bash
|
||||
npx tsc --noEmit
|
||||
```
|
||||
|
||||
Zero erros = concluído.
|
||||
|
||||
---
|
||||
|
||||
## Checklist Final
|
||||
|
||||
- [ ] O schema está no pacote `*-comuns` (quando compartilhado entre front/back)?
|
||||
- [ ] O tipo é derivado do schema com `z.infer<>`?
|
||||
- [ ] A validação usa `safeParse` (exceto em boot/middleware)?
|
||||
- [ ] A nomenclatura segue o padrão `z{Entidade}{Acao}`?
|
||||
- [ ] Transformações (trim, coerce, default) estão no schema, não no handler?
|
||||
- [ ] Schemas derivados usam composição (.partial, .extend, .pick), não duplicação?
|
||||
- [ ] `tsc --noEmit` passa sem erros?
|
||||
|
||||
## Referências
|
||||
|
||||
- Rule: `.agent/rules/zod-validacao-padrao.global.md`
|
||||
- Rule: `.agent/rules/typescript-sem-any.global.md`
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
name: diagnosticar-erros-build
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
description: >
|
||||
Guia operacional para diagnosticar e resolver erros de build em cascata em monorepos TypeScript.
|
||||
---
|
||||
|
|
@ -181,5 +182,5 @@ pnpm install && pnpm build
|
|||
## 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`
|
||||
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||
- Skill: `.agent/skills/mapear-codigo-fonte.global/SKILL.md`
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
name: documentar-decisao-tecnica
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
description: >
|
||||
Guia operacional para registrar decisões técnicas e arquiteturais como ADRs (Architecture Decision Records).
|
||||
---
|
||||
|
|
@ -157,4 +158,4 @@ Antes de considerar completo:
|
|||
## Referências
|
||||
|
||||
- Workflow: `.agent/workflows/aprimorar-IA.global.md` (seção de classificação de artefatos)
|
||||
- Workflow: `.agent/workflows/documentar-codigo.global.md`
|
||||
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||
|
|
|
|||
131
.agent/skills/documentar-dominio-modulo.global/SKILL.md
Normal file
131
.agent/skills/documentar-dominio-modulo.global/SKILL.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
---
|
||||
name: documentar-dominio-modulo
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
description: >
|
||||
Guia para documentar o domínio científico/técnico de cada módulo SaaS,
|
||||
garantindo que o agente compreenda a terminologia e as regras do domínio
|
||||
ao gerar código, texto e interface.
|
||||
---
|
||||
|
||||
# Skill: Documentar Domínio de um Módulo
|
||||
|
||||
Use esta skill ao iniciar um novo módulo SaaS ou ao perceber que o agente não conhece o vocabulário e as regras do domínio que o módulo aborda.
|
||||
|
||||
Cada módulo opera em uma disciplina diferente da ciência/gestão ambiental (licenciamento, gases de efeito estufa, resíduos, projetos, etc.). O agente precisa de uma **base factual do domínio** para gerar labels, mensagens, regras de negócio e textos comerciais corretos.
|
||||
|
||||
---
|
||||
|
||||
## PASSO 1 — Identificar o Domínio do Módulo
|
||||
|
||||
Determinar qual área da ciência/gestão o módulo aborda:
|
||||
|
||||
| Exemplo de módulo | Domínio |
|
||||
|---|---|
|
||||
| Licenciamento | Licenciamento ambiental (LP, LI, LO, condicionantes) |
|
||||
| GEE | Gases de Efeito Estufa (inventário, emissões, fatores) |
|
||||
| Resíduos | Gestão de resíduos sólidos (PGRS, MTR, classificação) |
|
||||
| Outorga | Outorga de uso de recursos hídricos |
|
||||
| Flora/Fauna | Monitoramento de biodiversidade |
|
||||
| Projetos | Gestão de projetos ambientais e consultorias |
|
||||
|
||||
---
|
||||
|
||||
## PASSO 2 — Criar o Arquivo de Domínio
|
||||
|
||||
Criar em `.agent/memoria/dominio-<modulo>.md`:
|
||||
|
||||
```markdown
|
||||
# Domínio: <Nome do Módulo>
|
||||
|
||||
## Área de Conhecimento
|
||||
Breve descrição da disciplina (1-3 linhas).
|
||||
|
||||
## Glossário do Módulo
|
||||
|
||||
| Termo | Definição | Sigla |
|
||||
|---|---|---|
|
||||
| Licença Prévia | Autorização para planejamento do empreendimento | LP |
|
||||
| Licença de Instalação | Autorização para início das obras | LI |
|
||||
| ... | ... | ... |
|
||||
|
||||
## Entidades Principais
|
||||
|
||||
Lista das entidades de negócio do módulo com descrição e relações:
|
||||
|
||||
- **Empreendimento**: unidade física onde ocorre a atividade potencialmente poluidora
|
||||
- **Licença**: autorização ambiental vinculada a um empreendimento
|
||||
- **Condicionante**: obrigação imposta pelo órgão ambiental na licença
|
||||
- ...
|
||||
|
||||
## Legislação Aplicável
|
||||
|
||||
| Norma | Descrição | Relevância |
|
||||
|---|---|---|
|
||||
| Lei 6.938/1981 | Política Nacional do Meio Ambiente | Base legal do licenciamento |
|
||||
| Resolução CONAMA 237/1997 | Regulamenta o licenciamento ambiental | Tipos de licença, prazos |
|
||||
| ... | ... | ... |
|
||||
|
||||
## Regras de citação legal
|
||||
- Formato: "Resolução CONAMA nº 237/1997, art. 8º, inciso I"
|
||||
- Toda sigla na primeira ocorrência com nome por extenso
|
||||
- Legislação federal > estadual > municipal (hierarquia)
|
||||
|
||||
## Fluxos do Domínio
|
||||
|
||||
Descrever os processos-chave que o módulo implementa:
|
||||
|
||||
1. Solicitação de licença → Análise técnica → Emissão → Monitoramento
|
||||
2. Cadastro de condicionante → Acompanhamento de prazo → Cumprimento
|
||||
|
||||
## Vocabulário de Interface
|
||||
|
||||
Termos que devem ser usados em labels, botões e mensagens:
|
||||
|
||||
| Contexto | ❌ Genérico | ✅ Correto para o módulo |
|
||||
|---|---|---|
|
||||
| Campo de nome | "Nome" | "Razão Social do Empreendedor" |
|
||||
| Status | "Ativo/Inativo" | "Vigente/Vencida/Suspensa" |
|
||||
| Ação principal | "Criar novo" | "Solicitar nova licença" |
|
||||
| Lista vazia | "Nenhum registro" | "Nenhuma licença cadastrada" |
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PASSO 3 — Validar com o Operador
|
||||
|
||||
Antes de consolidar:
|
||||
|
||||
- [ ] Os termos do glossário estão corretos para o contexto do módulo?
|
||||
- [ ] As entidades cobrem os conceitos centrais?
|
||||
- [ ] A legislação listada é a principal (não exaustiva)?
|
||||
- [ ] O vocabulário de interface reflete como o usuário fala no dia a dia?
|
||||
|
||||
---
|
||||
|
||||
## PASSO 4 — Conectar com as Rules
|
||||
|
||||
Após documentar o domínio:
|
||||
|
||||
1. Verificar se labels e mensagens no código usam o vocabulário definido (rule `mensagens-usuario.global.md`)
|
||||
2. Verificar se schemas Zod têm mensagens de erro no idioma do domínio (rule `zod-validacao-padrao.global.md`)
|
||||
3. Verificar se os arquivos `.ajuda.md` usam termos do glossário (workflow `adicionar-ajuda.global.md`)
|
||||
4. Verificar se textos comerciais citam a legislação corretamente (workflow `comercial.global.md`)
|
||||
|
||||
---
|
||||
|
||||
## Checklist Final
|
||||
|
||||
- [ ] Arquivo `dominio-<modulo>.md` criado em `.agent/memoria/`?
|
||||
- [ ] Glossário com pelo menos os 10 termos centrais do módulo?
|
||||
- [ ] Entidades principais listadas com descrição?
|
||||
- [ ] Legislação base documentada com formato de citação?
|
||||
- [ ] Vocabulário de interface definido (labels, status, ações, empty states)?
|
||||
- [ ] Operador validou a terminologia?
|
||||
|
||||
## Referências
|
||||
|
||||
- Rule: `.agent/rules/mensagens-usuario.global.md`
|
||||
- Rule: `.agent/rules/regras-negocio-md.global.md`
|
||||
- Workflow: `.agent/workflows/comercial.global.md`
|
||||
- Workflow: `.agent/workflows/adicionar-ajuda.global.md`
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
---
|
||||
name: documentar-regras-negocio.global
|
||||
name: documentar-regras-negocio
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
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.
|
||||
|
|
@ -206,7 +208,5 @@ Percorrer cada regra listada no `.md` e verificar que há código correspondente
|
|||
|
||||
## Referências
|
||||
|
||||
- Rule: `.agent/rules/regras_negocio_md.global.md`
|
||||
- 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`
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
name: mapear-codigo-fonte
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
description: >
|
||||
Guia operacional para mapear, navegar e compreender a estrutura de um monorepo TypeScript.
|
||||
---
|
||||
|
|
@ -156,4 +157,4 @@ Descrever como os dados fluem entre pacotes.
|
|||
## Referências
|
||||
|
||||
- Rules: `.agent/rules/typescript-sem-any.global.md`
|
||||
- Workflow: `.agent/workflows/documentar-codigo.global.md`
|
||||
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ Para instalar as ferramentas base de forma ágil e em lote, copie os blocos de c
|
|||
```bash
|
||||
# 1. Atualizar e instalar ferramentas base do sistema
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ripgrep fd-find jq shellcheck bat tree httpie gh
|
||||
sudo apt-get install -y ripgrep fd-find jq shellcheck bat tree eza httpie gh
|
||||
|
||||
# 2. Instalar ferramentas em Node
|
||||
npm install -g @ast-grep/cli @biomejs/biome
|
||||
|
|
|
|||
41
.agent/verificar-linhas.sh
Normal file
41
.agent/verificar-linhas.sh
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# comando sh ../.agent/verificar-linhas.sh || exit 1
|
||||
|
||||
LIMITE=250
|
||||
|
||||
RAIZ=$(cd "$(dirname "$0")/.." && pwd)
|
||||
|
||||
RESULTADO=$(
|
||||
find "$RAIZ" \
|
||||
-type d \( \
|
||||
-name node_modules -o \
|
||||
-name .git -o \
|
||||
-name dist -o \
|
||||
-name build \
|
||||
\) -prune \
|
||||
-o \
|
||||
-type f \( \
|
||||
-name "*.ts" -o \
|
||||
-name "*.tsx" -o \
|
||||
-name "*.vue" -o \
|
||||
-name "*.css" \
|
||||
\) \
|
||||
-print | while IFS= read -r arquivo; do
|
||||
linhas=$(wc -l < "$arquivo" | tr -d ' ')
|
||||
if [ "$linhas" -gt "$LIMITE" ]; then
|
||||
relativo="${arquivo#$RAIZ/}"
|
||||
printf "%5s linhas -> %s\n" "$linhas" "$relativo"
|
||||
fi
|
||||
done
|
||||
)
|
||||
|
||||
if [ -n "$RESULTADO" ]; then
|
||||
echo "$RESULTADO"
|
||||
VIOLACOES=$(printf '%s\n' "$RESULTADO" | wc -l | tr -d ' ')
|
||||
printf "\n❌ %s arquivo(s) violam o limite de %s linhas.\n" "$VIOLACOES" "$LIMITE"
|
||||
printf "\n Resolva usando o arquivo: .agent/workflows/otimizar-codigos.global.md\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf "✅ Todos os arquivos dentro do limite de %s linhas.\n" "$LIMITE"
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: adicionar-ajuda
|
||||
description: Adicionar ou atualizar botão de ajuda e documentação em telas (Frontend)
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Adicionar Ajuda em Telas
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: aprimorar-IA
|
||||
description: Consolidar aprendizados da conversa atual e evoluir continuamente as regras, skills e fluxos da aplicação
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Aprimorar Conhecimento da Aplicação
|
||||
|
|
@ -74,7 +78,7 @@ Para cada item identificado, classificar obrigatoriamente:
|
|||
### Estrutura obrigatória:
|
||||
|
||||
- Um arquivo = um único assunto.
|
||||
- Nome claro em `snake_case`.
|
||||
- Nome claro em `kebab-case`.
|
||||
- Limite máximo: ~10.000 caracteres.
|
||||
|
||||
### É obrigatório:
|
||||
|
|
@ -196,105 +200,64 @@ Exemplos de skills de projeto:
|
|||
Sempre que decisões críticas sobre a arquitetura da aplicação ou o contexto do domínio precisarem ser arquivadas temporária ou permanentemente de maneira descritiva (e não diretamente injetável em código ou regra de lint):
|
||||
|
||||
* Registre o novo documento no formato adequado mantendo a pasta limpa em `.agent/memoria/`.
|
||||
* Exemplo: Manter diário de pendências (`diario_pendencias_modulo_x.md`) ou Arquivo de Registro de Decisão Arquitetural (`adr-001-migracao-nuxt-4.md`).
|
||||
* Atenção! Tudo que puder ser abstraído para um formato técnico estrito/guiado, deve virar **Skill** ou **Rule**. Use a Memória apenas como extensão de base factual.
|
||||
* Exemplo: Manter diário de pendências (`diario-pendencias-modulo-x.md`) ou ADR (`adr-001-migracao-nuxt-4.md`).
|
||||
* Atenção! Tudo que puder ser abstraído para formato técnico estrito deve virar **Skill** ou **Rule**. Use a Memória apenas como extensão de base factual.
|
||||
|
||||
---
|
||||
|
||||
## 6️⃣ Revisão Global de TODO o Sistema de Conhecimento (OBRIGATÓRIA E INEGOCIÁVEL)
|
||||
## 6️⃣ Revisão de Impacto (Dirigida por Grafo)
|
||||
|
||||
Esta é a etapa mais crítica.
|
||||
Quando um artefato é alterado, a revisão deve ser **dirigida**, não exaustiva.
|
||||
|
||||
Sempre que qualquer alteração ocorrer, é **OBRIGATÓRIO revisar TODO o sistema de conhecimento**, incluindo:
|
||||
### Processo:
|
||||
|
||||
* **TODOS os arquivos em `.agent/rules/`**
|
||||
* **TODOS os arquivos em `.agent/workflows/`**
|
||||
* **TODOS os arquivos em `.agent/skills/`**
|
||||
* **TODOS os arquivos em `.agent/memoria/`**
|
||||
1. Identificar o artefato alterado
|
||||
2. Consultar a seção `Referências` do artefato para encontrar dependentes diretos
|
||||
3. Verificar consistência APENAS entre o artefato alterado e seus dependentes
|
||||
4. Se uma inconsistência for encontrada, propagar para o próximo nível
|
||||
|
||||
### Regras de escopo:
|
||||
|
||||
| Se alterou... | Revisar... |
|
||||
|---|---|
|
||||
| Uma **Rule** | Workflows e skills que a **referenciam** |
|
||||
| Um **Workflow** | Skills que o **referenciam** |
|
||||
| Uma **Skill** | Rules e workflows na seção Referências |
|
||||
| **Memória/ADR** | Nada — memória é registro, não dependência |
|
||||
|
||||
### É PROIBIDO:
|
||||
|
||||
* Atualizar apenas um arquivo isolado.
|
||||
* Assumir que o impacto é local.
|
||||
* Ignorar arquivos existentes.
|
||||
* Criar artefatos sem validar o restante do sistema.
|
||||
* Revisar artefatos **sem relação** com a mudança
|
||||
* Afirmar que "tudo foi revisado" sem listar quais artefatos foram verificados
|
||||
* Criar artefatos sem verificar se já existe um com o mesmo escopo
|
||||
|
||||
### A revisão DEVE verificar:
|
||||
|
||||
* Não existem regras conflitantes entre o artefato alterado e seus dependentes
|
||||
* Referências cruzadas continuam válidas (arquivos existem, nomes corretos)
|
||||
* Skills refletem fielmente as rules que referenciam
|
||||
* Não há duplicação de conteúdo entre artefatos
|
||||
|
||||
---
|
||||
|
||||
### A revisão DEVE obrigatoriamente verificar:
|
||||
|
||||
#### Consistência
|
||||
|
||||
* Não existem regras conflitantes.
|
||||
* Não existem interpretações ambíguas.
|
||||
* Skills refletem fielmente as rules e workflows atuais.
|
||||
|
||||
#### Atualização
|
||||
|
||||
* Nenhuma rule está desatualizada.
|
||||
* Nenhum workflow usa regra antiga.
|
||||
* Nenhuma skill contém padrões obsoletos.
|
||||
|
||||
#### Não duplicação
|
||||
|
||||
* Não existem regras repetidas em arquivos diferentes.
|
||||
* Conteúdos redundantes foram consolidados.
|
||||
* Skills referenciam rules (não copiam o conteúdo).
|
||||
|
||||
#### Propagação de impacto
|
||||
|
||||
* Toda mudança foi refletida em:
|
||||
|
||||
* Rules relacionadas
|
||||
* Workflows relacionados
|
||||
* Skills relacionadas
|
||||
* Memória afetada pela mudança (ADRs, Diários)
|
||||
|
||||
#### Coerência estrutural
|
||||
|
||||
* Nomes de arquivos continuam válidos.
|
||||
* Assuntos estão bem separados.
|
||||
* Arquivos grandes foram divididos.
|
||||
* Skills estão organizadas em diretórios individuais.
|
||||
|
||||
---
|
||||
|
||||
### Regras obrigatórias desta etapa:
|
||||
|
||||
* **Toda alteração é considerada global até prova contrária.**
|
||||
* **Se uma rule muda, todos os workflows e skills relacionados DEVEM ser revisados.**
|
||||
* **Se um workflow muda, todas as rules e skills relacionadas DEVEM ser revisadas.**
|
||||
* **Se uma skill muda, as rules e workflows que ela referencia DEVEM ser verificados.**
|
||||
* **Atualizações de contexto devem garantir que toda a memória conflitante seja suprimida ou tagueada.**
|
||||
* **Nenhuma inconsistência pode permanecer.**
|
||||
* **Nenhuma duplicação é aceitável.**
|
||||
|
||||
---
|
||||
|
||||
## 7️⃣ Verificação Final (Checklist obrigatório)
|
||||
## 7⃣ Verificação Final (Checklist obrigatório)
|
||||
|
||||
Só é permitido encerrar se TODOS forem verdadeiros:
|
||||
|
||||
* [ ] Todas as rules foram revisadas
|
||||
* [ ] Todos os workflows foram revisados
|
||||
* [ ] Todas as skills foram revisadas
|
||||
* [ ] Não existe conflito entre artefatos
|
||||
* [ ] Artefatos dependentes do alterado foram revisados
|
||||
* [ ] Não existe conflito entre artefatos revisados
|
||||
* [ ] Não existe duplicação de conteúdo
|
||||
* [ ] Nenhuma regra ficou implícita
|
||||
* [ ] Todas as mudanças foram propagadas (rules ↔ workflows ↔ skills)
|
||||
* [ ] Referências cruzadas estão válidas
|
||||
* [ ] Estrutura está organizada por assunto
|
||||
* [ ] Nenhum arquivo excede ~10k caracteres
|
||||
* [ ] Workflows refletem fielmente as rules atuais
|
||||
* [ ] Skills referenciam (não duplicam) rules
|
||||
* [ ] O sistema está consistente como um todo
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Regra Suprema
|
||||
|
||||
> Se existir qualquer dúvida, conflito, duplicação ou inconsistência,
|
||||
> Se existir qualquer dúvida, conflito ou inconsistência
|
||||
> entre o artefato alterado e seus dependentes,
|
||||
> o trabalho é considerado **INCOMPLETO**.
|
||||
|
||||
Não existe atualização parcial.
|
||||
Não existe impacto local.
|
||||
Não existe exceção.
|
||||
A revisão é dirigida, não opcional.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: atualizar-agente
|
||||
description: Aplica atualizações globais para o agente de IA
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Atualizar Agente Global
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: comercial
|
||||
description: Criar uma descrição comercial das funcionalidades e do sistema
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Criar Descrição Comercial
|
||||
|
|
@ -137,4 +141,4 @@ O arquivo `./COMERCIAL/<nome-do-modulo>.md` deve seguir esta estrutura:
|
|||
- Regra global: `.agent/rules/escrita-natural.global.md` (padrão obrigatório de redação)
|
||||
- Workflow: `.agent/workflows/orcamento.global.md` (texto para documentos de orçamento e proposta — apresentação + lista de funcionalidades)
|
||||
- Workflow: `.agent/workflows/marketing.global.md` (peças de marketing digital — LinkedIn, Instagram, WhatsApp, E-mail)
|
||||
- Workflow: `.agent/workflows/documentar-codigo.global.md` (para documentação técnica, não comercial)
|
||||
- Workflow: `.agent/workflows/otimizar-codigos.global.md` (para documentação técnica, não comercial)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: criar-fluxograma
|
||||
description: Criar ou atualizar uma página de fluxograma interativo em qualquer sistema
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Criar Fluxograma de Decisões
|
||||
|
|
@ -181,5 +185,5 @@ Caso contrário, seguir os passos acima para criar a primeira implementação.
|
|||
|
||||
## Referências
|
||||
|
||||
- Workflow: `.agent/workflows/documentar-codigo.global.md`
|
||||
- Skill: `.agent/skills/documentar-decisao-tecnica/SKILL.md` (para decisões que geram fluxogramas)
|
||||
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||
- Skill: `.agent/skills/documentar-decisao-tecnica.global/SKILL.md` (para decisões que geram fluxogramas)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: documentar-regras-negocio
|
||||
description: Criar ou atualizar o arquivo {modulo}.regras-negocio.md co-localizado com um módulo TypeScript e garantir consistência entre código e documentação
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Documentar Regras de Negócio de um Módulo
|
||||
|
|
@ -86,7 +90,7 @@ Para cada regra listada no `.md`:
|
|||
|
||||
// turbo
|
||||
```bash
|
||||
cd e-licencie-back && node_modules/.bin/tsc --noEmit
|
||||
npx tsc --noEmit
|
||||
```
|
||||
|
||||
Zero erros = concluído.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: marketing
|
||||
description: Criar peças de marketing digital para funcionalidades e módulos do sistema
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Criar Peças de Marketing
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: orcamento
|
||||
description: Criar texto de orçamento pronto para copiar e colar em peças de orçamento/proposta
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Criar Texto de Orçamento
|
||||
|
|
|
|||
|
|
@ -1,221 +1,76 @@
|
|||
---
|
||||
description: Otimizar código e documentar padrões de qualidade (estrutura, limites, JSDoc e tipagem)
|
||||
type: workflow
|
||||
name: otimizar-codigos
|
||||
description: Processo de refatoração e validação de qualidade de código
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
|
||||
|
||||
# Workflow: Qualidade e Documentação de Código
|
||||
# Workflow: Qualidade e Otimização de Código
|
||||
|
||||
## 🎯 Objetivo
|
||||
|
||||
Unificar as regras de **estrutura de arquivos**, **otimização** e **documentação** em um único fluxo de referência para o projeto `eli-vue`.
|
||||
Aplicar as rules de qualidade do ecossistema Azteca em código existente ou novo, garantindo que todos os padrões sejam cumpridos antes de finalizar uma tarefa.
|
||||
|
||||
---
|
||||
|
||||
## 1️⃣ Limite de Linhas por Arquivo
|
||||
## Passos
|
||||
|
||||
Nenhum arquivo `*.vue`, `*.ts` ou `*.tsx` pode ultrapassar **250 linhas**.
|
||||
### 1. Verificar limite de linhas
|
||||
|
||||
Essa regra existe para facilitar a leitura humana, a revisão de código e a manutenção a longo prazo.
|
||||
|
||||
> O script `scripts/check-vue-linhas.sh` valida automaticamente os arquivos `.vue` no `prebuild`.
|
||||
|
||||
**Estratégias quando o limite se aproxima:**
|
||||
|
||||
| Situação | Ação |
|
||||
|---|---|
|
||||
| Template longo | Extrair seções como subcomponentes |
|
||||
| CSS extenso | Mover para `<nome>.css` co-localizado |
|
||||
| `setup()` extenso | Extrair subcomponentes, CSS ou Dispatch Table |
|
||||
| Modal/Dialog embutido | Sempre em componente separado (`*Modal.vue`) |
|
||||
| Handlers e dispatch | Extrair para `handlers.ts` ou `dispatch.ts` |
|
||||
|
||||
---
|
||||
|
||||
## 2️⃣ Estrutura de Componentes Vue
|
||||
|
||||
### `defineComponent` obrigatório
|
||||
|
||||
Todo componente Vue deve usar `defineComponent` para garantir inferência de tipos correta e consistência.
|
||||
|
||||
```vue
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'MeuComponente',
|
||||
setup() {
|
||||
// lógica aqui
|
||||
}
|
||||
})
|
||||
</script>
|
||||
```bash
|
||||
sh .agent/verificar-linhas.sh
|
||||
```
|
||||
|
||||
**Por que é importante:**
|
||||
- Inferência de tipos TypeScript correta dentro do componente
|
||||
- Reconhecimento por ferramentas de análise estática e IDEs
|
||||
- Compatível com Options API e Composition API com `setup()`
|
||||
- Padronização entre todos os componentes do projeto
|
||||
Se houver violações, aplicar estratégias da rule `limite-linhas.global.md`:
|
||||
- Extrair subcomponentes, mover CSS, usar Dispatch Table
|
||||
- Se necessário, converter em pasta com `index.vue`
|
||||
|
||||
---
|
||||
### 2. Validar estrutura Vue
|
||||
|
||||
### `setup()` não pode ser externo
|
||||
Para cada componente `.vue` modificado, verificar conforme `estrutura-vue.global.md`:
|
||||
- `defineComponent` presente?
|
||||
- `setup()` contém lógica própria (não delegada)?
|
||||
- CSS extenso foi movido para arquivo co-localizado?
|
||||
|
||||
O `setup()` deve estar sempre dentro do componente `.vue`. Não é permitido extrair ou delegar o `setup` para nenhum arquivo externo.
|
||||
### 3. Documentar código
|
||||
|
||||
```ts
|
||||
// ❌ Proibido — setup delegado inteiramente para arquivo externo
|
||||
// useEliTabela.ts
|
||||
export function useEliTabela(props, emit) { ... }
|
||||
Para cada função compartilhada criada/modificada, aplicar `jsdoc-padrao.global.md`:
|
||||
- JSDoc com `@param` e `@returns`?
|
||||
- Casts temporários têm comentário justificando?
|
||||
- TODOs no formato padronizado?
|
||||
|
||||
// EliTabela.vue
|
||||
export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
return useEliTabela(props, emit) // setup é apenas um proxy vazio
|
||||
}
|
||||
})
|
||||
### 4. Validar tipagem
|
||||
|
||||
```bash
|
||||
npx tsc --noEmit
|
||||
```
|
||||
|
||||
```ts
|
||||
// ✅ Correto — setup com lógica própria dentro do componente
|
||||
// EliTabela.vue
|
||||
export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
const estado = ref(null)
|
||||
const carregar = async () => { ... }
|
||||
return { estado, carregar }
|
||||
}
|
||||
})
|
||||
```
|
||||
Zero erros = prosseguir. Se houver erros, aplicar `typescript-sem-any.global.md` — nunca resolver com `any`.
|
||||
|
||||
> Composables `use*.ts` podem encapsular lógica reutilizável pontual (ex: `useFormatador`, `usePermissao`), mas nunca substituir ou esvaziar o `setup()` do componente. Se o componente ultrapassar 250 linhas, a solução é extrair subcomponentes, mover CSS ou usar Dispatch Table — não esvaziar o `setup`.
|
||||
### 5. Formatar
|
||||
|
||||
---
|
||||
|
||||
### Desassociação de CSS
|
||||
|
||||
A separação de estilos em arquivo externo é permitida e recomendada quando o CSS contribui significativamente para o total de linhas.
|
||||
|
||||
**Padrão de nomenclatura:**
|
||||
|
||||
```
|
||||
MeuComponente.vue
|
||||
MeuComponente.css
|
||||
```
|
||||
|
||||
O `.vue` importa o arquivo CSS no script:
|
||||
|
||||
```ts
|
||||
import './MeuComponente.css'
|
||||
```
|
||||
|
||||
Ou via tag `<style>`:
|
||||
|
||||
```vue
|
||||
<style src="./MeuComponente.css" />
|
||||
```bash
|
||||
npx biome check --write .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Dispatch Table em Arquivo Separado
|
||||
## Checklist Final
|
||||
|
||||
O uso de Dispatch Table (mapa de funções) em arquivos separados é bem-vindo para eliminar blocos longos de `if/else` ou `switch`.
|
||||
- [ ] `verificar-linhas.sh` passa sem violações?
|
||||
- [ ] Componentes Vue usam `defineComponent`?
|
||||
- [ ] Funções compartilhadas têm JSDoc?
|
||||
- [ ] Casts temporários estão justificados?
|
||||
- [ ] `tsc --noEmit` zero erros?
|
||||
- [ ] `biome check` sem problemas?
|
||||
|
||||
```ts
|
||||
// handlers.ts
|
||||
export const acaoHandlers: Record<string, () => void> = {
|
||||
salvar: () => { ... },
|
||||
cancelar: () => { ... },
|
||||
excluir: () => { ... },
|
||||
}
|
||||
```
|
||||
## Rules Aplicadas
|
||||
|
||||
```ts
|
||||
// MeuComponente.vue
|
||||
import { acaoHandlers } from './handlers'
|
||||
Este workflow orquestra a verificação das seguintes rules:
|
||||
|
||||
function executar(acao: string) {
|
||||
acaoHandlers[acao]?.()
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3️⃣ Documentação em Código (JSDoc)
|
||||
|
||||
### Princípios básicos
|
||||
|
||||
- **Por que, não o Quê**: Documente o raciocínio por trás da decisão arquitetural, não o mecanismo óbvio que o TypeScript já expressa.
|
||||
- **Nomenclatura limpa**: Confie na auto-documentação de nomes expressivos antes de escrever comentários de texto livre.
|
||||
|
||||
### Funções compartilhadas — JSDoc obrigatório
|
||||
|
||||
Toda função central ou de uso compartilhado (frontend, backend, mobile ou bibliotecas comuns) deve ter cabeçalho em `JSDoc`.
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Busca os detalhes de uma entidade baseando-se no ID fornecido e calcula privilégios aplicáveis.
|
||||
* Não utilizar em fluxos de processamento em lote para evitar sobrecarga de requisições.
|
||||
*
|
||||
* @param tenantId - Identificador único do cliente/tenant no sistema
|
||||
* @param entityId - ID exclusivo identificando o registro na base de dados
|
||||
* @returns Retorna o objeto consolidado com dados ou `null` caso não seja encontrado
|
||||
*/
|
||||
export const obterDetalhesEntidade = async (tenantId: string, entityId: string) => { ... }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4️⃣ Casts Temporários e Exceções de Tipagem
|
||||
|
||||
Devido à política **TypeScript sem any**, coerções agressivas requerem justificativa obrigatória em comentário.
|
||||
|
||||
```typescript
|
||||
// Necessário cast duplo pois a biblioteca externa não provê tipagem genérica adequada na versão atual
|
||||
const dados = payload.raw as unknown as RespostaFormatada
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5️⃣ TODOs Estruturados
|
||||
|
||||
Toda dívida técnica ou dúvida de negócio deixada em código deve seguir o formato `// TODO`:
|
||||
|
||||
- **Tipagem**: `// TODO de tipagem: Criar interface estrita para o retorno da API de listagem`
|
||||
- **Negócio**: `// TODO de regra: Validar com Produto se a taxa adicional se aplica a clientes antigos`
|
||||
|
||||
---
|
||||
|
||||
## 6️⃣ Resumo das Regras
|
||||
|
||||
| Regra | Permitido | Proibido |
|
||||
|---|---|---|
|
||||
| Tamanho de arquivo | Até 250 linhas | Acima de 250 linhas |
|
||||
| `defineComponent` | Obrigatório em todo `.vue` | Componentes sem `defineComponent` |
|
||||
| `setup()` externo | — | Proibido em qualquer forma |
|
||||
| CSS externo | `<nome>.css` vinculado ao `.vue` | CSS inline quando ultrapassa o limite |
|
||||
| Dispatch Table | Em arquivo separado | — |
|
||||
| JSDoc | Obrigatório em funções compartilhadas | Omitir em funções de uso amplo |
|
||||
| Casts `as any` | Com `biome-ignore` justificado | Sem comentário explicativo |
|
||||
|
||||
---
|
||||
|
||||
## 7️⃣ Checklist de Validação
|
||||
|
||||
Antes de concluir qualquer refatoração ou adição de código:
|
||||
|
||||
- [ ] O arquivo resultante tem menos de 250 linhas?
|
||||
- [ ] Funções compartilhadas têm `JSDoc` com `@param` e `@returns`?
|
||||
- [ ] Casts temporários têm comentário justificando?
|
||||
- [ ] TODOs estão no formato padronizado?
|
||||
- [ ] A documentação explica o **porquê**, não apenas o **o quê**?
|
||||
- [ ] `defineComponent` está presente em todo componente `.vue`?
|
||||
|
||||
---
|
||||
|
||||
## Referências
|
||||
|
||||
- Script: `scripts/check-vue-linhas.sh` (validação automática de tamanho)
|
||||
- Rule: `.agent/rules/vue-limite-linhas.global.md` (política de limite de linhas)
|
||||
- Rule: `.agent/rules/typescript-sem-any.global.md` (política de tipagem)
|
||||
- Skill: `.agent/skills/documentar-decisao-tecnica/SKILL.md` (ADRs para decisões arquiteturais)
|
||||
- `.agent/rules/limite-linhas.global.md` — máximo 250 linhas
|
||||
- `.agent/rules/estrutura-vue.global.md` — defineComponent, setup, CSS, dispatch
|
||||
- `.agent/rules/jsdoc-padrao.global.md` — JSDoc, casts, TODOs
|
||||
- `.agent/rules/typescript-sem-any.global.md` — proibição de any
|
||||
- `.agent/rules/zod-validacao-padrao.global.md` — validação de entradas externas
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: reels
|
||||
description: Criar cadeia de roteiros de Reels para divulgação de funcionalidades e módulos
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Criar Roteiros de Reels
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
---
|
||||
type: workflow
|
||||
name: ux
|
||||
description: Revisar e otimizar UX de componentes e telas Vue (Frontend)
|
||||
scope: global
|
||||
updatedAt: "2026-06-01"
|
||||
---
|
||||
|
||||
# Workflow: Revisão de UX
|
||||
|
|
@ -191,44 +195,8 @@ import { Filter, Plus, X, Trash2, Eye } from "@lucide/vue"
|
|||
|
||||
**Catálogo de referência**: https://lucide.dev/icons — buscar pelo nome do ícone em inglês.
|
||||
|
||||
#### CSS do projeto
|
||||
|
||||
```css
|
||||
/* Escala primária — Verde floresta */
|
||||
--cor-eli-primaria-bg: #EEF3D0;
|
||||
--cor-eli-primaria-zebra: #F6F9E8;
|
||||
--cor-eli-primaria-suave: #BFC99C;
|
||||
--cor-eli-primaria-clara: #D4E290;
|
||||
--cor-eli-primaria-media: #ADCC44;
|
||||
--cor-eli-primaria-acao: #8AAF00;
|
||||
--cor-eli-primaria: #688C00;
|
||||
--cor-eli-primaria-escura: #4A6500;
|
||||
--cor-eli-primaria-texto: #2E3F00;
|
||||
|
||||
/* Escala de apoio — Âmbar terroso */
|
||||
--cor-eli-alerta-bg: #FAF3DF;
|
||||
--cor-eli-alerta-clara: #F5DC8A;
|
||||
--cor-eli-alerta: #DDB847;
|
||||
--cor-eli-alerta-forte: #8C6A00;
|
||||
|
||||
/* Escala neutra — Cinza musgo */
|
||||
--cor-eli-fundo: #F2F3EE;
|
||||
--cor-eli-borda: #D5D8CC;
|
||||
--cor-eli-borda-forte: #B5BAA8;
|
||||
--cor-eli-neutro: #5E6553;
|
||||
--cor-eli-neutro-escuro: #3E4436;
|
||||
--cor-eli-superficie: #FFFFFF;
|
||||
|
||||
/* Semânticas */
|
||||
--cor-eli-sucesso: #2E7D32;
|
||||
--cor-eli-sucesso-bg: #E8F5E9;
|
||||
--cor-eli-erro: #C62828;
|
||||
--cor-eli-erro-bg: #FFEBEE;
|
||||
--cor-eli-info: #1565C0;
|
||||
--cor-eli-info-bg: #E3F2FD;
|
||||
```
|
||||
|
||||
> **⚠️ Regra crítica para componentes distribuídos como biblioteca**: todo token CSS novo (`--cor-eli-primaria-zebra`, `--cor-eli-primaria-suave`, etc.) deve ter **fallback hardcoded** no CSS do componente: `var(--token, #valorhex)`. Projetos destino podem não ter a versão mais recente do `design-tokens.css` e a variável resolverá como `undefined`, tornando a propriedade invisível.
|
||||
> Os tokens CSS estão documentados nas tabelas da seção **Paleta de Cores Institucional** acima.
|
||||
> No código, usar `var(--token, #fallback)` — sempre com fallback hardcoded em componentes de biblioteca.
|
||||
|
||||
- Classes devem seguir BEM: `eli-componente__elemento--modificador`
|
||||
- Evitar `!important` — resolver especificidade via seletor mais específico
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue