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>
5.2 KiB
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:
- admin_dashboard - 0 tablas, 4 vistas
- gamilit - 0 tablas, 14 funciones
- 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:
-- 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:
-- 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
- Tech Lead
- Database Architect
- Backend Lead
- 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.