workspace/projects/gamilit/docs/97-adr/ADR-007-schemas-sin-tablas.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

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 Supabase Storage API**.
**Justificación:**
- Supabase Storage maneja buckets, objetos y metadatos internamente
- No necesitamos tablas custom para storage
- Reduce complejidad de mantenimiento
- Aprovecha features optimizadas de Supabase (CDN, transformaciones, etc.)
**Implementación:**
- API: `supabase.storage.from('bucket').upload()`
- Sin tablas custom
- Metadata en `storage.objects` (tabla managed de Supabase)
**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 - Supabase Storage 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 Supabase:** 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 Supabase Storage 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.**