# Principio de idiomas de framework

Complemento a `SKILL.md` de `meta-skills-estandar`. Tabla extensa por framework
y anti-patrón de código a detectar. Referenciado desde el skill principal.

---

## Regla

> Las convenciones del framework toman **precedencia** sobre la consistencia
> cross-proyecto. Si el framework provee un mecanismo oficial para resolver un
> problema, ese mecanismo ES la solución correcta — no una alternativa genérica.

## Ejemplos por framework

| Framework | Patrón idiomático correcto | Anti-patrón genérico a evitar |
|-----------|---------------------------|-------------------------------|
| **Django** | Middleware global de errores, signals para side effects, `select_related`/`prefetch_related` | Try/except en cada vista, queries N+1, actualizaciones manuales de estado |
| **FastAPI** | `Annotated` + `Depends` para DI, `selectinload` explícito en async, `lifespan` para startup/shutdown | Parámetros manuales de DI, lazy loading en contexto async (MissingGreenlet) |
| **NestJS** | Constructor injection con `@Injectable()`, DTOs con `class-validator`, `@Module` para encapsulación | Field injection con `@Autowired`, validación manual de inputs |
| **Spring Boot** | `@Transactional` de Spring, constructor injection con `@RequiredArgsConstructor`, `@Transactional(readOnly=true)` para lecturas | Field injection, manejo manual de transacciones, SQL raw sin justificación |
| **Laravel** | Eager loading con `->with()`, API Resources para transformación, Jobs para operaciones largas | N+1 con Eloquent, lógica de negocio en controladores, sync para operaciones costosas |
| **Rails** | `includes`/`eager_load` para N+1, service objects para lógica compleja, `strong_parameters` para inputs | Lazy loading no controlado, lógica en controladores, params sin filtrar |
| **Go** | `context.Context` para cancellation, error wrapping con `fmt.Errorf("...: %w", err)`, `sync.WaitGroup` para concurrencia | Panics para errores de negocio, goroutines sin control de lifecycle |
| **Rust** | `?` operator para propagación de errores, `Arc<Mutex<T>>` para estado compartido, `thiserror` para error types | Panics en código de biblioteca, `unwrap()` en producción, `clone()` innecesario |

## Cómo aplicar al escribir o revisar una skill

1. **Identificar el mecanismo oficial** del framework para el problema.
2. **Verificar** que el ejemplo de código en la skill usa ese mecanismo.
3. **Marcar como anti-patrón** cualquier alternativa genérica que ignore el
   mecanismo del framework.
4. **Documentar el "por qué"**: explicar qué errores específicos evita.

## Anti-patrón a detectar

```markdown
# MAL — skill que describe patrones genéricos
## Manejo de errores
try:
    resultado = operacion()
except Exception as e:
    logging.error(e)
    raise

# BIEN — skill que usa el idioma de Django
## Manejo de errores (Django)
# Usar el middleware global de Django para errores inesperados:
# MIDDLEWARE = ['django.middleware.common.CommonMiddleware', ...]
# Para errores esperados, usar excepciones específicas de DRF:
raise ValidationError({"campo": "El valor no es válido"})
# DRF las convierte automáticamente en respuestas 400 con formato estándar
```

## Gotcha: aplicar solo cuando el skill cubre UN framework

Un skill transversal (p.ej. `compactacion-contexto`) NO debe usar ejemplos
de framework específico. El principio aplica únicamente cuando la skill
cubre un solo framework y tiene como propósito documentar patrones
idiomáticos de ese framework.
