# Code Review Checklist — Fundamental Skill

Skill para revisar PRs y escribir código limpio. Usar antes de mergear cualquier PR en ventures de Fundamental.

---

## Checklist de PR (14 ítems)

Puntaje: X/14. Copiar resultado al PR como comentario.

### Nombres
- [ ] ¿Variables y métodos describen su intención sin necesidad de comentario?
  > Si necesitás un comentario para explicar el nombre, el nombre está mal. $d → $discountRate.
- [ ] ¿Sin abreviaturas ni nombres de una letra (salvo i, j en loops)?
  > $usr, $ord, $val → siempre explícitos. Tu yo de 3 meses te lo agradecerá.
- [ ] ¿Los booleanos son preguntas: isActive, hasPermission, canProcess?
  > Un booleano que no es pregunta obliga a leer el contexto para entender qué significa.

### Funciones
- [ ] ¿Cada función hace una sola cosa?
  > Si el nombre tiene "and", "or" o "also" ya hace dos cosas. Dividir.
- [ ] ¿Las funciones tienen 3 parámetros o menos?
  > Más de 3 parámetros → probablemente necesitás un Value Object o DTO.
- [ ] ¿No hay funciones de más de 20 líneas?
  > No es absoluta, pero funciones largas casi siempre hacen más de una cosa.

### Acoplamiento (Rigidez — dolor principal)
- [ ] ¿Este cambio tocó 3 archivos o menos?
  > Más de 3 archivos para una sola feature = rigidez. El sistema está mal acoplado.
- [ ] ¿Las dependencias apuntan a interfaces, no a clases concretas?
  > new MySQLRepository() en el negocio = rigidez garantizada. Inyectá la interfaz.
- [ ] ¿No hay if/elseif chains que deberían ser polimorfismo?
  > if type=='paypal' / elseif 'stripe' → cada nuevo tipo requiere tocar ese if.
- [ ] ¿Los módulos modificados pueden testearse de forma independiente?
  > Si para testear A necesitás B, C y D, el acoplamiento es demasiado alto.

### Claridad
- [ ] ¿Los comentarios explican el PORQUÉ, no el QUÉ?
  > // Regulación fiscal GT: IGV 12% → OK. // multiplica por 0.12 → el código ya lo dice.
- [ ] ¿No hay números ni strings mágicos sin nombre?
  > 86400 → SECONDS_PER_DAY. 0.12 → TAX_RATE_GT. "admin" → UserRole.ADMIN.

### IA-Ready (Claude Code / OpenCode)
- [ ] ¿Un agente de IA podría entender el dominio solo con los nombres del código?
  > Tu código es el prompt. Nombres vagos = el agente genera código incorrecto.
- [ ] ¿No hay lógica duplicada que un agente podría amplificar?
  > Los agentes repiten los patrones que ven. Duplicación existente → duplicación ×10.

---

## Diagnóstico de diseño (4 síntomas)

### Rigidez (Rigidity) — TU DOLOR PRINCIPAL
Cambiar una cosa obliga a cambiar muchas otras en cascada. Cada feature tarda el doble.
```js
// Cambiar el formato de fecha toca 18 archivos
// porque está hardcodeado en todos lados
```

### Fragilidad (Fragility)
Un cambio rompe partes que no tienen relación lógica con lo que tocaste.
```js
// Arreglás descuentos y
// misteriosamente se rompe el módulo de envíos
```

### Inmovilidad (Immobility)
No podés reusar una parte sin traerte todo lo demás.
```js
// Querés la lógica de descuentos en otro venture
// pero está acoplada a DB + mailer + sesión
```

### Viscosidad (Viscosity)
Hacer el hack es más fácil que hacerlo bien. El diseño te empuja al camino incorrecto.
```js
// Agregar el feature con un if anidado
// es más rápido que respetar el patrón
```

Sprint cada vez más lentos → Rigidez. Bugs en lugares inesperados → Fragilidad. Imposible reusar entre ventures → Inmovilidad. Siempre conviene el atajo → Viscosidad.

---

## Principios SOLID

### S — Single Responsibility
Una clase, una razón para cambiar.
- ❌ UserService { login() save() sendEmail() generateReport() }
- ✅ UserAuthenticator  UserRepository  UserMailer

### O — Open / Closed (CURA RIGIDEZ)
Abierto para extender, cerrado para modificar.
- ❌ if type=='paypal'... elseif 'stripe'... elseif 'crypto'...
- ✅ interface PaymentGateway { charge(Money $amount): Receipt }

### L — Liskov Substitution
Un subtipo reemplaza a su padre sin sorpresas.
- ❌ class Square extends Rectangle { // rompe setWidth() }
- ✅ class Square implements Shape { area(): float }

### I — Interface Segregation
No obligues a implementar métodos que no usás.
- ❌ interface Worker { work() eat() sleep() }  // el robot no duerme
- ✅ interface Workable { work() }  Feedable { eat() }

### D — Dependency Inversion (CURA RIGIDEZ)
Dependé de abstracciones, no de implementaciones.
- ❌ class OrderService { public MySQLRepo $repo; }
- ✅ __construct(OrderRepositoryInterface $repo)

---

## Glosario

- **Rigidez (Rigidity)**: Cambiar una cosa obliga a cambiar muchas otras. Causa: acoplamiento directo.
- **Fragilidad (Fragility)**: Los cambios rompen partes no relacionadas. Causa: dependencias ocultas.
- **Inmovilidad (Immobility)**: No podés reusar código sin traerte todo. Causa: negocio mezclado con infraestructura.
- **Viscosidad (Viscosity)**: El hack es más fácil que hacerlo bien. Causa: el diseño no facilita la vía correcta.
- **Acoplamiento (Coupling)**: Grado en que un módulo conoce los detalles internos de otro. Alto acoplamiento = Rigidez.
- **Cohesión (Cohesion)**: Grado en que las responsabilidades de una clase pertenecen juntas. Alta cohesión = SRP.
- **Polimorfismo (Polymorphism)**: Tratar distintos tipos de forma uniforme. Reemplaza los if/elseif chains.
- **Deuda técnica (Technical debt)**: Costo futuro de las decisiones apresuradas de hoy. Se acumula con intereses.
