Saltar al contenido principal

0001 — Documentación como código

Estado: aceptada · Fecha: 2026-09-09

Contexto​

El repositorio tenía catorce archivos .md sueltos en la raíz que nadie tenía obligación de actualizar, sin OpenAPI, sin referencia de tipos, sin changelog. La superficie a documentar es grande: unos 110 endpoints, 85 pantallas, 7 canales, 98 migraciones y decenas de variables de entorno.

Una wiki externa (Notion, Confluence) resuelve el problema de escribir y no el de mantener: nada conecta un cambio de código con la página que lo describe, así que la documentación empieza a mentir a las pocas semanas y deja de consultarse.

Decisión​

La documentación vive en docs/, en el mismo repositorio y en el mismo PR que el código, con Docusaurus y MDX. Y todo lo que se pueda deducir del código se genera, no se escribe: endpoints, variables de entorno, pantallas, tipos compartidos y migraciones.

Los artefactos generados se versionan, y el CI falla si difieren de lo que produce el código actual.

Consecuencias​

A favor. La documentación se revisa con el mismo mecanismo que el código. Un endpoint nuevo aparece solo en la referencia. Un enlace muerto rompe el build. El diff de un PR enseña cuándo cambió la superficie del producto.

En contra. Escribir documentación exige pasar por git, lo que deja fuera a quien no sea técnico. Se asume: quien escribe aquí es el equipo de desarrollo.

Coste. Cinco generadores y un job de CI que mantener. A cambio, la parte más voluminosa de la documentación no necesita mantenimiento manual.

Alternativas descartadas​

Wiki externa. Descartada por lo dicho: no hay forma de acoplar un cambio de código a la actualización de la página.

Generar el OpenAPI arrancando Nest. Habría dado esquemas de los DTO, pero exige levantar la aplicación (Redis, Supabase, variables de entorno) para construir la documentación. Se optó por leer los decoradores con el AST de TypeScript: menos rico, pero funciona en cualquier máquina y no puede fallar por un servicio caído.

TypeDoc para los tipos compartidos. Descartado por el mismo motivo: añade una cadena de herramientas que puede romper el build del CI, y genera enlaces relativos que chocan con la comprobación de enlaces rotos. El generador propio produce menos, pero produce siempre.

@nestjs/swagger en el backend. Es la forma canónica de tener OpenAPI en Nest y da una interfaz interactiva. Se descartó por ahora porque el backend no usa class-validator en los DTO, así que el plugin del CLI tendría muy poco de donde inferir: se pagaría una dependencia y unos decoradores en 25 controladores a cambio de casi los mismos datos que ya extrae el AST. La openapi.json que se publica sale de ese análisis estático. Si algún día los DTO llevan validación, esta decisión merece revisarse: entonces sí habría esquemas reales que generar.

commitlint con husky. Un centenar de paquetes de dependencia para validar una expresión regular. scripts/validar-commit.mjs hace lo mismo sin dependencias, funciona igual con npm o yarn, y el mensaje de error puede enumerar los tipos válidos explicados en castellano. El hook se activa desde el prepare de la raíz, que es lo único que aportaba husky.