feat: rule global feedback-visivel + checklist no ag-agente

This commit is contained in:
Luiz Silva 2026-06-18 16:24:02 -03:00
parent 420e7b7a75
commit 43107a8023
3 changed files with 144 additions and 1 deletions

View file

@ -0,0 +1,130 @@
---
type: rule
name: feedback-visivel
description: Feedbacks importantes nunca ficam ocultos — devem ser visíveis no front, no console e no log de fila.
scope: global
trigger: always_on
updatedAt: "2026-06-18"
---
# Regra: Feedback Visível em Todas as Camadas
## Contexto
Erros silenciosos e feedback oculto são as piores formas de falha em um sistema.
O usuário fica sem saber o que aconteceu, o desenvolvedor não consegue diagnosticar, e o operador não vê nada nos logs.
Esta regra exige que todo feedback relevante seja surfaceado na camada apropriada — sem exceção.
---
## Regra
Todo evento relevante (erro, aviso, conclusão de processo, falha de validação) deve aparecer em **pelo menos uma** das camadas abaixo, e nas **todas as camadas que tiverem acesso**:
| Camada | Responsável | Como |
|--------|-------------|------|
| **Frontend** | `@ag-front` + `@ag-ux` | Toast, banner, mensagem inline, estado de erro visível |
| **Backend** | `@ag-back` | `console.error()` / `console.warn()` com contexto suficiente |
| **Log de fila** | `@ag-back` + `@ag-deploy` | Registrar falha no job com payload + stack trace |
---
## Exemplos
### ✅ Correto — frontend mostra, backend registra
```ts
// backend
try {
await processarLicenca(dados)
} catch (erro) {
console.error('[licenca] Falha ao processar', { licencaId: dados.id, erro })
throw new ErroOperacional('Não foi possível processar a licença')
}
```
```ts
// frontend
catch (erro) {
mensagem.value = extrairMensagemErro(erro) // nunca silenciar
mostrarFeedback('erro', mensagem.value)
}
```
### ❌ Errado — engolir o erro silenciosamente
```ts
try {
await processarLicenca(dados)
} catch (_) {
// silêncio — o usuário não sabe, o log não sabe
}
```
### ❌ Errado — mostrar erro técnico ao usuário
```ts
// frontend
catch (erro) {
alert(erro.stack) // nunca expor stack trace ao usuário
}
```
### ✅ Correto — log de fila (BullMQ)
```ts
// processador de fila
processor.on('failed', (job, erro) => {
console.error('[fila] Job falhou', {
jobId: job.id,
nome: job.name,
tentativas: job.attemptsMade,
erro: erro.message,
})
})
```
---
## Camadas e responsabilidades detalhadas
### Frontend (`@ag-front` + `@ag-ux`)
- Todo `catch` deve resultar em feedback visível ao usuário
- Nunca usar `catch (_) {}` sem ao menos logar no console do browser
- Mensagens de erro para o usuário: linguagem do domínio, sem stack trace, sem IDs técnicos
- Estados de carregamento e erro devem ser explícitos na UI (não apenas esconder o spinner)
- Usar o padrão: `loading → sucesso | erro`, nunca ficar preso em "loading" silencioso
### Backend (`@ag-back`)
- Toda exceção capturada deve ser logada com contexto: qual operação, qual entidade, qual erro
- `console.error()` para erros operacionais; `console.warn()` para situações de atenção
- Nunca logar senhas, tokens ou dados pessoais
- O log deve incluir o suficiente para reproduzir o problema: IDs, parâmetros relevantes
- Erros internos não devem vazar para o cliente — traduzir para `ErroOperacional` ou equivalente
### Fila (`@ag-back` + `@ag-deploy`)
- Se o sistema usa BullMQ, Redis ou similar: configurar handler de `failed` e `error`
- Jobs que falham devem ser registrados com: jobId, nome, tentativas, payload relevante, erro
- Falhas repetidas devem gerar alerta (monitoramento de `job.failedReason`)
- Nunca deixar um job falhar silenciosamente sem registro
---
## Impacto
- **Diagnóstico:** sem log, nenhum problema pode ser investigado
- **Confiança do usuário:** feedback ausente = sistema parece travado ou bugado
- **Operação:** sem log de fila, jobs perdidos são invisíveis
---
## Referências
- Rule: `global/rules/mensagens-usuario` (vocabulário para mensagens ao usuário)
- Persona: `agents/ag-front/persona.md` (estados de UI)
- Persona: `agents/ag-back/persona.md` (tratamento de erros)
- Persona: `agents/ag-ux/persona.md` (feedback imediato como princípio)