feat: biblioteca inteligente libs/ + 5 novas skills (20 skills total)
NOVAS SKILLS: - next-best-practices v0.1.0 (CLEAN) — Next.js App Router, RSC, caching, data - nextjs-patterns v1.0.0 (CLEAN) — Next.js 15: Server Actions, route handlers - vite v1.0.0 (CLEAN) — env vars, aliases, proxy, CJS compat - uncle-bob v1.0.0 (CLEAN) — Clean Code, SOLID, Clean Architecture - clean-code-review v1.0.0 (CLEAN) — naming, guard clauses, anti-patterns, refactoring - vue v1.0.0 (CLEAN) — Vue framework - vue-composition-api-best-practices v1.0.0 (CLEAN) — composables, Pinia, reactivity BIBLIOTECA INTELIGENTE libs/ (10 dominios, 11 arquivos): - typescript/ — TS safe + generics gotchas - react/ — Next.js App Router + Vite config - vue/ — Composition API + Pinia - linux/ — System diagnostic cheatsheet - database/ — PostgreSQL + MySQL patterns - browser/ — Chromium CLI + E2E testing - security/ — SAST audit (OWASP Top 10) - best-practices/ — Clean Code + SOLID + Clean Architecture - deploy/ — Docker multi-stack + OpenClaw ops - + INDEX.md como guia de navegacao .learnings/ — LRN-20260519-003 criado (biblioteca compartilhada)
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
# Clean Code & Architecture — Uncle Bob + SOLID
|
||||
|
||||
> Extracted from: `uncle-bob` v1.0.0 + `clean-code-review` v1.0.0
|
||||
|
||||
## 🧹 Clean Code — Regras Fundamentais
|
||||
|
||||
### Naming (nomes são a melhor documentação)
|
||||
| Elemento | Convenção | ❌ Errado | ✅ Certo |
|
||||
|----------|-----------|-----------|--------|
|
||||
| Variáveis | Revelam intenção | `n`, `d`, `tmp` | `userCount`, `elapsed` |
|
||||
| Funções | Verbo + substantivo | `user()`, `calc()` | `getUserById()`, `calculateTotal()` |
|
||||
| Booleanos | Forma de pergunta | `active`, `flag` | `isActive`, `hasPermission`, `canEdit()` |
|
||||
| Constantes | SNAKE_CASE | `max`, `timeout` | `MAX_RETRY_COUNT`, `REQUEST_TIMEOUT_MS` |
|
||||
| Classes | Substantivo | `Manager`, `Data` | `UserRepository`, `OrderService` |
|
||||
|
||||
> Se precisa de comentário para explicar o nome, o nome está errado.
|
||||
|
||||
### Functions — Regras
|
||||
| Regra | Guia |
|
||||
|-------|------|
|
||||
| **Small** | Máx 20 linhas, ideal 5-10 |
|
||||
| **One Thing** | Faz uma coisa, e faz bem |
|
||||
| **One Level** | Um nível de abstração por função |
|
||||
| **Few Args** | Max 3 argumentos, preferir 0-2 |
|
||||
| **No Side Effects** | Não muta entradas inesperadamente |
|
||||
|
||||
### Guard Clauses (evitar ninho profundidade)
|
||||
```ts
|
||||
// ❌ 5 níveis de profundidade
|
||||
function processOrder(order: Order) {
|
||||
if (order) {
|
||||
if (order.items.length > 0) {
|
||||
if (order.total > 0) { ... }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Guard clauses — zero aninhamento
|
||||
function processOrder(order: Order) {
|
||||
if (!order) return;
|
||||
if (order.items.length === 0) return;
|
||||
if (order.total <= 0) return;
|
||||
// lógica principal aqui
|
||||
}
|
||||
```
|
||||
|
||||
### SRP — Single Responsibility
|
||||
> Uma classe tem **um** motivo para mudar. Um ator, uma responsabilidade.
|
||||
|
||||
### DRY + YAGNI
|
||||
- **DRY**: Não duplique — três instâncias de duplicação é o limite para abstrair
|
||||
- **YAGNI**: Você não vai precisar — não construa features não requisitadas
|
||||
|
||||
---
|
||||
|
||||
## 🔷 SOLID Principles
|
||||
|
||||
| Princípio | Regra Curta |
|
||||
|-----------|-------------|
|
||||
| **S** — Single Responsibility | Uma razão para mudar |
|
||||
| **O** — Open/Closed | Aberto para extensão, fechado para modificação |
|
||||
| **L** — Liskov Substitution | Subtipo deve ser substituível pelo seu tipo base |
|
||||
| **I** — Interface Segregation | Muitas interfaces específicas > uma geral |
|
||||
| **D** — Dependency Inversion | Dependa de abstrações, não de concretudes |
|
||||
|
||||
### D — Dependency Inversion Exemplo
|
||||
```ts
|
||||
// ❌ Alto nível depende de baixo nível
|
||||
class ReportGenerator {
|
||||
private db = new MySQLConnection(); // concreto!
|
||||
}
|
||||
|
||||
// ✅ Depende de abstração
|
||||
interface Database { query(sql: string): Promise<any[]> }
|
||||
class ReportGenerator {
|
||||
constructor(private db: Database) {} // injetado!
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Clean Architecture — Dependency Rule
|
||||
|
||||
> Dependências de código apontam **para dentro** — para políticas de mais alto nível.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Entities / Domain │ ← Nada depende disto
|
||||
├─────────────────────────────────────┤
|
||||
│ Use Cases / Business Logic │ ← Só depende de Entities
|
||||
├─────────────────────────────────────┤
|
||||
│ Interface Adapters (Controllers) │ ← Só depende de Use Cases
|
||||
├─────────────────────────────────────┤
|
||||
│ Frameworks & Drivers (DB, UI) │ ← Tudo depende para dentro
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Regra da Dependência
|
||||
```
|
||||
Código de alto nível → abstração → código de baixo nível
|
||||
(não pode depender de detalhes)
|
||||
```
|
||||
|
||||
### Quando Usar Clean Architecture
|
||||
- Projetos com vida útil esperada > 2 anos
|
||||
- Múltiplas equipes trabalhando no mesmo código
|
||||
- Possibilidade de trocar framework
|
||||
- Regras de negócio complexas
|
||||
|
||||
## Code Review Checklist (Clean Code)
|
||||
- [ ] Nomes revelam intenção?
|
||||
- [ ] Funções fazem uma coisa só?
|
||||
- [ ] Sem comentários que só recontam o que o código faz?
|
||||
- [ ] Sem código comentado fora?
|
||||
- [ ] Sem mais de 3 argumentos em qualquer função?
|
||||
- [ ] SRP respeitado?
|
||||
- [ ] DRY aplicado mas sem over-abstração?
|
||||
- [ ] Tratamento de erros centralizado?
|
||||
- [ ] Sem uso de `any`/`as any` sem justificativa?
|
||||
- [ ] O retorno do commit deixa o código melhor do que encontrou? (Boy Scout)
|
||||
Reference in New Issue
Block a user