Some checks are pending
CI Pipeline / changes (push) Waiting to run
CI Pipeline / core (push) Blocked by required conditions
CI Pipeline / trading-backend (push) Blocked by required conditions
CI Pipeline / trading-data-service (push) Blocked by required conditions
CI Pipeline / trading-frontend (push) Blocked by required conditions
CI Pipeline / erp-core (push) Blocked by required conditions
CI Pipeline / erp-mecanicas (push) Blocked by required conditions
CI Pipeline / gamilit-backend (push) Blocked by required conditions
CI Pipeline / gamilit-frontend (push) Blocked by required conditions
Gamilit: - Backend: Teacher services, assignments, gamification, exercise submissions - Frontend: Admin/Teacher/Student portals, module 4-5 mechanics, monitoring - Database: DDL functions, seeds for dev/prod, auth/gamification schemas - Docs: Architecture, features, guides cleanup and reorganization Core/Orchestration: - New workspace directives index - Documentation directive Trading-platform: - Database seeds and inventory updates - Tech leader validation report 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
173 lines
5.2 KiB
Markdown
173 lines
5.2 KiB
Markdown
# ADR-007: Schemas de Base de Datos Sin Tablas
|
|
|
|
**Estado:** Aceptado
|
|
**Fecha:** 2025-11-10
|
|
**Autores:** Equipo Técnico GAMILIT
|
|
**Decisores:** Tech Lead, Database Architect
|
|
|
|
---
|
|
|
|
## Contexto
|
|
|
|
Durante la reorganización de la base de datos a arquitectura modular (13 schemas por dominio), se identificaron 3 schemas sin tablas propias:
|
|
|
|
1. **admin_dashboard** - 0 tablas, 4 vistas
|
|
2. **gamilit** - 0 tablas, 14 funciones
|
|
3. **storage** - 0 tablas, 1 enum
|
|
|
|
Esta situación genera confusión sobre si son schemas "incompletos" o si hay una estrategia arquitectónica intencional.
|
|
|
|
---
|
|
|
|
## Decisión
|
|
|
|
Se decide **mantener los 3 schemas sin tablas** por las siguientes razones estratégicas:
|
|
|
|
### 1. admin_dashboard
|
|
|
|
**Estrategia:** Usar **vistas exclusivamente** sobre tablas de otros schemas.
|
|
|
|
**Justificación:**
|
|
- Evita duplicación de datos
|
|
- Mantiene una capa de agregación separada
|
|
- Facilita cambios en la estructura subyacente sin afectar dashboards
|
|
- Performance adecuado con índices en tablas base
|
|
|
|
**Implementación:**
|
|
```sql
|
|
-- 4 vistas implementadas:
|
|
- user_stats_summary (agrega datos de auth_management + gamification)
|
|
- organization_stats_summary (agrega social_features + progress_tracking)
|
|
- moderation_queue (agrega content_management + audit_logging)
|
|
- recent_admin_actions (agrega audit_logging)
|
|
```
|
|
|
|
**Beneficio:** Separación de concerns - el schema admin_dashboard NO posee datos, solo los presenta.
|
|
|
|
### 2. gamilit
|
|
|
|
**Estrategia:** Schema para **funciones utilitarias compartidas** (sin datos propios).
|
|
|
|
**Justificación:**
|
|
- Funciones de utilidad necesitan ubicación centralizada
|
|
- No requieren tablas de estado
|
|
- Se usan desde múltiples schemas
|
|
- Evita duplicación de código SQL
|
|
|
|
**Implementación:**
|
|
```sql
|
|
-- 14 funciones utilitarias:
|
|
- get_current_user_id()
|
|
- get_current_user_role()
|
|
- validate_email_format()
|
|
- validate_username()
|
|
- now_mexico()
|
|
- is_admin()
|
|
- audit_profile_changes()
|
|
- update_updated_at_column()
|
|
- etc.
|
|
```
|
|
|
|
**Beneficio:** Reutilización de lógica común sin acoplamiento de datos.
|
|
|
|
### 3. storage
|
|
|
|
**Estrategia:** **Delegar completamente a Storage compatible API**.
|
|
|
|
**Justificación:**
|
|
- Storage compatible maneja buckets, objetos y metadatos internamente
|
|
- No necesitamos tablas custom para storage
|
|
- Reduce complejidad de mantenimiento
|
|
- Aprovecha features del storage provider (CDN, transformaciones, etc.)
|
|
|
|
**Implementación:**
|
|
- API: `storageClient.from('bucket').upload()`
|
|
- Sin tablas custom
|
|
- Metadata en `storage.objects` (tabla del sistema)
|
|
|
|
**Beneficio:** Menor superficie de mantenimiento, features enterprise incluidas.
|
|
|
|
---
|
|
|
|
## Alternativas Consideradas
|
|
|
|
### Alternativa 1: Crear Tablas en admin_dashboard
|
|
**Pros:** Datos "propios" del dashboard
|
|
**Cons:** Duplicación de datos, sincronización compleja, ETL necesario
|
|
**Decisión:** ❌ Rechazado - vistas son suficientes
|
|
|
|
### Alternativa 2: Crear Schema functions/ en lugar de gamilit
|
|
**Pros:** Nombre más explícito
|
|
**Cons:** Breaking change, migraciones complejas
|
|
**Decisión:** ❌ Rechazado - nombre gamilit es histórico y funcional
|
|
|
|
### Alternativa 3: Implementar Custom Storage en storage schema
|
|
**Pros:** Control total sobre storage
|
|
**Cons:** Reinventar la rueda, 100+ horas de desarrollo, bugs potenciales
|
|
**Decisión:** ❌ Rechazado - Storage compatible es superior
|
|
|
|
---
|
|
|
|
## Consecuencias
|
|
|
|
### Positivas
|
|
|
|
✅ **Claridad Arquitectónica:** Documentado que schemas sin tablas son intencionales
|
|
✅ **Menor Complejidad:** No duplicación de datos
|
|
✅ **Mejor Mantenimiento:** Cambios en un solo lugar
|
|
✅ **Performance:** Vistas optimizadas con índices en tablas base
|
|
✅ **Reutilización:** Funciones compartidas evitan código duplicado
|
|
|
|
### Negativas
|
|
|
|
⚠️ **Confusión Inicial:** Desarrolladores nuevos pueden pensar que están "incompletos"
|
|
⚠️ **Documentación Crítica:** Requiere ADR (este documento) para explicar estrategia
|
|
⚠️ **Dependencia de Storage externo:** Storage depende 100% de servicio externo
|
|
|
|
### Mitigación
|
|
|
|
- ✅ Este ADR documenta la estrategia claramente
|
|
- ✅ Comentarios en DDL explican el propósito de cada schema
|
|
- ✅ Inventario de base de datos (DATABASE_INVENTORY.yml) documenta el estado
|
|
- ✅ Backups de Storage compatible configurados
|
|
|
|
---
|
|
|
|
## Estado de Implementación
|
|
|
|
| Schema | Tablas | Objetos | Estado | Documentado |
|
|
|--------|--------|---------|--------|-------------|
|
|
| **admin_dashboard** | 0 | 4 vistas | ✅ Completo | ✅ Sí |
|
|
| **gamilit** | 0 | 14 funciones | ✅ Completo | ✅ Sí |
|
|
| **storage** | 0 | 1 enum (legacy) | ✅ Completo | ✅ Sí |
|
|
|
|
---
|
|
|
|
## Referencias
|
|
|
|
- **DDL:** `/apps/database/ddl/schemas/*/`
|
|
- **Inventario:** `/docs/90-transversal/inventarios/DATABASE_INVENTORY.yml`
|
|
- **ADR Relacionado:** ADR-002 (Arquitectura de Base de Datos)
|
|
- **Epic:** EMR-001 (Migración a Schemas Modulares)
|
|
|
|
---
|
|
|
|
## Aprobaciones
|
|
|
|
- [x] Tech Lead
|
|
- [x] Database Architect
|
|
- [x] Backend Lead
|
|
- [x] DevOps Lead
|
|
|
|
---
|
|
|
|
## Changelog
|
|
|
|
| Fecha | Versión | Cambio |
|
|
|-------|---------|--------|
|
|
| 2025-11-10 | 1.0 | ADR inicial - Decisión documentada |
|
|
|
|
---
|
|
|
|
**Este ADR resuelve la confusión sobre schemas "vacíos" y establece que su estado actual es intencional y arquitectónicamente sound.**
|