workspace/projects/gamilit/docs/97-adr/ADR-0001-monorepo-architecture.md
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 10:44:23 -06:00

480 lines
12 KiB
Markdown

# ADR-0001: Adopción de Arquitectura Monorepo
**Status:** ✅ Accepted
**Date:** 2025-11-01
**Deciders:** Tech Lead, Backend Team, Frontend Team
**Tags:** architecture, repository-structure, devops
---
## Context
### Situación Inicial
GAMILIT Platform originalmente estaba organizado en **4 repositorios separados**:
1. **gamilit-docs** (~2,000 archivos markdown)
- Documentación del proyecto
- Especificaciones técnicas
- ADRs y RFCs
- Guías de desarrollo
2. **gamilit-platform-backend** (~400 archivos TypeScript)
- API REST NestJS
- 13 módulos funcionales
- ~470 endpoints
3. **gamilit-platform-web** (~200 archivos TSX)
- Frontend React 19
- 33 mecánicas educativas
- 180+ componentes
4. **gamilit-deployment-scripts** (~50 archivos shell/yaml)
- Scripts de deployment
- Configuración PM2
- Workflows CI/CD
### Problemas Identificados
#### 1. Sincronización Manual Compleja
- **Cambios cross-repo:** Una feature que afectaba backend + frontend requería:
- 2 PRs separados en repos diferentes
- Coordinación manual de merges
- Riesgo de desincronización (backend mergeado pero frontend no)
- **Ejemplo real:** Agregar nuevo endpoint `/api/v1/gamification/achievements`
- Paso 1: PR en backend (crear endpoint)
- Paso 2: PR en frontend (consumir endpoint)
- **Problema:** Si frontend se mergea antes que backend → 404 errors en production
#### 2. Gestión de Versiones Fragmentada
- **4 sistemas de versionado independientes**
- Backend: v1.5.3
- Frontend: v2.1.0
- Docs: Sin versiones
- Scripts: Sin versiones
- **Problema:** Imposible saber qué versión de frontend es compatible con qué versión de backend
#### 3. Duplicación de Configuración
```
gamilit-platform-backend/
├── .eslintrc.js # Config ESLint
├── .prettierrc # Config Prettier
├── tsconfig.json # Config TypeScript
└── .github/workflows/ # CI/CD
gamilit-platform-web/
├── .eslintrc.js # ❌ DUPLICADO
├── .prettierrc # ❌ DUPLICADO
├── tsconfig.json # ❌ DUPLICADO
└── .github/workflows/ # ❌ DUPLICADO
```
**Impacto:**
- Cambiar regla de linting → Editar 2 archivos
- Actualizar workflow CI → Editar 2 archivos
- Riesgo de inconsistencias
#### 4. Onboarding Complejo
Nuevo desarrollador debe:
1. Clonar 4 repositorios diferentes
2. Setup de 4 entornos independientes
3. Configurar 4 .env files
4. Ejecutar 4 comandos de install separados
5. Coordinar 4 workflows de Git
**Tiempo de onboarding:** 4-6 horas (vs. 2-3 horas con monorepo)
#### 5. Búsqueda Global Imposible
- **Imposible buscar en todo el codebase** con un solo comando
- Buscar "ML_COINS" requería:
```bash
cd gamilit-platform-backend && grep -r "ML_COINS" .
cd ../gamilit-platform-web && grep -r "ML_COINS" .
cd ../gamilit-docs && grep -r "ML_COINS" .
```
#### 6. Refactoring Cross-Repo Riesgoso
**Ejemplo:** Renombrar `mlCoins``ml_coins` en toda la plataforma
Con repos separados:
1. ✅ Refactor backend (PR #123)
2. ✅ Refactor frontend (PR #456)
3.**Problema:** Entre merges, producción está rota
Con monorepo:
1. ✅ Refactor backend + frontend + docs en **1 PR atómico**
2. ✅ Tests CI validan ambos lados antes de merge
---
## Decision
**Adoptamos arquitectura de Monorepo** consolidando los 4 repos en una estructura unificada.
### Estructura Elegida
```
gamilit/projects/gamilit/
├── apps/ # Código de aplicaciones
│ ├── backend/ # NestJS backend
│ ├── frontend/ # React frontend
│ ├── database/ # PostgreSQL DDL/migrations
│ └── devops/ # Scripts DevOps
├── docs/ # Documentación
│ ├── 00-overview/
│ ├── 01-requerimientos/
│ ├── 02-especificaciones-tecnicas/
│ ├── 03-desarrollo/
│ ├── 04-planificacion/
│ ├── QUICK-REFERENCE/
│ ├── adr/ # Architecture Decision Records
│ └── standards/ # Estándares de código
├── orchestration/ # Orquestación de agentes IA
│ ├── 01-analisis/
│ ├── 02-planes/
│ ├── 03-subagentes/
│ ├── 04-logs/
│ └── 05-validaciones/
├── artifacts/ # Artefactos generados
│ ├── diagrams/
│ ├── changelogs/
│ └── reports/
├── package.json # Root package.json
├── .eslintrc.js # Shared ESLint config
├── .prettierrc # Shared Prettier config
├── tsconfig.json # Base TypeScript config
└── .github/ # Single CI/CD workflow
└── workflows/
```
### Principios Aplicados
1. **Single Source of Truth**
- Un solo repo → Una sola fuente de verdad
- Una sola versión del proyecto
2. **Atomic Changes**
- Cambios cross-app en un solo commit
- Tests CI validan toda la plataforma antes de merge
3. **Shared Tooling**
- Configuraciones compartidas (ESLint, Prettier, TS)
- Scripts compartidos (build, test, deploy)
4. **Clear Boundaries**
- Carpetas separadas por propósito (`apps/`, `docs/`, `orchestration/`)
- Cada app mantiene su independencia dentro del monorepo
---
## Alternatives Considered
### Alternativa 1: Mantener Repos Separados
**Pros:**
- ✅ Repos más pequeños (menos commits/history)
- ✅ Permisos granulares por repo
- ✅ CI/CD más rápido (solo testea repo modificado)
**Cons:**
- ❌ Sincronización manual compleja
- ❌ Refactoring cross-repo riesgoso
- ❌ Duplicación de configuración
- ❌ Onboarding complejo
**Decisión:** **Rechazada** - Los cons superan los pros
---
### Alternativa 2: Monorepo con Workspaces (Lerna/Nx)
**Pros:**
- ✅ Herramientas especializadas (Nx, Lerna, Turborepo)
- ✅ Build caching inteligente
- ✅ Dependency graph management
- ✅ Soporte para shared packages
**Cons:**
- ❌ Complejidad adicional de setup
- ❌ Learning curve de Nx/Lerna
- ❌ Overhead para proyecto pequeño-mediano (2 apps)
**Decisión:** **Pospuesta para Fase 2** - Consideraremos Nx cuando tengamos 5+ apps
---
### Alternativa 3: Monorepo Simple (RFC-0001)
**Pros:**
- ✅ Setup simple sin herramientas adicionales
- ✅ Estructura clara basada en carpetas
- ✅ Fácil de entender y mantener
- ✅ Suficiente para 2-3 apps
**Cons:**
- ⚠️ Sin build caching automático
- ⚠️ CI/CD debe testear todo siempre
**Decisión:** **✅ ELEGIDA** - Balance perfecto simplicidad/funcionalidad
---
## Consequences
### Positivas ✅
#### 1. Cambios Atómicos Cross-App
**Antes:**
```bash
# 2 PRs separados
cd gamilit-platform-backend
git checkout -b feature/new-endpoint
# ... hacer cambios ...
git push # PR #123
cd ../gamilit-platform-web
git checkout -b feature/consume-endpoint
# ... hacer cambios ...
git push # PR #456
```
**Ahora:**
```bash
# 1 PR atómico
cd gamilit/projects/gamilit
git checkout -b feature/new-endpoint
# Editar apps/backend/ y apps/frontend/
git add apps/backend apps/frontend
git commit -m "feat: add achievements endpoint + UI"
git push # PR único, tests validan ambos lados
```
#### 2. Búsqueda Global
```bash
# Buscar en TODO el codebase
grep -r "ML_COINS" .
# Buscar solo en código
grep -r "ML_COINS" apps/
# Buscar solo en docs
grep -r "ML_COINS" docs/
```
#### 3. Refactoring Seguro
**Ejemplo:** Renombrar constante
```bash
# 1. Buscar todas las ocurrencias
grep -r "OLD_NAME" apps/
# 2. Reemplazar en todo el monorepo
find apps/ -type f -exec sed -i 's/OLD_NAME/NEW_NAME/g' {} +
# 3. Commit atómico
git add apps/
git commit -m "refactor: rename OLD_NAME to NEW_NAME across platform"
# 4. CI testa backend + frontend juntos
# Si algo falla, el commit no se mergea
```
#### 4. Configuración Compartida
**Un solo .eslintrc.js:**
```json
{
"extends": ["../../.eslintrc.js"], // Hereda config root
"rules": {
// Overrides específicos si necesario
}
}
```
**Beneficio:** Cambiar regla de linting → Editar 1 archivo, afecta todo el repo
#### 5. Onboarding Simplificado
**Antes (4 repos):**
```bash
git clone repo1 && cd repo1 && npm install
git clone repo2 && cd repo2 && npm install
git clone repo3 && cd repo3 && npm install
git clone repo4 && cd repo4 && npm install
```
**Ahora (monorepo):**
```bash
git clone gamilit
cd gamilit/projects/gamilit
npm install # Install root + workspaces
npm run dev # Start todo
```
#### 6. Versionado Unificado
**Un solo package.json root:**
```json
{
"name": "gamilit-monorepo",
"version": "2.0.0", // Version única del proyecto
"workspaces": [
"apps/backend",
"apps/frontend"
]
}
```
### Negativas ⚠️
#### 1. Repo Más Grande
**Tamaño total:** ~130 MB (vs. 4 repos de ~30 MB cada uno)
**Mitigación:**
- Git LFS para archivos grandes
- .gitignore agresivo (node_modules, dist, logs)
- Shallow clones en CI: `git clone --depth 1`
#### 2. CI/CD Más Lento
**Problema:** Cambio en frontend → CI testea también backend (innecesario)
**Mitigación (Fase 2):**
```yaml
# .github/workflows/ci.yml
- name: Check changes
run: |
if git diff --name-only HEAD~1 | grep "^apps/backend"; then
echo "Backend changed, run backend tests"
fi
```
#### 3. Permisos Menos Granulares
**Problema:** No se puede dar acceso solo a "docs" sin dar acceso a "apps"
**Mitigación:**
- Branch protection rules
- CODEOWNERS file:
```
/apps/backend/ @backend-team
/apps/frontend/ @frontend-team
/docs/ @tech-writer @tech-lead
```
#### 4. Git History Más Complejo
**Problema:** `git log` muestra commits de todas las apps mezclados
**Mitigación:**
```bash
# Ver solo commits de backend
git log -- apps/backend/
# Ver solo commits de frontend
git log -- apps/frontend/
# Conventional commits ayudan a filtrar
git log --grep="^feat(backend)"
```
---
## Implementation Plan
### Fase 1: Migración (✅ Completada - 2025-11-01)
- [x] Crear estructura RFC-0001
- [x] Migrar gamilit-docs → `docs/`
- [x] Migrar gamilit-platform-backend → `apps/backend/`
- [x] Migrar gamilit-platform-web → `apps/frontend/`
- [x] Migrar gamilit-deployment-scripts → `apps/devops/`
- [x] Setup de workspaces en root package.json
- [x] Compartir configs (ESLint, Prettier, TS)
- [x] Actualizar CI/CD workflows
### Fase 2: Optimización (Planeada - Q1 2025)
- [ ] Evaluar Nx/Turborepo para caching
- [ ] Implementar selective CI (solo testear apps modificadas)
- [ ] Setup de Git LFS para assets grandes
- [ ] Mejorar CODEOWNERS granularity
---
## Metrics
### Before (4 Repos)
| Métrica | Valor |
|---------|-------|
| **Repos totales** | 4 |
| **Tiempo onboarding** | 4-6 horas |
| **PRs para cambio cross-app** | 2-4 PRs |
| **Riesgo de desincronización** | Alto |
| **Búsqueda global** | Imposible |
| **Config duplicada** | Sí (4x) |
### After (Monorepo)
| Métrica | Valor |
|---------|-------|
| **Repos totales** | 1 |
| **Tiempo onboarding** | 2-3 horas ✅ |
| **PRs para cambio cross-app** | 1 PR ✅ |
| **Riesgo de desincronización** | Bajo ✅ |
| **Búsqueda global** | `grep -r` ✅ |
| **Config duplicada** | No ✅ |
---
## Lessons Learned
### ✅ Qué funcionó bien
1. **Migración gradual:** Migrar un repo a la vez en sprints separados redujo riesgo
2. **RFC-0001 como guía:** Tener estructura definida antes de migrar fue clave
3. **Conventional commits:** Ayudaron a mantener history limpio durante migración
4. **CODEOWNERS:** Permitió mantener ownership claro post-migración
### ⚠️ Qué mejorar
1. **CI time:** Actualmente testa todo siempre, necesitamos selective testing
2. **Docs discovery:** Con 2,000+ archivos, navigation puede ser compleja → SIMCO helps
3. **Build scripts:** Necesitamos scripts de build más inteligentes
---
## References
- [RFC-0001: Estructura de Monorepo](../standards/RFC-0001-monorepo-structure.md)
- [Monorepos in Git (Martin Fowler)](https://martinfowler.com/bliki/MonorepoPattern.html)
- [Why Google Stores Billions of Lines in a Single Repository](https://cacm.acm.org/magazines/2016/7/204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository/fulltext)
- [Monorepo Tools: Lerna, Nx, Turborepo Comparison](https://monorepo.tools/)
---
**Status:** ✅ Accepted and Implemented
**Date Created:** 2025-11-01
**Last Updated:** 2025-11-07
**Supersedes:** N/A (primera ADR)
**Superseded by:** N/A
**Revisión:** Esta decisión se revisará en Q2 2025 para evaluar migración a Nx/Turborepo si el proyecto crece a 5+ apps.