Coding Guidelines
Principios core para trabajar con LLMs en tareas de desarrollo.
4 Principios
1. Pensa Antes de Codear
NO empezar a escribir codigo inmediatamente.
- Surfacea assumptions antes de implementar
- Pregunta sobre preferencias: estructuras de datos, patrones, librerias
- Presenta multiples opciones con trade-offs
- Confirma alineamiento antes de codear
2. Simplicidad Primero
El codigo mas simple que resuelve el problema.
- KISS, DRY, YAGNI siempre
- Sin abstracciones especulativas ("por si algun dia...")
- Sin features no pedidas
- Sin over-engineering: 3 lineas similares > abstraccion prematura
3. Cambios Quirurgicos
Editar lo minimo necesario.
- Matchear patterns existentes del codebase
- No refactorizar codigo que no toca la feature
- No agregar docstrings/comments donde no habia
- No cambiar estilo/formato de codigo existente
4. Objetivos Verificables
Criterios claros para saber cuando esta listo.
- Definir que significa "funciona"
- Tests que validen el comportamiento esperado
- Checkear lint, types, build antes de terminar
Aplicacion por Lenguaje
Ver referencias para reglas especificas:
references/typescript.md- TypeScript strict mode, testing, estructurareferences/python.md- Type hints, mypy, pytest, ruff
Ejemplos de Uso
Ejemplo 1: Usuario pide agregar feature de logging
Usuario: "Agrega logging a este servicio"
MAL (sin consultar):
import winston from 'winston';
const logger = winston.createLogger({...});
BIEN (consultar primero):
Antes de agregar logging, necesito entender:
1. Que libreria de logging prefieren? (winston, pino, console estructurado)
2. A donde van los logs? (stdout, archivo, servicio externo)
3. Que nivel de detalle? (solo errores, debug incluido)
4. Hay un formato estandar en el proyecto?
Vi que ya usan console.log en otros lugares. Prefieren mantener
consistencia o migrar todo a una libreria?
Ejemplo 2: Usuario pide refactorizar
Usuario: "Este archivo esta muy largo, refactorizalo"
MAL (hacer todo):
// Extraer todo a archivos separados, agregar types, cambiar naming...
BIEN (proponer opciones):
El archivo tiene 450 lineas. Opciones:
A) Extraer helpers a utils/helpers.ts (reduce a ~300 lineas)
B) Separar por dominio: user.ts, auth.ts, session.ts
C) Solo extraer la funcion mas larga (validateUserSession, 80 lineas)
Cual preferis? Recomiendo C porque es el cambio minimo
que mejora legibilidad sin reestructurar todo.
Ejemplo 3: Usuario pide implementar validacion
Usuario: "Agrega validacion al form de registro"
MAL (asumir):
import { z } from 'zod';
const userSchema = z.object({...});
BIEN (preguntar scope):
Que tipo de validacion necesitas?
1. Solo frontend (mostrar errores en el form)
2. Solo backend (retornar 400 con errores)
3. Ambos (schema compartido)
Vi que el proyecto usa yup en otros forms.
Sigo con yup o preferis otra libreria?
Anti-patrones
Saltar a codear sin discutir
// Usuario: "Agrega cache"
// Inmediatamente:
import Redis from 'ioredis';
const redis = new Redis(); // Quien pidio Redis?
Problema: Se asumio Redis cuando podria ser in-memory, localStorage, o un servicio externo.
Agregar features "por las dudas"
// Te pidieron: agregar un boton de logout
// Agregaste:
<Button onClick={logout}>Logout</Button>
<ConfirmModal /> {/* Nadie pidio confirmacion */}
<SessionTimeoutWarning /> {/* Nadie pidio esto */}
Problema: Features no solicitadas = codigo extra que mantener.
Refactorizar de paso
// Te pidieron: corregir bug en calculateTotal()
// Se hizo:
- function calculateTotal(items) {
+ function calculateTotal(items: CartItem[]): Money { // Tipos nuevos
// ... fix del bug ...
}
+ // Tambien se renombraron variables para mayor claridad - NO
+ // Y se extrajo la logica de descuentos - NO
Problema: El PR tiene cambios mezclados, dificil de revisar.
Over-engineering
// Te pidieron: guardar preferencia de tema (dark/light)
// Se hizo:
class ThemeManager implements IThemeProvider {
private strategy: ThemeStrategy;
private observers: ThemeObserver[] = [];
constructor(config: ThemeConfig) { ... }
}
// Cuando bastaba:
localStorage.setItem('theme', 'dark');
Problema: Complejidad innecesaria. Un boolean no necesita un patron Observer.
Asumir en vez de preguntar
// Usuario: "No funciona el login"
// Se empezo a reescribir el auth flow completo...
// Cuando el bug era:
- if (password = storedHash) // typo: = en vez de ===
+ if (password === storedHash)
Problema: Investigar primero, preguntar que error ven, antes de reescribir.