- 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>
370 lines
12 KiB
Markdown
370 lines
12 KiB
Markdown
# DECISIONES ARQUITECTURALES REQUERIDAS
|
|
|
|
**Fecha:** 2025-11-07
|
|
**Estado:** Post-validación de integridad
|
|
**Prioridad:** CRÍTICA - Requiere decisión antes de continuar desarrollo
|
|
|
|
---
|
|
|
|
## PROPÓSITO
|
|
|
|
Este documento lista las **decisiones arquitecturales críticas** que deben tomarse para resolver los problemas encontrados en la validación de integridad. Cada decisión está bloqueando funcionalidad o impidiendo el progreso de correcciones.
|
|
|
|
---
|
|
|
|
## DECISIONES CRÍTICAS (Bloquean desarrollo)
|
|
|
|
### D1. Sistema de Misiones - ¿Dónde ubicar la tabla missions?
|
|
|
|
**Problema:**
|
|
- Función `update_mission_progress` referencia `educational_content.missions`
|
|
- La tabla NO existe en educational_content
|
|
- Existe `gamification_system.missions` en archivos DDL
|
|
|
|
**Opciones:**
|
|
|
|
| Opción | Pros | Contras | Recomendación |
|
|
|--------|------|---------|---------------|
|
|
| **A) Crear en educational_content** | Misiones son contenido educativo | Duplica con gamification_system.missions | ❌ No recomendado |
|
|
| **B) Usar gamification_system.missions** | Ya existe en DDL | Función está en progress_tracking | ✅ **RECOMENDADO** |
|
|
| **C) Mover a progress_tracking** | Función está ahí | Misiones no son solo progreso | ⚠️ Considerar |
|
|
|
|
**Decisión recomendada:** **OPCIÓN B**
|
|
- Usar tabla existente `gamification_system.missions`
|
|
- Actualizar función para referenciar schema correcto
|
|
- Razón: Ya existe, schema correcto para misiones
|
|
|
|
**Acción requerida:**
|
|
```sql
|
|
-- En progress_tracking/functions/06-update_mission_progress.sql
|
|
-- Cambiar:
|
|
FROM educational_content.missions
|
|
-- Por:
|
|
FROM gamification_system.missions
|
|
```
|
|
|
|
---
|
|
|
|
### D2. Sistema de Inventario - ¿Modelo de datos?
|
|
|
|
**Problema:**
|
|
- 6 funciones referencian `user_inventory` y `store_items`
|
|
- Estas tablas NO existen
|
|
- Existe tabla `comodines_inventory`
|
|
|
|
**Opciones:**
|
|
|
|
| Opción | Pros | Contras | Esfuerzo |
|
|
|--------|------|---------|----------|
|
|
| **A) Crear user_inventory + store_items** | Separación de concerns | 2 tablas nuevas, más complejo | 8 horas |
|
|
| **B) Refactorizar a comodines_inventory** | Usa tabla existente | Funciones deben reescribirse | 6 horas |
|
|
| **C) Modelo híbrido** | Flexible | Más complejo mantener | 10 horas |
|
|
|
|
**Análisis de modelo A (Separación):**
|
|
|
|
```sql
|
|
-- Tabla de catálogo de items
|
|
CREATE TABLE gamification_system.store_items (
|
|
id UUID PRIMARY KEY,
|
|
item_type TEXT, -- 'comodin', 'powerup', 'cosmetic'
|
|
name TEXT,
|
|
description TEXT,
|
|
cost_ml_coins INTEGER,
|
|
metadata JSONB
|
|
);
|
|
|
|
-- Tabla de inventario de usuario
|
|
CREATE TABLE gamification_system.user_inventory (
|
|
id UUID PRIMARY KEY,
|
|
user_id UUID REFERENCES auth_management.profiles(id),
|
|
item_id UUID REFERENCES gamification_system.store_items(id),
|
|
quantity INTEGER,
|
|
acquired_at TIMESTAMPTZ
|
|
);
|
|
```
|
|
|
|
**Análisis de modelo B (Simplificado):**
|
|
|
|
```sql
|
|
-- Usar tabla existente
|
|
-- gamification_system.comodines_inventory ya tiene:
|
|
-- - user_id
|
|
-- - comodin_type (pistas, vision_lectora, segunda_oportunidad)
|
|
-- - quantity
|
|
-- - last_earned_at
|
|
|
|
-- Funciones deben adaptarse para:
|
|
-- 1. Usar comodin_type en lugar de item_id
|
|
-- 2. Trabajar directamente con inventory
|
|
```
|
|
|
|
**Decisión recomendada:** **OPCIÓN B (corto plazo) → OPCIÓN A (largo plazo)**
|
|
|
|
**Razón:**
|
|
- Corto plazo: Refactorizar funciones para usar `comodines_inventory` (menor esfuerzo, funciona YA)
|
|
- Largo plazo: Migrar a modelo completo cuando se agreguen items no-comodines
|
|
|
|
**Acción inmediata:**
|
|
1. Refactorizar 6 funciones para usar `comodines_inventory`
|
|
2. Documentar plan de migración a modelo completo en futuro
|
|
|
|
---
|
|
|
|
### D3. Tabla mechanic_progress - ¿Feature necesaria?
|
|
|
|
**Problema:**
|
|
- Función `check_mechanic_completion` referencia `progress_tracking.mechanic_progress`
|
|
- Tabla NO existe
|
|
- No hay otra referencia a "mechanics" en el sistema
|
|
|
|
**Opciones:**
|
|
|
|
| Opción | Pros | Contras | Recomendación |
|
|
|--------|------|---------|---------------|
|
|
| **A) Crear tabla + feature completa** | Sistema de progreso granular | Trabajo adicional sin spec clara | ❌ No ahora |
|
|
| **B) Eliminar función** | Simplifica código | Pierde feature potencial | ✅ **RECOMENDADO** |
|
|
| **C) Deprecar y documentar** | Mantiene para futuro | Código muerto | ⚠️ Alternativa |
|
|
|
|
**Decisión recomendada:** **OPCIÓN B**
|
|
|
|
**Razón:**
|
|
- No hay especificación de "mechanics" como concepto separado
|
|
- No hay tabla `educational_content.mechanics`
|
|
- Función no es llamada por ningún otro código
|
|
- Simplifica sistema sin perder funcionalidad documentada
|
|
|
|
**Acción requerida:**
|
|
```bash
|
|
# Mover a deprecated
|
|
mv apps/database/ddl/schemas/progress_tracking/functions/02-check_mechanic_completion.sql \
|
|
apps/database/ddl/schemas/progress_tracking/functions/_deprecated/
|
|
|
|
# Documentar en _deprecated/README.md por qué se eliminó
|
|
```
|
|
|
|
---
|
|
|
|
### D4. User Feature Flags - ¿Nivel de usuario o global?
|
|
|
|
**Problema:**
|
|
- Función `is_feature_enabled` referencia `system_configuration.user_feature_flags`
|
|
- Tabla NO existe
|
|
- Existe `system_configuration.feature_flags` (tabla global)
|
|
|
|
**Opciones:**
|
|
|
|
| Opción | Pros | Contras | Esfuerzo |
|
|
|--------|------|---------|----------|
|
|
| **A) Crear user_feature_flags** | Feature flags por usuario | Complejidad adicional | 4 horas |
|
|
| **B) Usar feature_flags global** | Usa tabla existente | No hay control por usuario | 1 hora |
|
|
| **C) Modelo híbrido (override)** | Flexible | Más complejo | 6 horas |
|
|
|
|
**Análisis:**
|
|
|
|
```sql
|
|
-- OPCIÓN A: Tabla nueva
|
|
CREATE TABLE system_configuration.user_feature_flags (
|
|
user_id UUID REFERENCES auth_management.profiles(id),
|
|
flag_key TEXT,
|
|
enabled BOOLEAN,
|
|
overrides_global BOOLEAN,
|
|
PRIMARY KEY (user_id, flag_key)
|
|
);
|
|
|
|
-- OPCIÓN B: Usar tabla existente
|
|
-- system_configuration.feature_flags tiene:
|
|
-- - key, enabled, target_roles, ...
|
|
-- Función verifica: flag_enabled AND user_role IN target_roles
|
|
|
|
-- OPCIÓN C: Híbrido
|
|
-- 1. Primero busca en user_feature_flags
|
|
-- 2. Si no existe, usa feature_flags global
|
|
-- 3. Permite overrides por usuario
|
|
```
|
|
|
|
**Decisión recomendada:** **OPCIÓN B (inmediato) → OPCIÓN C (futuro)**
|
|
|
|
**Razón:**
|
|
- Corto plazo: Tabla global es suficiente para MVP
|
|
- `target_roles` permite filtrado básico
|
|
- Largo plazo: Agregar overrides cuando se necesite A/B testing
|
|
|
|
**Acción inmediata:**
|
|
```sql
|
|
-- Actualizar función is_feature_enabled
|
|
CREATE OR REPLACE FUNCTION public.is_feature_enabled(flag_key TEXT)
|
|
RETURNS BOOLEAN AS $$
|
|
BEGIN
|
|
RETURN EXISTS (
|
|
SELECT 1 FROM system_configuration.feature_flags
|
|
WHERE key = flag_key
|
|
AND enabled = true
|
|
AND (target_roles IS NULL
|
|
OR gamilit.get_current_user_role() = ANY(target_roles))
|
|
);
|
|
END;
|
|
$$ LANGUAGE plpgsql STABLE;
|
|
```
|
|
|
|
---
|
|
|
|
### D5. Tabla maya_ranks (configuración) - ¿Estructura?
|
|
|
|
**Problema:**
|
|
- 3 funciones referencian `gamification_system.maya_ranks`
|
|
- Tabla NO existe (existe el ENUM maya_rank)
|
|
- Se necesita tabla de configuración con XP, perks, etc.
|
|
|
|
**Opciones:**
|
|
|
|
| Opción | Pros | Contras | Recomendación |
|
|
|--------|------|---------|---------------|
|
|
| **A) Tabla con configuración completa** | Flexible, extensible | Requiere seed data | ✅ **RECOMENDADO** |
|
|
| **B) Hardcodear en función** | Más simple | Difícil cambiar valores | ❌ No escalable |
|
|
| **C) JSONB en settings** | No requiere tabla | Menos estructurado | ⚠️ Alternativa |
|
|
|
|
**Decisión recomendada:** **OPCIÓN A**
|
|
|
|
**Estructura propuesta:**
|
|
|
|
```sql
|
|
CREATE TABLE gamification_system.maya_ranks (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
rank_name gamification_system.maya_rank NOT NULL UNIQUE,
|
|
rank_order INTEGER NOT NULL UNIQUE, -- 1-5
|
|
min_xp INTEGER NOT NULL,
|
|
max_xp INTEGER, -- NULL para último rango
|
|
description TEXT,
|
|
icon TEXT,
|
|
color TEXT, -- Para UI
|
|
perks JSONB, -- Beneficios del rango
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Seed data
|
|
INSERT INTO gamification_system.maya_ranks (rank_name, rank_order, min_xp, max_xp, description, icon, color, perks) VALUES
|
|
('Ajaw', 1, 0, 999, 'Nivel inicial del viaje maya', 'star', '#bronze', '{"xp_multiplier": 1.0}'::jsonb),
|
|
('Nacom', 2, 1000, 2999, 'Guerrero en entrenamiento', 'shield', '#silver', '{"xp_multiplier": 1.1, "ml_coins_bonus": 10}'::jsonb),
|
|
('Ah K''in', 3, 3000, 6999, 'Sacerdote del conocimiento', 'book', '#gold', '{"xp_multiplier": 1.2, "ml_coins_bonus": 20}'::jsonb),
|
|
('Halach Uinic', 4, 7000, 14999, 'Líder de la comunidad', 'crown', '#platinum', '{"xp_multiplier": 1.3, "ml_coins_bonus": 30, "unlock_exclusive_content": true}'::jsonb),
|
|
('K''uk''ulkan', 5, 15000, NULL, 'Máximo rango maya', 'dragon', '#diamond', '{"xp_multiplier": 1.5, "ml_coins_bonus": 50, "all_perks": true}'::jsonb);
|
|
```
|
|
|
|
**Acción requerida:**
|
|
1. Crear archivo DDL: `gamification_system/tables/10-maya_ranks.sql`
|
|
2. Crear seed: `gamification_system/seeds/maya_ranks.sql`
|
|
3. Actualizar 3 funciones que la referencian
|
|
|
|
---
|
|
|
|
### D6. Tabla user_activity_log vs user_activity_logs
|
|
|
|
**Problema:**
|
|
- Función `cleanup_old_user_activity` referencia `audit_logging.user_activity_log` (singular)
|
|
- Existe `audit_logging.user_activity_logs` (plural)
|
|
- ¿Es typo o tabla diferente?
|
|
|
|
**Opciones:**
|
|
|
|
| Opción | Pros | Contras | Recomendación |
|
|
|--------|------|---------|---------------|
|
|
| **A) Es typo, usar _logs** | Usa tabla existente | - | ✅ **RECOMENDADO** |
|
|
| **B) Son tablas diferentes** | - | ¿Por qué 2 tablas? | ❌ Poco probable |
|
|
|
|
**Decisión recomendada:** **OPCIÓN A** (es un typo)
|
|
|
|
**Acción requerida:**
|
|
```sql
|
|
-- Actualizar función
|
|
-- Cambiar: audit_logging.user_activity_log
|
|
-- Por: audit_logging.user_activity_logs
|
|
```
|
|
|
|
---
|
|
|
|
### D7. Notificaciones - ¿Dónde está la tabla?
|
|
|
|
**Problema:**
|
|
- Función `send_notification` referencia `social_features.notifications`
|
|
- Tabla NO existe en social_features
|
|
- Existe `gamification_system.notifications`
|
|
|
|
**Opciones:**
|
|
|
|
| Opción | Pros | Contras | Recomendación |
|
|
|--------|------|---------|---------------|
|
|
| **A) Mover a social_features** | Función lo espera ahí | Notificaciones no son solo sociales | ❌ |
|
|
| **B) Usar gamification_system** | Ubicación correcta actual | Función debe actualizarse | ✅ **RECOMENDADO** |
|
|
| **C) Duplicar tabla** | - | Horrible idea | ❌ Nunca |
|
|
|
|
**Decisión recomendada:** **OPCIÓN B**
|
|
|
|
**Razón:**
|
|
- Notificaciones son parte de gamificación (achievements, coins, etc.)
|
|
- Schema correcto: gamification_system
|
|
- Función debe actualizarse
|
|
|
|
**Acción requerida:**
|
|
```sql
|
|
-- Actualizar función send_notification
|
|
-- Cambiar: social_features.notifications
|
|
-- Por: gamification_system.notifications
|
|
```
|
|
|
|
---
|
|
|
|
## DECISIONES SECUNDARIAS (No bloquean)
|
|
|
|
### D8. ENUMs en prerequisites vs archivos individuales
|
|
|
|
**Problema:** ENUMs definidos en 2 lugares
|
|
|
|
**Decisión:** Eliminar de prerequisites, usar solo archivos individuales
|
|
|
|
**Razón:** Fuente de verdad única por schema
|
|
|
|
---
|
|
|
|
### D9. notification_type en public vs gamification_system
|
|
|
|
**Problema:** ENUM en schema incorrecto
|
|
|
|
**Decisión:** Migrar a gamification_system en fase P1 de ENUMs
|
|
|
|
**Razón:** Consistencia arquitectural
|
|
|
|
---
|
|
|
|
## RESUMEN DE DECISIONES
|
|
|
|
| ID | Decisión | Recomendación | Prioridad | Esfuerzo |
|
|
|----|----------|---------------|-----------|----------|
|
|
| D1 | Ubicación missions | Usar gamification_system.missions | 🔴 CRÍTICA | 30 min |
|
|
| D2 | Modelo inventario | Refactorizar a comodines_inventory | 🔴 CRÍTICA | 6 horas |
|
|
| D3 | mechanic_progress | Eliminar feature | 🔴 CRÍTICA | 30 min |
|
|
| D4 | User feature flags | Usar tabla global feature_flags | 🔴 CRÍTICA | 1 hora |
|
|
| D5 | maya_ranks config | Crear tabla con seed data | 🟠 ALTA | 2 horas |
|
|
| D6 | user_activity_log | Corregir typo a _logs | 🔴 CRÍTICA | 10 min |
|
|
| D7 | Ubicación notifications | Usar gamification_system | 🔴 CRÍTICA | 10 min |
|
|
| D8 | ENUMs duplicados | Eliminar de prerequisites | 🟡 MEDIA | 30 min |
|
|
| D9 | notification_type schema | Migrar en fase P1 | 🟡 MEDIA | 1 hora |
|
|
|
|
**Total esfuerzo estimado (decisiones críticas):** ~11 horas
|
|
|
|
---
|
|
|
|
## PRÓXIMOS PASOS
|
|
|
|
1. **Revisar y aprobar decisiones** (30 min - Equipo)
|
|
2. **Implementar decisiones críticas** (1 día)
|
|
3. **Testing de funciones actualizadas** (2 horas)
|
|
4. **Actualizar documentación** (1 hora)
|
|
5. **Continuar con plan P1 de migración ENUMs**
|
|
|
|
---
|
|
|
|
**Documento preparado por:** Sistema de Validación
|
|
**Requiere aprobación de:** Arquitecto de BD / Tech Lead
|
|
**Fecha límite decisión:** ASAP (bloquea desarrollo)
|