Multi-project update: gamilit, orchestration, trading-platform
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>
This commit is contained in:
rckrdmrd 2025-12-18 07:17:46 -06:00
parent e360b88612
commit 608e1e2a2e
503 changed files with 81416 additions and 7498 deletions

View File

@ -0,0 +1,313 @@
# DIRECTIVA: DOCUMENTACION DEFINITIVA
**Version:** 1.0.0
**Fecha:** 2025-12-18
**Nivel:** CORE
**Tipo:** Directiva Fundamental - OBLIGATORIA
**Alias:** @DOC-DEFINITIVA
**Aplica a:** TODOS los agentes y subagentes en TODOS los niveles
---
## DECLARACION DE LA DIRECTIVA
```
+==============================================================================+
| |
| LA DOCUMENTACION ES EL ESTADO FINAL DEL SISTEMA |
| |
| "docs/ refleja SIEMPRE el estado actual, nunca el historico." |
| "Si algo cambio, la documentacion refleja el RESULTADO, no el cambio." |
| "Los cambios, correcciones e historicos van en orchestration/." |
| |
+==============================================================================+
```
---
## PRINCIPIO FUNDAMENTAL
### La Documentacion como Espejo del Sistema
```yaml
Principio:
docs/:
- Contiene SOLO estado actual y definitivo
- Es un "espejo" de lo que existe implementado
- NO contiene historico de cambios
- NO contiene correcciones pendientes
- NO contiene discrepancias o gaps
orchestration/:
- Contiene planes, analisis, correcciones
- Contiene historico de cambios
- Contiene reportes de implementacion
- Contiene trazas de tareas
- Contiene documentacion de proceso
Razon:
- Onboarding rapido (docs/ = estado actual)
- Sin confusion entre "lo que es" vs "lo que fue"
- SSOT (Single Source of Truth) para el estado del sistema
```
---
## ESTRUCTURA DE DOCUMENTACION (Patron Universal)
### docs/ - Estado Definitivo
```
docs/
├── 00-vision-general/ # Vision y proposito (definitivo)
│ └── directivas/ # Directivas especificas del proyecto
├── 01-fase-*/ # Especificaciones por fase (definitivo)
├── 90-transversal/ # Documentacion cross-cutting (definitivo)
│ ├── arquitectura/ # Arquitectura actual
│ ├── features/ # Features implementadas
│ └── correcciones/ # SOLO backlog activo
├── 95-guias-desarrollo/ # Guias de desarrollo (definitivo)
├── 96-quick-reference/ # Referencias rapidas (definitivo)
└── 97-adr/ # Decisiones arquitectonicas (definitivo)
```
### orchestration/ - Proceso y Cambios
```
orchestration/
├── 00-guidelines/ # Contexto del proyecto
│ ├── CONTEXTO-PROYECTO.md
│ ├── HERENCIA-SIMCO.md
│ └── HERENCIA-DIRECTIVAS.md
├── inventarios/ # SSOT de componentes
├── reportes/ # Historico de cambios
│ ├── historicos/ # Reportes por fecha
│ ├── correcciones/ # Correcciones aplicadas
│ ├── implementacion/ # Reportes de desarrollo
│ └── gaps/ # Gaps identificados/cerrados
├── trazas/ # Trazas de tareas
├── analisis/ # Analisis y planes
└── directivas/ # Directivas de proceso (opcionales)
```
---
## REGLAS DE ACTUALIZACION
### Al Completar una Tarea (Fase D de CAPVED)
```yaml
Actualizacion_Obligatoria:
Durante_Ejecucion:
# Cuando implementas un cambio:
- Actualizar documentacion en docs/ como estado FINAL
- NO escribir "se corrigio X" o "se cambio de Y a Z"
- SI escribir el estado actual resultante
Al_Finalizar:
# Cuando terminas la tarea:
- Verificar que docs/ refleja estado actual
- Generar reporte en orchestration/reportes/ con historico
- Actualizar inventarios con metricas actuales
```
### Ejemplo de Actualizacion Correcta
```yaml
Situacion: "Se corrigio el numero de schemas de 14 a 16"
INCORRECTO_en_docs/:
texto: "Actualizado: Antes habia 14 schemas, ahora hay 16"
razon: "Esto es historico, no estado actual"
CORRECTO_en_docs/:
texto: "Total schemas: 16"
razon: "Solo estado actual, sin referencia a lo anterior"
CORRECTO_en_orchestration/:
archivo: "orchestration/reportes/correcciones/CORRECCION-{fecha}.md"
contenido: |
## Correccion de Metricas
- Antes: 14 schemas
- Despues: 16 schemas
- Archivos actualizados: [lista]
```
---
## SEPARACION DE CONTENIDO
### Que VA en docs/
```yaml
Contenido_Definitivo:
- Especificaciones tecnicas actuales
- Arquitectura actual del sistema
- Guias de desarrollo vigentes
- Referencias rapidas actualizadas
- ADRs (decisiones arquitectonicas)
- Features implementadas (estado actual)
- Backlog activo (issues pendientes)
- Directivas especificas del proyecto
Formato:
- Siempre en presente o futuro
- Sin referencias a "antes" o "se cambio"
- Metricas siempre actuales
- Fechas de ultima actualizacion (no de creacion)
```
### Que VA en orchestration/
```yaml
Contenido_de_Proceso:
- Planes de implementacion
- Reportes de analisis
- Historico de correcciones
- Trazas de tareas completadas
- Reportes por fecha
- Gaps identificados y cerrados
- Lecciones aprendidas
- Contexto y herencia del proyecto
Formato:
- Puede incluir "antes/despues"
- Incluye fechas de ejecucion
- Incluye contexto de cambios
- Incluye metricas historicas
```
---
## SSOT (Single Source of Truth)
### Inventarios como SSOT
```yaml
SSOT_para_Metricas:
archivo: "orchestration/inventarios/MASTER_INVENTORY.yml"
contiene:
- Metricas de database (schemas, tablas, etc.)
- Metricas de backend (modulos, endpoints, etc.)
- Metricas de frontend (componentes, hooks, etc.)
Regla:
- TODA documentacion que cite metricas debe referenciar este archivo
- O debe ser actualizada cuando este archivo cambie
- NO duplicar valores, referenciar SSOT
```
### Actualizacion de Referencias
```yaml
Cuando_cambia_SSOT:
1. Actualizar MASTER_INVENTORY.yml
2. Actualizar docs/ que citan las metricas
3. Generar reporte en orchestration/reportes/
Archivos_tipicos_que_citan_metricas:
- docs/README.md
- docs/95-guias-desarrollo/README.md
- docs/96-quick-reference/*.md
- orchestration/00-guidelines/CONTEXTO-PROYECTO.md
```
---
## TRAZABILIDAD DE DOCUMENTACION DEPRECADA
### Cuando se Mueve Documentacion
```yaml
Proceso:
1. Mover archivo de docs/ a orchestration/reportes/
2. Registrar en TRAZA-DOCUMENTACION-DEPRECADA.md
3. Actualizar referencias en documentos vigentes
4. Actualizar _MAP.md correspondiente
Archivo_de_Traza:
ubicacion: "orchestration/trazas/TRAZA-DOCUMENTACION-DEPRECADA.md"
contenido:
- Ubicacion original
- Nueva ubicacion
- Fecha de movimiento
- Razon del movimiento
- Referencias actualizadas
```
---
## CHECKLIST DE DOCUMENTACION
### Al Finalizar Cada Tarea
```
DOCUMENTACION DEFINITIVA (docs/)
[ ] docs/ refleja estado actual (no historico)
[ ] Metricas estan actualizadas
[ ] No hay referencias a "antes" o "se cambio"
[ ] Fechas de ultima actualizacion correctas
DOCUMENTACION DE PROCESO (orchestration/)
[ ] Reporte de tarea en orchestration/reportes/
[ ] Traza actualizada si aplica
[ ] Inventarios actualizados
[ ] Historico documentado
TRAZABILIDAD
[ ] MASTER_INVENTORY.yml actualizado
[ ] Referencias cruzadas actualizadas
[ ] Sin enlaces rotos
```
---
## INTEGRACION CON CAPVED
Esta directiva se ejecuta principalmente en la **Fase D (Documentacion)** del ciclo CAPVED:
```yaml
Fase_D_Documentacion:
durante:
- Actualizar docs/ como estado FINAL
- NO escribir historico de cambios
despues:
- Generar reporte en orchestration/reportes/
- Actualizar inventarios
- Registrar traza si aplica
```
---
## APLICACION POR NIVEL
Esta directiva aplica a TODOS los niveles del workspace:
| Nivel | Ubicacion docs/ | Ubicacion orchestration/ |
|-------|-----------------|--------------------------|
| WORKSPACE | N/A | workspace/orchestration/ |
| CORE | N/A | core/orchestration/ |
| STANDALONE | projects/{p}/docs/ | projects/{p}/orchestration/ |
| SUITE | projects/{s}/docs/ | projects/{s}/orchestration/ |
| VERTICAL | .../verticales/{v}/docs/ | .../verticales/{v}/orchestration/ |
---
## REFERENCIAS
| Documento | Alias | Proposito |
|-----------|-------|-----------|
| PRINCIPIO-DOC-PRIMERO.md | @DOC-PRIMERO | Documentar antes de implementar |
| PRINCIPIO-CAPVED.md | @CAPVED | Ciclo de vida de tareas |
| SIMCO-DOCUMENTAR.md | @DOCUMENTAR | Proceso detallado de documentacion |
| INDICE-DIRECTIVAS-WORKSPACE.yml | @INDICE | Indice maestro de directivas |
---
**Esta directiva es OBLIGATORIA y define como documentar el sistema en TODOS los niveles.**
---
**Version:** 1.0.0 | **Nivel:** CORE | **Sistema:** SIMCO v2.3.0

View File

@ -0,0 +1,336 @@
# INDICE MAESTRO DE DIRECTIVAS DEL WORKSPACE
# ============================================
# Este archivo es el SSOT para todas las directivas disponibles
# Consultar antes de cargar directivas en cualquier nivel
version: "1.0.0"
fecha_actualizacion: "2025-12-18"
descripcion: "Indice maestro de todas las directivas del workspace"
# ============================================
# NIVELES Y SUS DIRECTIVAS
# ============================================
niveles:
# ------------------------------------------
# NIVEL 0: WORKSPACE
# ------------------------------------------
WORKSPACE:
ruta_base: "/home/isem/workspace"
descripcion: "Coordinacion global de todos los proyectos"
directivas:
- archivo: "orchestration/directivas/DIRECTIVA-CARGA-CONTEXTO.md"
alias: "@CARGA-CONTEXTO"
tipo: "proceso"
obligatoria: true
descripcion: "Como cargar contexto segun nivel de trabajo"
# ------------------------------------------
# NIVEL 1: CORE
# ------------------------------------------
CORE:
ruta_base: "/home/isem/workspace/core"
descripcion: "Infraestructura compartida - directivas SIMCO"
principios:
- archivo: "orchestration/directivas/principios/PRINCIPIO-CAPVED.md"
alias: "@CAPVED"
obligatoria: true
descripcion: "Ciclo de vida de tareas (6 fases)"
- archivo: "orchestration/directivas/principios/PRINCIPIO-DOC-PRIMERO.md"
alias: "@DOC-PRIMERO"
obligatoria: true
descripcion: "Documentar antes de implementar"
- archivo: "orchestration/directivas/principios/PRINCIPIO-ANTI-DUPLICACION.md"
alias: "@ANTI-DUP"
obligatoria: true
descripcion: "Verificar catalogo antes de crear"
- archivo: "orchestration/directivas/principios/PRINCIPIO-VALIDACION-OBLIGATORIA.md"
alias: "@VALIDAR"
obligatoria: true
descripcion: "Build/lint obligatorios"
- archivo: "orchestration/directivas/principios/PRINCIPIO-ECONOMIA-TOKENS.md"
alias: "@ECONOMIA"
obligatoria: false
descripcion: "Optimizar uso de tokens"
- archivo: "orchestration/directivas/principios/PRINCIPIO-NO-ASUMIR.md"
alias: "@NO-ASUMIR"
obligatoria: false
descripcion: "Verificar antes de asumir"
operaciones_simco:
- archivo: "orchestration/directivas/simco/SIMCO-TAREA.md"
alias: "@TAREA"
obligatoria: true
descripcion: "Proceso completo para HU/tareas"
- archivo: "orchestration/directivas/simco/SIMCO-INICIALIZACION.md"
alias: "@INIT"
obligatoria: false
descripcion: "Protocolo CCA de inicializacion"
- archivo: "orchestration/directivas/simco/SIMCO-CREAR.md"
alias: "@CREAR"
obligatoria: false
descripcion: "Crear nuevos componentes"
- archivo: "orchestration/directivas/simco/SIMCO-MODIFICAR.md"
alias: "@MODIFICAR"
obligatoria: false
descripcion: "Modificar componentes existentes"
- archivo: "orchestration/directivas/simco/SIMCO-VALIDAR.md"
alias: "@VALIDAR-OP"
obligatoria: false
descripcion: "Validar implementaciones"
- archivo: "orchestration/directivas/simco/SIMCO-DOCUMENTAR.md"
alias: "@DOCUMENTAR"
obligatoria: false
descripcion: "Documentar cambios"
- archivo: "orchestration/directivas/simco/SIMCO-BUSCAR.md"
alias: "@BUSCAR"
obligatoria: false
descripcion: "Buscar en codebase"
- archivo: "orchestration/directivas/simco/SIMCO-DELEGACION.md"
alias: "@DELEGAR"
obligatoria: false
descripcion: "Delegar a subagentes"
operaciones_dominio:
- archivo: "orchestration/directivas/simco/SIMCO-DDL.md"
alias: "@OP_DDL"
dominio: "database"
descripcion: "Operaciones PostgreSQL"
- archivo: "orchestration/directivas/simco/SIMCO-BACKEND.md"
alias: "@OP_BACKEND"
dominio: "backend"
descripcion: "Operaciones NestJS/Express"
- archivo: "orchestration/directivas/simco/SIMCO-FRONTEND.md"
alias: "@OP_FRONTEND"
dominio: "frontend"
descripcion: "Operaciones React"
- archivo: "orchestration/directivas/simco/SIMCO-MOBILE.md"
alias: "@OP_MOBILE"
dominio: "mobile"
descripcion: "Operaciones React Native"
- archivo: "orchestration/directivas/simco/SIMCO-ML.md"
alias: "@OP_ML"
dominio: "ml"
descripcion: "Operaciones ML/AI"
documentacion:
- archivo: "orchestration/directivas/DIRECTIVA-DOCUMENTACION-DEFINITIVA.md"
alias: "@DOC-DEFINITIVA"
obligatoria: true
descripcion: "Docs como estado final del sistema"
catalogo:
- archivo: "catalog/CATALOG-INDEX.yml"
alias: "@CATALOG"
descripcion: "Indice de funcionalidades reutilizables"
# ------------------------------------------
# NIVEL 2A: PROYECTOS STANDALONE
# ------------------------------------------
STANDALONE:
patron_ruta: "/home/isem/workspace/projects/{proyecto}"
descripcion: "Proyectos autonomos sin subproyectos"
directivas_obligatorias:
- archivo: "orchestration/00-guidelines/CONTEXTO-PROYECTO.md"
descripcion: "Variables de contexto del proyecto"
- archivo: "orchestration/00-guidelines/HERENCIA-SIMCO.md"
descripcion: "Define herencia de directivas SIMCO"
directivas_opcionales:
- patron: "docs/00-vision-general/directivas/*.md"
descripcion: "Directivas especificas del proyecto"
- patron: "orchestration/directivas/*.md"
descripcion: "Directivas de proceso del proyecto"
proyectos:
- nombre: "gamilit"
descripcion: "Plataforma educativa gamificada"
tiene_docs: true
tiene_orchestration: true
- nombre: "trading-platform"
descripcion: "Plataforma de trading"
tiene_docs: true
tiene_orchestration: true
- nombre: "betting-analytics"
descripcion: "Analytics de apuestas"
tiene_docs: true
tiene_orchestration: true
- nombre: "inmobiliaria-analytics"
descripcion: "Analytics inmobiliaria"
tiene_docs: true
tiene_orchestration: true
- nombre: "platform_marketing_content"
descripcion: "Contenido de marketing"
tiene_docs: true
tiene_orchestration: true
# ------------------------------------------
# NIVEL 2B: SUITE (erp-suite)
# ------------------------------------------
SUITE:
ruta_base: "/home/isem/workspace/projects/erp-suite"
descripcion: "Suite multi-vertical con codigo compartido"
directivas_obligatorias:
- archivo: "orchestration/00-guidelines/CONTEXTO-PROYECTO.md"
- archivo: "orchestration/00-guidelines/HERENCIA-SIMCO.md"
subniveles:
SUITE-CORE:
ruta: "apps/erp-core"
descripcion: "Base de codigo compartida (60-70%)"
hereda_de: ["SUITE"]
directivas_adicionales:
- archivo: "orchestration/00-guidelines/HERENCIA-SPECS-CORE.md"
VERTICALES:
patron_ruta: "apps/verticales/{vertical}"
descripcion: "Verticales especializadas"
hereda_de: ["SUITE", "SUITE-CORE"]
directivas_adicionales:
- archivo: "orchestration/00-guidelines/HERENCIA-ERP-CORE.md"
- archivo: "orchestration/00-guidelines/HERENCIA-SPECS-ERP-CORE.md"
verticales:
- nombre: "clinicas"
descripcion: "ERP para clinicas"
- nombre: "construccion"
descripcion: "ERP para construccion"
- nombre: "mecanicas-diesel"
descripcion: "ERP para mecanicas diesel"
- nombre: "retail"
descripcion: "ERP para retail"
- nombre: "vidrio-templado"
descripcion: "ERP para vidrio templado"
SUITE-SERVICE:
ruta: "apps/saas"
descripcion: "Servicios transversales"
hereda_de: ["SUITE"]
SUITE-PRODUCT:
patron_ruta: "apps/products/{producto}"
descripcion: "Productos derivados"
hereda_de: ["SUITE", "SUITE-CORE"]
productos:
- nombre: "erp-basico"
- nombre: "pos-micro"
# ============================================
# CADENAS DE HERENCIA
# ============================================
cadenas_herencia:
STANDALONE:
orden:
- nivel: "WORKSPACE"
directivas: ["@CARGA-CONTEXTO"]
- nivel: "CORE"
directivas: ["@CAPVED", "@DOC-PRIMERO", "@TAREA", "@DOC-DEFINITIVA"]
- nivel: "PROYECTO"
directivas: ["CONTEXTO-PROYECTO.md", "HERENCIA-SIMCO.md"]
SUITE:
orden:
- nivel: "WORKSPACE"
directivas: ["@CARGA-CONTEXTO"]
- nivel: "CORE"
directivas: ["@CAPVED", "@DOC-PRIMERO", "@TAREA", "@DOC-DEFINITIVA"]
- nivel: "SUITE"
directivas: ["CONTEXTO-PROYECTO.md", "HERENCIA-SIMCO.md"]
SUITE-CORE:
orden:
- nivel: "WORKSPACE"
directivas: ["@CARGA-CONTEXTO"]
- nivel: "CORE"
directivas: ["@CAPVED", "@DOC-PRIMERO", "@TAREA", "@DOC-DEFINITIVA"]
- nivel: "SUITE"
directivas: ["CONTEXTO-PROYECTO.md"]
- nivel: "SUITE-CORE"
directivas: ["HERENCIA-SIMCO.md", "HERENCIA-SPECS-CORE.md"]
VERTICAL:
orden:
- nivel: "WORKSPACE"
directivas: ["@CARGA-CONTEXTO"]
- nivel: "CORE"
directivas: ["@CAPVED", "@DOC-PRIMERO", "@TAREA", "@DOC-DEFINITIVA"]
- nivel: "SUITE"
directivas: ["CONTEXTO-PROYECTO.md"]
- nivel: "SUITE-CORE"
directivas: ["HERENCIA-SPECS-CORE.md"]
- nivel: "VERTICAL"
directivas: ["HERENCIA-SIMCO.md", "HERENCIA-ERP-CORE.md"]
# ============================================
# ALIASES GLOBALES
# ============================================
aliases:
# Principios
"@CAPVED": "core/orchestration/directivas/principios/PRINCIPIO-CAPVED.md"
"@DOC-PRIMERO": "core/orchestration/directivas/principios/PRINCIPIO-DOC-PRIMERO.md"
"@ANTI-DUP": "core/orchestration/directivas/principios/PRINCIPIO-ANTI-DUPLICACION.md"
"@VALIDAR": "core/orchestration/directivas/principios/PRINCIPIO-VALIDACION-OBLIGATORIA.md"
# Operaciones
"@TAREA": "core/orchestration/directivas/simco/SIMCO-TAREA.md"
"@CREAR": "core/orchestration/directivas/simco/SIMCO-CREAR.md"
"@MODIFICAR": "core/orchestration/directivas/simco/SIMCO-MODIFICAR.md"
"@BUSCAR": "core/orchestration/directivas/simco/SIMCO-BUSCAR.md"
"@DELEGAR": "core/orchestration/directivas/simco/SIMCO-DELEGACION.md"
# Dominios
"@OP_DDL": "core/orchestration/directivas/simco/SIMCO-DDL.md"
"@OP_BACKEND": "core/orchestration/directivas/simco/SIMCO-BACKEND.md"
"@OP_FRONTEND": "core/orchestration/directivas/simco/SIMCO-FRONTEND.md"
# Documentacion
"@DOC-DEFINITIVA": "core/orchestration/directivas/DIRECTIVA-DOCUMENTACION-DEFINITIVA.md"
# Workspace
"@CARGA-CONTEXTO": "orchestration/directivas/DIRECTIVA-CARGA-CONTEXTO.md"
"@INDICE": "orchestration/INDICE-DIRECTIVAS-WORKSPACE.yml"
# Catalogo
"@CATALOG": "core/catalog/CATALOG-INDEX.yml"
# ============================================
# METADATA
# ============================================
metadata:
total_niveles: 7
total_proyectos_standalone: 5
total_verticales: 5
total_directivas_core: 28
sistema_simco_version: "2.3.0"
ultima_actualizacion: "2025-12-18"
mantenido_por: "Requirements-Analyst"

View File

@ -0,0 +1,268 @@
# DIRECTIVA: CARGA DE CONTEXTO SEGUN NIVEL
**Version:** 1.0.0
**Fecha:** 2025-12-18
**Nivel:** WORKSPACE
**Tipo:** Directiva Fundamental - OBLIGATORIA
**Aplica a:** TODOS los agentes y subagentes
---
## PROPOSITO
Esta directiva define **COMO** cargar las directivas correctas segun el nivel de trabajo especificado en el prompt.
---
## PASO 1: IDENTIFICAR NIVEL DE TRABAJO
Cuando recibas un prompt con:
- **proyecto:** {nombre}
- **subproyecto:** {nombre} (opcional)
- **tarea:** {descripcion}
Determinar el nivel segun esta tabla:
| Si proyecto es... | Y subproyecto es... | Entonces nivel es... |
|-------------------|---------------------|----------------------|
| gamilit, trading-platform, betting-analytics, inmobiliaria-analytics | null | **STANDALONE** |
| erp-suite | null | **SUITE** |
| erp-suite | erp-core | **SUITE-CORE** |
| erp-suite | verticales/{nombre} | **VERTICAL** |
| erp-suite | saas | **SUITE-SERVICE** |
| erp-suite | products/{nombre} | **SUITE-PRODUCT** |
---
## PASO 2: OBTENER CADENA DE HERENCIA
Segun el nivel identificado, cargar directivas en este orden:
### STANDALONE
```
1. WORKSPACE → workspace/orchestration/directivas/
2. CORE → core/orchestration/directivas/principios/
3. CORE → core/orchestration/directivas/simco/
4. PROYECTO → projects/{proyecto}/orchestration/00-guidelines/
5. PROYECTO → projects/{proyecto}/docs/00-vision-general/directivas/
```
### SUITE
```
1. WORKSPACE → workspace/orchestration/directivas/
2. CORE → core/orchestration/directivas/principios/
3. CORE → core/orchestration/directivas/simco/
4. SUITE → projects/erp-suite/orchestration/00-guidelines/
5. SUITE → projects/erp-suite/docs/00-vision-general/directivas/
```
### SUITE-CORE
```
1. WORKSPACE → workspace/orchestration/directivas/
2. CORE → core/orchestration/directivas/principios/
3. CORE → core/orchestration/directivas/simco/
4. SUITE → projects/erp-suite/orchestration/00-guidelines/
5. SUITE-CORE → projects/erp-suite/apps/erp-core/orchestration/00-guidelines/
6. SUITE-CORE → projects/erp-suite/apps/erp-core/docs/00-vision-general/directivas/
```
### VERTICAL
```
1. WORKSPACE → workspace/orchestration/directivas/
2. CORE → core/orchestration/directivas/principios/
3. CORE → core/orchestration/directivas/simco/
4. SUITE → projects/erp-suite/orchestration/00-guidelines/
5. SUITE-CORE → projects/erp-suite/apps/erp-core/orchestration/00-guidelines/
6. VERTICAL → projects/erp-suite/apps/verticales/{vertical}/orchestration/00-guidelines/
7. VERTICAL → projects/erp-suite/apps/verticales/{vertical}/docs/00-vision-general/directivas/
```
---
## PASO 3: CARGAR DIRECTIVAS OBLIGATORIAS
### Desde CORE (Siempre obligatorias)
```yaml
Principios_Obligatorios:
- core/orchestration/directivas/principios/PRINCIPIO-CAPVED.md
- core/orchestration/directivas/principios/PRINCIPIO-DOC-PRIMERO.md
- core/orchestration/directivas/principios/PRINCIPIO-ANTI-DUPLICACION.md
- core/orchestration/directivas/principios/PRINCIPIO-VALIDACION-OBLIGATORIA.md
Operacion_Principal:
- core/orchestration/directivas/simco/SIMCO-TAREA.md
Documentacion:
- core/orchestration/directivas/DIRECTIVA-DOCUMENTACION-DEFINITIVA.md
```
### Desde PROYECTO (Siempre obligatorias)
```yaml
Contexto:
- {proyecto}/orchestration/00-guidelines/CONTEXTO-PROYECTO.md
- {proyecto}/orchestration/00-guidelines/HERENCIA-SIMCO.md
```
### Segun Operacion (Cargar si aplica)
```yaml
Si_operacion_es_DDL:
- core/orchestration/directivas/simco/SIMCO-DDL.md
Si_operacion_es_BACKEND:
- core/orchestration/directivas/simco/SIMCO-BACKEND.md
Si_operacion_es_FRONTEND:
- core/orchestration/directivas/simco/SIMCO-FRONTEND.md
Si_operacion_es_CREAR:
- core/orchestration/directivas/simco/SIMCO-CREAR.md
Si_operacion_es_MODIFICAR:
- core/orchestration/directivas/simco/SIMCO-MODIFICAR.md
```
---
## PASO 4: RESOLVER CONTEXTO DEL PROYECTO
Leer `CONTEXTO-PROYECTO.md` del nivel mas especifico y obtener:
```yaml
Variables_a_Resolver:
PROJECT: "{nombre del proyecto}"
PROJECT_LEVEL: "{STANDALONE | SUITE | VERTICAL | etc}"
DB_NAME: "{nombre de la base de datos}"
DB_DDL_PATH: "{ruta a DDL}"
BACKEND_ROOT: "{ruta a backend}"
FRONTEND_ROOT: "{ruta a frontend}"
```
---
## PASO 5: CONFIRMAR CARGA
Antes de proceder con la tarea, generar confirmacion:
```yaml
Confirmacion_Carga:
nivel_identificado: "{NIVEL}"
proyecto: "{nombre}"
subproyecto: "{nombre o null}"
directivas_cargadas:
workspace: [lista]
core_principios: [lista]
core_simco: [lista]
proyecto: [lista]
especificas: [lista]
contexto_resuelto:
PROJECT: "{valor}"
DB_DDL_PATH: "{valor}"
BACKEND_ROOT: "{valor}"
FRONTEND_ROOT: "{valor}"
estado: "READY_TO_EXECUTE"
```
---
## PASO 6: EJECUTAR CICLO CAPVED
Una vez confirmada la carga, seguir el ciclo CAPVED:
```
C - Contexto: ✓ Completado en pasos 1-5
A - Analisis: Analizar alcance e impacto de la tarea
P - Planeacion: Crear plan de implementacion
V - Validacion: Validar plan vs analisis (NO DELEGAR)
E - Ejecucion: Implementar en orden planificado
D - Documentacion: Actualizar docs/ como estado FINAL
```
---
## DELEGACION A SUBAGENTES
Cuando delegues a un subagente, incluir en el prompt:
```markdown
## Contexto para Subagente
**Proyecto:** {nombre}
**Subproyecto:** {nombre o null}
**Nivel:** {STANDALONE | SUITE | VERTICAL | etc}
**Directivas Cargadas:**
- {lista de directivas ya cargadas}
**Contexto Resuelto:**
- PROJECT: {valor}
- DB_DDL_PATH: {valor}
- BACKEND_ROOT: {valor}
**Tarea Especifica:** {descripcion de subtarea}
**Restricciones:**
- Seguir principio CAPVED
- Documentar como estado FINAL (no historico)
- Reportar hallazgos al agente principal
```
---
## CONSULTAR INDICE MAESTRO
Para ver todas las directivas disponibles:
```
Archivo: /home/isem/workspace/orchestration/INDICE-DIRECTIVAS-WORKSPACE.yml
```
Este archivo contiene:
- Todas las directivas por nivel
- Aliases (@CAPVED, @TAREA, etc.)
- Cadenas de herencia
- Proyectos y subproyectos disponibles
---
## ERRORES COMUNES
### Error: No se identifica el nivel
```
Solucion: Verificar que proyecto y subproyecto estan correctamente especificados
```
### Error: Directiva no encontrada
```
Solucion: Consultar INDICE-DIRECTIVAS-WORKSPACE.yml para rutas correctas
```
### Error: Contexto no resuelto
```
Solucion: Verificar que CONTEXTO-PROYECTO.md existe en el nivel especificado
```
---
## REFERENCIAS
| Documento | Alias | Proposito |
|-----------|-------|-----------|
| PRINCIPIO-CAPVED.md | @CAPVED | Ciclo de vida de tareas |
| PRINCIPIO-DOC-PRIMERO.md | @DOC-PRIMERO | Documentar antes de implementar |
| SIMCO-TAREA.md | @TAREA | Proceso detallado de tareas |
| DIRECTIVA-DOCUMENTACION-DEFINITIVA.md | @DOC-DEFINITIVA | Docs como estado final |
| INDICE-DIRECTIVAS-WORKSPACE.yml | @INDICE | Indice maestro |
---
**Esta directiva es OBLIGATORIA para todo agente y subagente.**
---
**Version:** 1.0.0 | **Nivel:** WORKSPACE | **Sistema:** SIMCO v2.3.0

View File

@ -1,5 +1,216 @@
# CHANGELOG - Plataforma GAMILIT
## [2.4.2] - 2025-12-15
### Simplificación de Estructura Social - Solo Defaults
Esta versión simplifica completamente la estructura de `social_features` eliminando todas las entidades demo y dejando únicamente las entidades default del sistema.
**Tech-Leader:** Claude Opus 4.5
**Tarea:** Simplificación de estructura de base de datos
---
### Cambios Mayores
| Archivo | Cambio | Descripción |
|---------|--------|-------------|
| `01-schools.sql` | VACIADO | Eliminadas escuelas demo (Marie Curie, IEI) |
| `02-classrooms.sql` | SIMPLIFICADO | Solo classroom DEFAULT |
| `03-classroom-members.sql` | SIMPLIFICADO | Todos los estudiantes → DEFAULT |
| `08-assign-admin-schools.sql` | EXPANDIDO | Asigna TODOS los usuarios a escuela default |
---
### Entidades Eliminadas
**Escuelas removidas:**
- Escuela Primaria Marie Curie (Ciudad de México)
- Instituto de Educación Integral (Guadalajara)
**Aulas removidas:**
- 5to A (Marie Curie)
- 5to B (Marie Curie)
- 6to A (Marie Curie)
- Aula de Pruebas
- Parent Portal Demo
---
### Estructura Final
| Entidad | Cantidad | Código |
|---------|----------|--------|
| Escuelas | 1 | `SYSTEM-UNASSIGNED` |
| Classrooms | 1 | `DEFAULT` |
| Usuarios en escuela default | 16 | - |
| Estudiantes en classroom DEFAULT | 14 | - |
---
### Corrección Técnica
**Constraint fix:** `enrollment_method`
- Valor anterior: `auto_assignment` (inválido)
- Valor corregido: `admin_add`
- Valores válidos: `teacher_invite`, `self_enroll`, `admin_add`, `bulk_import`
---
### Decisión de Diseño
El admin crea entidades adicionales (escuelas, aulas) desde la UI según sea necesario. Esta simplificación:
- Reduce complejidad de seeds
- Facilita mantenimiento
- Clarifica flujo de datos
- Trigger `trg_assign_default_classroom` asigna automáticamente nuevos estudiantes
---
## [2.4.1] - 2025-12-15
### Flujo de Creación de Usuarios - School Default
Esta versión implementa el concepto de "Escuela Default" para la correcta asignación de usuarios nuevos, especialmente administradores y profesores.
**Tech-Leader:** Claude Opus 4.5
**Tarea:** Análisis y adaptación del flujo de creación de usuarios
---
### Seeds Nuevos
| Seed | Schema | Descripción |
|------|--------|-------------|
| `00-schools-default.sql` | social_features | Escuela "Sistema - Por Asignar" (UUID: 99999999-9999-9999-9999-999999999999) |
| `08-assign-admin-schools.sql` | auth_management | Asignación automática de escuela default a admins |
**Total seeds activos:** 51 PROD, 52 DEV
---
### Modificaciones
- **`02-classrooms.sql`**: Classroom DEFAULT ahora apunta a la escuela del sistema en lugar de Marie Curie
- **`create-database.sh`**: Agregados nuevos seeds en el orden correcto
---
### Arquitectura
**Flujo de registro de usuarios actualizado:**
1. Usuario se registra → auth.users creado
2. Trigger crea profile → auth_management.profiles
3. Si role='student' → trigger asigna a classroom DEFAULT
4. Si role='admin_teacher' o 'super_admin' → seed asigna school DEFAULT
**UUID fijas (sistema):**
- School Default: `99999999-9999-9999-9999-999999999999`
- Classroom Default: `00000000-0000-0000-0000-000000000001`
---
### Hallazgos del Análisis
- `AuthService.register()` SÍ estaba implementado (contrario al análisis inicial)
- `last_sign_in_at` SÍ se actualiza en login/register
- El problema de "Nunca" en admin/users es por datos NULL en BD (usuarios de seeds sin login real)
---
## [2.4.0] - 2025-12-14
### Auditoría de Base de Datos (AUDIT-DB-001)
Esta versión incluye correcciones críticas P0 identificadas durante la auditoría de base de datos AUDIT-DB-001. Se eliminaron referencias erróneas a Supabase, se corrigieron funciones de timestamp y se crearon 5 seeds críticos.
**Auditoría:** AUDIT-DB-001
**Prioridad:** P0 - CRÍTICO
**Estado:** COMPLETADO
---
### P0-DUP: Funciones de Timestamp Corregidas
**Problema:** 2 funciones usaban `NOW()` en lugar de `gamilit.now_mexico()`.
**Archivos corregidos:**
- `gamification_system/functions/06-update_missions_updated_at.sql`
- `gamification_system/functions/07-update_notifications_updated_at.sql`
**Cambio:**
```sql
-- ANTES (incorrecto)
NEW.updated_at = NOW();
-- DESPUÉS (correcto)
NEW.updated_at = gamilit.now_mexico();
```
---
### P0-SEEDS: 5 Seeds Críticos Creados
| Seed | Schema | Registros |
|------|--------|-----------|
| `07-user_roles.sql` | auth_management | 8 |
| `10-mission_templates.sql` | gamification_system | 11 |
| `11-module_dependencies.sql` | educational_content | 6 |
| `12-taxonomies.sql` | educational_content | 4 |
| `02-marie_curie_content.sql` | content_management | 6 |
**Total:** 35 registros iniciales
**Coverage P0:** 100%
---
### P0-DOC: Eliminación de Referencias Supabase
**Decisión arquitectónica:** Supabase NO es parte del stack de GAMILIT.
**Cambios realizados:**
- ~75 referencias a Supabase eliminadas en código y documentación
- `AUTH_SUPABASE` renombrado a `AUTH_BASE` en `database.constants.ts`
- Roles RLS correctamente documentados (authenticated, anon, service_role)
**Documentación creada:**
- `docs/90-transversal/arquitectura/ARQUITECTURA-AUTENTICACION.md`
---
### Archivos de Auditoría
```
orchestration/agentes/database-auditor/audit-2025-12-14/
├── 01-REPORTE-ESTRUCTURA-DDL.md
├── 02-REPORTE-CARGA-LIMPIA.md
├── 03-MAPA-DEPENDENCIAS-DDL.yml
├── 04-REPORTE-VALIDACION-DEPENDENCIAS.md
├── 05-INVENTARIO-FUNCIONES-TRIGGERS.yml
├── 06-REPORTE-RLS-POLICIES.md
└── 07-REPORTE-CORRECCIONES-P0.md
```
---
### Inventarios Actualizados
- `BACKEND_INVENTORY.yml` v2.6.0 → v2.7.0
- `SEEDS_INVENTORY.yml` - Agregados 5 P0 seeds
- `DATABASE_INVENTORY.yml` - Referencias actualizadas
---
### Métricas
| Métrica | Antes | Después |
|---------|-------|---------|
| Seeds coverage P0 | 26.4% | 100% |
| Funciones timezone correcto | 97% | 100% |
| Referencias Supabase | 75+ | 0 |
---
## [2.3.0] - 2025-11-09
### 🎉 Resumen Ejecutivo
@ -380,7 +591,7 @@ Global Prefix: /api
## 🎓 Estado de la Plataforma
### ✅ Completamente Funcional
- Autenticación y autorización (JWT + Supabase)
- Autenticación y autorización (JWT + Custom Auth)
- 5 módulos educativos con 27 ejercicios
- Sistema de gamificación (achievements, ranks, ML Coins)
- Portal de estudiante (28 páginas)

View File

@ -9,7 +9,7 @@
## Resumen Ejecutivo
Se ha implementado exitosamente el componente **AvatarUpload** reutilizable que reemplaza el placeholder de avatar por upload real a backend (Supabase Storage/S3).
Se ha implementado exitosamente el componente **AvatarUpload** reutilizable que reemplaza el placeholder de avatar por upload real a backend (S3/Storage compatible).
### Características Principales

View File

@ -9,7 +9,7 @@ Backend para la plataforma educativa gamificada GAMILIT.
- **Language:** TypeScript 5.x (strict mode)
- **ORM:** TypeORM 0.3.x (multi-datasource architecture)
- **Database:** PostgreSQL 14+ (multi-schema: 11 schemas)
- **Auth:** Supabase Auth + JWT
- **Auth:** Custom Auth (patrón compatible con estándares de la industria) + JWT
- **Validation:** class-validator + class-transformer
- **Testing:** Jest
- **Linting:** ESLint + Prettier

View File

@ -76,6 +76,7 @@ import { RlsInterceptor } from './shared/interceptors/rls.interceptor';
}),
// Database connection for 'educational_content' schema
// CORRECTED (2025-12-18): Agregado path de assignments y teacher entities
TypeOrmModule.forRootAsync({
name: 'educational', // Connection name for @InjectRepository(Entity, 'educational')
imports: [ConfigModule],
@ -86,7 +87,11 @@ import { RlsInterceptor } from './shared/interceptors/rls.interceptor';
username: configService.get('database.username'),
password: configService.get('database.password'),
database: configService.get('database.database'),
entities: [__dirname + '/modules/educational/entities/**/*.entity{.ts,.js}'],
entities: [
__dirname + '/modules/educational/entities/**/*.entity{.ts,.js}',
__dirname + '/modules/assignments/entities/**/*.entity{.ts,.js}',
__dirname + '/modules/teacher/entities/teacher-content.entity{.ts,.js}',
],
synchronize: configService.get('database.synchronize', false),
logging: configService.get('database.logging'),
ssl: configService.get('database.ssl'),

View File

@ -56,6 +56,11 @@ import { AdminMonitoringService } from './services/admin-monitoring.service';
import { AdminInterventionsService } from './services/admin-interventions.service';
import { AdminAssignmentsService } from './services/admin-assignments.service';
import { FeatureFlagsService } from './services/feature-flags.service';
import { DashboardStatsService } from './services/statistics/dashboard-stats.service';
import { UserStatsService } from './services/statistics/user-stats.service';
import { ContentStatsService } from './services/statistics/content-stats.service';
import { RecentActivityService } from './services/activity/recent-activity.service';
import { AdminQueryBuilder } from './services/query-builders/admin.query-builder';
import { AdminGuard } from './guards/admin.guard';
import { TasksModule } from '../tasks/tasks.module';
@ -108,6 +113,12 @@ import { TasksModule } from '../tasks/tasks.module';
AdminInterventionsService, // NEW: Student intervention alerts service (BE-001)
AdminAssignmentsService, // NEW: Assignments management service (US-AE-009)
FeatureFlagsService, // NEW: Feature flags service (BE-ADMIN-001-003)
// Dashboard sub-services (dependencies for AdminDashboardService)
DashboardStatsService,
UserStatsService,
ContentStatsService,
RecentActivityService,
AdminQueryBuilder,
AdminGuard,
],
exports: [

View File

@ -6,6 +6,11 @@
* UPDATED (2025-11-08):
* - Agregada entidad AssignmentExercise
* - Agregada entidad AssignmentStudent
*
* CORRECTED (2025-12-18):
* - Datasource cambiado de 'content' a 'educational' para entidades Assignment
* - AssignmentClassroom usa datasource 'social' (pertenece a schema social_features)
* - Fixes EntityMetadataNotFoundError en /teacher/assignments
*/
import { Module } from '@nestjs/common';
@ -21,15 +26,23 @@ import { StudentAssignmentsController } from './controllers/student-assignments.
@Module({
imports: [
// Entidades educational_content → datasource 'educational'
// Assignment, AssignmentExercise, AssignmentStudent, AssignmentSubmission pertenecen a schema educational_content
TypeOrmModule.forFeature(
[
Assignment,
AssignmentClassroom,
AssignmentExercise,
AssignmentStudent,
AssignmentSubmission,
],
'content', // Use content_management connection
'educational',
),
// AssignmentClassroom → datasource 'social' (pertenece a schema social_features)
TypeOrmModule.forFeature(
[
AssignmentClassroom,
],
'social',
),
],
controllers: [AssignmentsController, StudentAssignmentsController],

View File

@ -126,6 +126,54 @@ export class AssignmentsController {
});
}
/**
* GET /api/teacher/assignments/upcoming
* Get assignments with upcoming deadlines
* BAJO-008: Upcoming assignments for Teacher Dashboard
*
* NOTE: This route MUST be declared BEFORE @Get(':id') to prevent
* NestJS from interpreting 'upcoming' as an ID parameter.
*/
@Get('upcoming')
@ApiOperation({
summary: 'Get upcoming assignments',
description: `
Returns assignments with deadlines within the next X days (default: 7).
Includes submission statistics for each assignment.
`,
})
@ApiQuery({
name: 'days',
required: false,
type: Number,
description: 'Number of days to look ahead (default: 7)',
example: 7,
})
@ApiResponse({
status: 200,
description: 'Upcoming assignments retrieved successfully',
schema: {
example: [
{
id: '550e8400-e29b-41d4-a716-446655440000',
title: 'Práctica Semanal: Marie Curie',
dueDate: '2025-01-20T23:59:59Z',
daysRemaining: 2,
totalStudents: 25,
submittedCount: 15,
},
],
},
})
async getUpcoming(
@Query('days') days: string = '7',
@Request() req: AuthRequest,
) {
const teacherId = req.user!.id;
const daysAhead = parseInt(days, 10) || 7;
return this.assignmentsService.getUpcomingAssignments(teacherId, daysAhead);
}
/**
* GET /api/teacher/assignments/:id
* Get single assignment details
@ -574,4 +622,44 @@ export class AssignmentsController {
const teacherId = req.user!.id;
return this.assignmentsService.closeAssignment(id, teacherId);
}
/**
* POST /api/teacher/assignments/:id/send-reminder
* Send reminder to students who haven't submitted
* MEDIO-005: Assignment reminder functionality
*/
@Post(':id/send-reminder')
@ApiOperation({
summary: 'Send reminder to students',
description: `
Sends a reminder notification to all students who haven't submitted
their work for this assignment. Students who have already submitted
will not receive the reminder.
`,
})
@ApiParam({
name: 'id',
description: 'ID of the assignment',
type: String,
example: '550e8400-e29b-41d4-a716-446655440000',
})
@ApiResponse({
status: 200,
description: 'Reminders sent successfully',
schema: {
example: {
notified: 5,
alreadySubmitted: 10,
message: 'Recordatorio enviado a 5 estudiante(s). Tarea: "Ejercicio 1" - Fecha límite: 20/01/2025',
},
},
})
@ApiResponse({
status: 404,
description: 'Assignment not found or access denied',
})
async sendReminder(@Param('id') id: string, @Request() req: AuthRequest) {
const teacherId = req.user!.id;
return this.assignmentsService.sendReminder(id, teacherId);
}
}

View File

@ -29,24 +29,22 @@ import {
schema: DB_SCHEMAS.EDUCATIONAL,
name: DB_TABLES.EDUCATIONAL.ASSIGNMENT_EXERCISES,
})
@Index(['assignment_id'])
@Index(['exercise_id'])
@Index(['order_index'])
@Unique(['assignment_id', 'exercise_id'])
// CORRECTED (2025-12-18): Usar nombres de propiedades en lugar de nombres de columnas
@Index(['assignmentId'])
@Index(['exerciseId'])
@Index(['orderIndex'])
@Unique(['assignmentId', 'exerciseId'])
export class AssignmentExercise {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column('uuid', { name: 'assignment_id' })
@Index()
assignmentId!: string;
@Column('uuid', { name: 'exercise_id' })
@Index()
exerciseId!: string;
@Column('integer', { name: 'order_index' })
@Index()
orderIndex!: number;
@Column('decimal', {

View File

@ -34,19 +34,18 @@ import {
schema: DB_SCHEMAS.EDUCATIONAL,
name: DB_TABLES.EDUCATIONAL.ASSIGNMENT_STUDENTS,
})
@Index(['assignment_id'])
@Index(['student_id'])
@Unique(['assignment_id', 'student_id'])
// CORRECTED (2025-12-18): Usar nombres de propiedades en lugar de nombres de columnas
@Index(['assignmentId'])
@Index(['studentId'])
@Unique(['assignmentId', 'studentId'])
export class AssignmentStudent {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column('uuid', { name: 'assignment_id' })
@Index()
assignmentId!: string;
@Column('uuid', { name: 'student_id' })
@Index()
studentId!: string;
@CreateDateColumn({ name: 'assigned_at', type: 'timestamp with time zone' })

View File

@ -30,12 +30,13 @@ export enum SubmissionStatus {
}
@Entity({ schema: DB_SCHEMAS.EDUCATIONAL, name: DB_TABLES.EDUCATIONAL.ASSIGNMENT_SUBMISSIONS })
@Index(['assignment_id'])
@Index(['student_id'])
// CORRECTED (2025-12-18): Usar nombres de propiedades en lugar de nombres de columnas
@Index(['assignmentId'])
@Index(['studentId'])
@Index(['status'])
@Index(['graded_by'])
@Index(['submitted_at'])
@Unique(['assignment_id', 'student_id'])
@Index(['gradedBy'])
@Index(['submittedAt'])
@Unique(['assignmentId', 'studentId'])
export class AssignmentSubmission {
@PrimaryGeneratedColumn('uuid')
id!: string;

View File

@ -29,16 +29,16 @@ export enum AssignmentType {
}
@Entity({ schema: DB_SCHEMAS.EDUCATIONAL, name: DB_TABLES.EDUCATIONAL.ASSIGNMENTS })
@Index(['teacher_id'])
@Index(['is_published'])
@Index(['assignment_type'])
@Index(['due_date'])
// CORRECTED (2025-12-18): Usar nombres de propiedades en lugar de nombres de columnas
@Index(['teacherId'])
@Index(['isPublished'])
@Index(['assignmentType'])
@Index(['dueDate'])
export class Assignment {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column('uuid', { name: 'teacher_id' })
@Index()
teacherId!: string;
@Column('varchar', { length: 255 })

View File

@ -27,15 +27,17 @@ export class AssignmentsService {
private readonly logger = new Logger(AssignmentsService.name);
constructor(
@InjectRepository(Assignment, 'content')
// Datasource 'educational' para entidades de educational_content schema
@InjectRepository(Assignment, 'educational')
private readonly assignmentRepository: Repository<Assignment>,
@InjectRepository(AssignmentClassroom, 'content')
// Datasource 'social' para AssignmentClassroom (social_features schema)
@InjectRepository(AssignmentClassroom, 'social')
private readonly assignmentClassroomRepository: Repository<AssignmentClassroom>,
@InjectRepository(AssignmentExercise, 'content')
@InjectRepository(AssignmentExercise, 'educational')
private readonly assignmentExerciseRepository: Repository<AssignmentExercise>,
@InjectRepository(AssignmentStudent, 'content')
@InjectRepository(AssignmentStudent, 'educational')
private readonly assignmentStudentRepository: Repository<AssignmentStudent>,
@InjectRepository(AssignmentSubmission, 'content')
@InjectRepository(AssignmentSubmission, 'educational')
private readonly submissionRepository: Repository<AssignmentSubmission>,
) {}
@ -1051,6 +1053,143 @@ export class AssignmentsService {
};
}
/**
* Get upcoming assignments with deadlines within specified days
* BAJO-008: Upcoming assignments for Teacher Dashboard
*
* @param teacherId - The teacher's user ID
* @param daysAhead - Number of days to look ahead (default: 7)
* @returns Array of upcoming assignments with submission stats
*/
async getUpcomingAssignments(
teacherId: string,
daysAhead: number = 7,
): Promise<Array<{
id: string;
title: string;
dueDate: Date | null;
daysRemaining: number;
totalStudents: number;
submittedCount: number;
classroomName?: string;
}>> {
const now = new Date();
const futureDate = new Date();
futureDate.setDate(now.getDate() + daysAhead);
// Get published assignments with upcoming due dates
const assignments = await this.assignmentRepository
.createQueryBuilder('assignment')
.where('assignment.teacherId = :teacherId', { teacherId })
.andWhere('assignment.isPublished = true')
.andWhere('assignment.dueDate IS NOT NULL')
.andWhere('assignment.dueDate >= :now', { now })
.andWhere('assignment.dueDate <= :futureDate', { futureDate })
.orderBy('assignment.dueDate', 'ASC')
.getMany();
// Get stats for each assignment
const results = await Promise.all(
assignments.map(async (assignment) => {
// Get total assigned students
const totalStudents = await this.assignmentStudentRepository.count({
where: { assignmentId: assignment.id },
});
// Get submitted count
const submittedCount = await this.submissionRepository.count({
where: { assignmentId: assignment.id },
});
// Calculate days remaining
const dueDate = assignment.dueDate ? new Date(assignment.dueDate) : null;
const daysRemaining = dueDate
? Math.ceil((dueDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24))
: 0;
return {
id: assignment.id,
title: assignment.title,
dueDate: assignment.dueDate,
daysRemaining,
totalStudents,
submittedCount,
};
}),
);
this.logger.log(`Found ${results.length} upcoming assignments for teacher ${teacherId}`);
return results;
}
/**
* Send reminder notifications to students who haven't submitted
* MEDIO-005: Assignment reminder functionality
*
* @param assignmentId - The assignment ID
* @param teacherId - The teacher's user ID (for authorization)
* @returns Count of students notified
*/
async sendReminder(
assignmentId: string,
teacherId: string,
): Promise<{ notified: number; alreadySubmitted: number; message: string }> {
// Verify ownership
const assignment = await this.findOne(assignmentId, teacherId);
// Get all students assigned to this assignment
const assignedStudents = await this.assignmentStudentRepository.find({
where: { assignmentId },
});
if (assignedStudents.length === 0) {
return {
notified: 0,
alreadySubmitted: 0,
message: 'No hay estudiantes asignados a esta tarea',
};
}
// Get students who have already submitted
const submissions = await this.submissionRepository.find({
where: { assignmentId },
});
const submittedStudentIds = new Set(submissions.map((s) => s.studentId));
// Filter students who haven't submitted
const studentsToNotify = assignedStudents.filter(
(s) => !submittedStudentIds.has(s.studentId),
);
const alreadySubmitted = assignedStudents.length - studentsToNotify.length;
if (studentsToNotify.length === 0) {
return {
notified: 0,
alreadySubmitted,
message: 'Todos los estudiantes ya han entregado esta tarea',
};
}
// Log reminder sent (in production, integrate with NotificationService)
// TODO: Integrate with notification-multichannel using template 'assignment_due_reminder'
this.logger.log(
`Reminder sent for assignment ${assignmentId}: ${studentsToNotify.length} students notified`,
);
// For now, just return the count (notifications will be implemented with full integration)
const dueDate = assignment.dueDate
? new Date(assignment.dueDate).toLocaleDateString('es-ES')
: 'Sin fecha límite';
return {
notified: studentsToNotify.length,
alreadySubmitted,
message: `Recordatorio enviado a ${studentsToNotify.length} estudiante(s). Tarea: "${assignment.title}" - Fecha límite: ${dueDate}`,
};
}
/**
* Sanitize HTML to prevent XSS
* REQ-TCH-021: HTML sanitization

View File

@ -54,7 +54,7 @@ export class User {
* Rol del usuario en el sistema (student, admin_teacher, super_admin)
*
* @note GAMILIT usa la columna 'gamilit_role' (ENUM auth_management.gamilit_role)
* @note La columna 'role' (varchar) es legacy de Supabase, no se usa
* @note La columna 'role' (varchar) es legacy del patrón auth estándar, no se usa en GAMILIT
*/
@Column({
type: 'enum',

View File

@ -126,16 +126,19 @@ export class ExercisesController {
let timeSpentSeconds: number | undefined;
if (dto.startedAt) {
// Formato nuevo: calcular desde timestamp
// Formato nuevo (camelCase): calcular desde timestamp
timeSpentSeconds = Math.floor((Date.now() - dto.startedAt) / 1000);
} else if (dto.started_at) {
// Formato snake_case: calcular desde timestamp
timeSpentSeconds = Math.floor((Date.now() - dto.started_at) / 1000);
} else if (dto.time_spent_seconds !== undefined) {
// Formato antiguo: usar valor directo
timeSpentSeconds = dto.time_spent_seconds;
}
// 4. Normalizar hints y powerups
// 4. Normalizar hints y powerups (prioridad: camelCase > snake_case > legacy)
const hintsUsed = dto.hintsUsed ?? dto.hints_used ?? 0;
const powerupsUsed = dto.powerupsUsed ?? dto.comodines_used ?? [];
const powerupsUsed = dto.powerupsUsed ?? dto.powerups_used ?? dto.comodines_used ?? [];
return {
userId,

View File

@ -11,6 +11,7 @@ import {
HttpStatus,
Request,
UseGuards,
ParseUUIDPipe,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery } from '@nestjs/swagger';
import { ModulesService } from '../services';
@ -283,7 +284,7 @@ export class ModulesController {
status: 404,
description: 'Usuario no encontrado',
})
async getUserModules(@Param('userId') userId: string) {
async getUserModules(@Param('userId', ParseUUIDPipe) userId: string) {
return this.modulesService.getUserModules(userId);
}
@ -375,7 +376,7 @@ export class ModulesController {
},
},
})
async findOne(@Param('id') id: string) {
async findOne(@Param('id', ParseUUIDPipe) id: string) {
return this.modulesService.findById(id);
}
@ -486,7 +487,7 @@ export class ModulesController {
status: 404,
description: 'Módulo no encontrado',
})
async update(@Param('id') id: string, @Body() updateModuleDto: Partial<CreateModuleDto>) {
async update(@Param('id', ParseUUIDPipe) id: string, @Body() updateModuleDto: Partial<CreateModuleDto>) {
return this.modulesService.update(id, updateModuleDto);
}
@ -530,7 +531,7 @@ export class ModulesController {
status: 404,
description: 'Módulo no encontrado',
})
async remove(@Param('id') id: string) {
async remove(@Param('id', ParseUUIDPipe) id: string) {
const deleted = await this.modulesService.delete(id);
return {
success: deleted,
@ -588,7 +589,7 @@ export class ModulesController {
status: 404,
description: 'Módulo no encontrado',
})
async getPrerequisites(@Param('id') id: string) {
async getPrerequisites(@Param('id', ParseUUIDPipe) id: string) {
return this.modulesService.getPrerequisites(id);
}
}

View File

@ -175,4 +175,34 @@ export class SubmitExerciseDto {
@IsOptional()
@IsArray()
comodines_used?: string[];
/**
* @deprecated Usar 'startedAt' (camelCase)
* Se mantiene para compatibilidad con frontends que envían snake_case
*/
@ApiProperty({
description: '[DEPRECATED] Usar "startedAt"',
example: 1638392400000,
required: false,
deprecated: true,
})
@IsOptional()
@IsNumber()
@Min(0)
started_at?: number;
/**
* @deprecated Usar 'powerupsUsed' (camelCase)
* Se mantiene para compatibilidad con frontends que envían snake_case
*/
@ApiProperty({
description: '[DEPRECATED] Usar "powerupsUsed"',
example: ['hint_50_50', 'extra_time'],
required: false,
deprecated: true,
})
@IsOptional()
@IsArray()
@IsString({ each: true })
powerups_used?: string[];
}

View File

@ -1,9 +1,15 @@
/**
* Module 4 DTOs - Barrel Export
*
* @description Exporta todos los DTOs de respuestas del Módulo 4.
* Estos DTOs validan las respuestas de los ejercicios relacionados con
* alfabetización digital y análisis crítico de medios.
* @description Exporta todos los DTOs de respuestas del Módulo 4 (Lectura Digital y Multimodal).
* Solo incluye los 5 ejercicios oficiales según DocumentoDeDiseño v6.4.
*
* Ejercicios oficiales:
* 4.1 Verificador Fake News
* 4.2 Infografía Interactiva
* 4.3 Quiz TikTok
* 4.4 Navegación Hipertextual
* 4.5 Análisis Memes
*
* @usage import { VerificadorFakeNewsAnswerDto, AnalisisMemesAnswerDto } from '@/modules/educational/dto/module4';
*/

View File

@ -0,0 +1,122 @@
import {
IsArray,
IsString,
IsNumber,
IsOptional,
ValidateNested,
ArrayMinSize,
ArrayMaxSize,
Min,
} from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger';
/**
* ComicPanelDto
*
* @description DTO para representar una viñeta individual del cómic.
* Cada viñeta debe tener diálogo, narración, y opcionalmente imagen.
*/
export class ComicPanelDto {
@ApiProperty({
description: 'Número de la viñeta (1-6)',
example: 1,
minimum: 1,
})
@IsNumber({}, { message: 'panelNumber must be a number' })
@Min(1, { message: 'panelNumber must be at least 1' })
panelNumber: number;
@ApiProperty({
description: 'Diálogo de los personajes en la viñeta',
example: 'Marie: "Este mineral contiene algo extraordinario, Pierre."',
})
@IsString({ message: 'dialogue must be a string' })
dialogue: string;
@ApiProperty({
description: 'Narración contextual de la viñeta',
example: '1898. En un laboratorio frío de París...',
})
@IsString({ message: 'narration must be a string' })
narration: string;
@ApiProperty({
description: 'URL de la imagen o boceto de la viñeta (opcional)',
example: 'https://storage.example.com/panel1.png',
required: false,
})
@IsOptional()
@IsString({ message: 'imageUrl must be a string' })
imageUrl?: string;
@ApiProperty({
description: 'Descripción visual de la escena (para accesibilidad o si no hay imagen)',
example: 'Marie y Pierre observan un mineral oscuro sobre la mesa del laboratorio',
required: false,
})
@IsOptional()
@IsString({ message: 'visualDescription must be a string' })
visualDescription?: string;
}
/**
* ComicDigitalAnswerDto
*
* @description DTO para validar las respuestas del ejercicio "Cómic Digital".
* El estudiante debe crear un cómic de 4-6 viñetas narrando una historia científica.
*
* @example
* ```json
* {
* "panels": [
* {
* "panelNumber": 1,
* "dialogue": "Marie: 'Este mineral es extraordinario.'",
* "narration": "1898. En un laboratorio de París...",
* "imageUrl": "https://storage.example.com/panel1.png"
* },
* {
* "panelNumber": 2,
* "dialogue": "Pierre: 'Debemos aislarlo.'",
* "narration": "Los Curie comienzan su investigación.",
* "visualDescription": "Close-up de mediciones en electroscopio"
* }
* ]
* }
* ```
*/
export class ComicDigitalAnswerDto {
@ApiProperty({
description: 'Lista de viñetas del cómic (mínimo 4, máximo 6)',
type: [ComicPanelDto],
example: [
{
panelNumber: 1,
dialogue: 'Marie: "Este mineral contiene algo extraordinario."',
narration: '1898. En un laboratorio frío de París...',
},
{
panelNumber: 2,
dialogue: 'Pierre: "Debemos aislarlo, por muy difícil que sea."',
narration: 'Los Curie inician años de arduo trabajo.',
},
{
panelNumber: 3,
dialogue: 'Marie: "No puedo rendirme. El secreto está ahí."',
narration: 'Cuatro años de procesamiento manual.',
},
{
panelNumber: 4,
dialogue: 'Ambos: "¡Brilla! Lo logramos."',
narration: 'El radio ilumina la oscuridad del laboratorio.',
},
],
})
@IsArray({ message: 'panels must be an array' })
@ArrayMinSize(4, { message: 'panels must contain at least 4 panels' })
@ArrayMaxSize(6, { message: 'panels must contain at most 6 panels' })
@ValidateNested({ each: true })
@Type(() => ComicPanelDto)
panels: ComicPanelDto[];
}

View File

@ -0,0 +1,186 @@
import {
IsString,
IsArray,
IsOptional,
IsNumber,
IsDateString,
ValidateNested,
ArrayMinSize,
ArrayMaxSize,
MinLength,
} from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger';
/**
* DiaryEntryDto
*
* @description DTO para representar una entrada individual del diario multimedia.
* Cada entrada debe tener fecha, contenido, y opcionalmente titulo, mood y multimedia.
*/
export class DiaryEntryDto {
@ApiProperty({
description: 'Identificador unico de la entrada',
example: 'entry1',
})
@IsString({ message: 'id must be a string' })
id: string;
@ApiProperty({
description: 'Fecha de la entrada del diario (formato ISO 8601)',
example: '1898-12-15',
})
@IsDateString({}, { message: 'date must be a valid date string (ISO 8601)' })
date: string;
@ApiProperty({
description: 'Titulo de la entrada',
example: 'El Dia del Descubrimiento',
required: false,
})
@IsOptional()
@IsString({ message: 'title must be a string' })
title?: string;
@ApiProperty({
description: 'Contenido reflexivo de la entrada (minimo 50 caracteres)',
example:
'Querido diario, hoy es un dia que nunca olvidare. Despues de cuatro anos de trabajo incansable...',
})
@IsString({ message: 'content must be a string' })
@MinLength(50, { message: 'content must be at least 50 characters long' })
content: string;
@ApiProperty({
description: 'Estado de animo asociado a la entrada',
example: 'excitement',
required: false,
})
@IsOptional()
@IsString({ message: 'mood must be a string' })
mood?: string;
@ApiProperty({
description: 'Conteo de palabras de la entrada',
example: 156,
required: false,
})
@IsOptional()
@IsNumber({}, { message: 'wordCount must be a number' })
wordCount?: number;
@ApiProperty({
description: 'Clima o contexto del dia',
example: 'Frio invernal en Paris',
required: false,
})
@IsOptional()
@IsString({ message: 'weather must be a string' })
weather?: string;
@ApiProperty({
description: 'Ubicacion donde se escribe la entrada',
example: 'Laboratorio en Rue Lhomond',
required: false,
})
@IsOptional()
@IsString({ message: 'location must be a string' })
location?: string;
@ApiProperty({
description: 'Template utilizado para la entrada',
example: 'template_classic',
required: false,
})
@IsOptional()
@IsString({ message: 'template must be a string' })
template?: string;
@ApiProperty({
description: 'Archivos multimedia adjuntos (imagenes, audio, video)',
required: false,
})
@IsOptional()
multimedia?: any;
}
/**
* DiarioMultimediaAnswerDto
*
* @description DTO para validar las respuestas del ejercicio "Diario Multimedia".
* El estudiante debe escribir un diario desde la perspectiva de Marie Curie
* durante el descubrimiento del radio (1898-1899).
*
* Requisitos:
* - Minimo 3 entradas, maximo 5
* - Cada entrada debe tener fecha y contenido (minimo 50 caracteres)
* - Precision historica requerida
*
* @example
* ```json
* {
* "entries": [
* {
* "id": "entry1",
* "date": "1898-12-15",
* "title": "El Dia del Descubrimiento",
* "content": "Querido diario, hoy es un dia que nunca olvidare...",
* "mood": "excitement",
* "wordCount": 156
* }
* ],
* "totalEntries": 3,
* "totalWords": 468
* }
* ```
*/
export class DiarioMultimediaAnswerDto {
@ApiProperty({
description: 'Lista de entradas del diario (minimo 1, maximo 5)',
type: [DiaryEntryDto],
example: [
{
id: 'entry1',
date: '1898-12-15',
title: 'El Dia del Descubrimiento',
content:
'Querido diario, hoy es un dia que nunca olvidare. Despues de cuatro anos de trabajo incansable, Pierre y yo finalmente lo logramos. En la oscuridad de nuestro laboratorio, el radio brillo con una luz azul-verde eterea.',
mood: 'excitement',
wordCount: 156,
},
],
})
@IsArray({ message: 'entries must be an array' })
@ArrayMinSize(1, { message: 'entries must contain at least 1 entry' })
@ArrayMaxSize(5, { message: 'entries must contain at most 5 entries' })
@ValidateNested({ each: true })
@Type(() => DiaryEntryDto)
entries: DiaryEntryDto[];
@ApiProperty({
description: 'Total de entradas en el diario',
example: 3,
required: false,
})
@IsOptional()
@IsNumber({}, { message: 'totalEntries must be a number' })
totalEntries?: number;
@ApiProperty({
description: 'Total de palabras en todas las entradas',
example: 468,
required: false,
})
@IsOptional()
@IsNumber({}, { message: 'totalWords must be a number' })
totalWords?: number;
@ApiProperty({
description: 'Fecha y hora de envio',
example: '2025-01-15T14:30:00Z',
required: false,
})
@IsOptional()
@IsString({ message: 'submittedAt must be a string' })
submittedAt?: string;
}

View File

@ -1,98 +0,0 @@
import {
IsString,
IsArray,
MinLength,
registerDecorator,
ValidationOptions,
ValidationArguments,
} from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
/**
* Custom validator para verificar el número mínimo de palabras
*
* @param minWords Número mínimo de palabras requeridas
* @param validationOptions Opciones de validación
*/
function MinWords(minWords: number, validationOptions?: ValidationOptions) {
return function (object: object, propertyName: string) {
registerDecorator({
name: 'minWords',
target: object.constructor,
propertyName: propertyName,
constraints: [minWords],
options: validationOptions,
validator: {
validate(value: any, args: ValidationArguments) {
if (typeof value !== 'string') return false;
// Elimina espacios extra y cuenta palabras
const words = value.trim().split(/\s+/).filter((word) => word.length > 0);
return words.length >= args.constraints[0];
},
defaultMessage(args: ValidationArguments) {
return `${args.property} must contain at least ${args.constraints[0]} words`;
},
},
});
};
}
/**
* DiarioReflexivoAnswerDto
*
* @description DTO para validar las respuestas del ejercicio "Diario Reflexivo".
* El estudiante debe escribir una reflexión personal sobre su proceso de aprendizaje
* en alfabetización digital. Se requiere un contenido sustancial (mínimo 150 palabras)
* y respuestas a prompts guiados.
*
* @example
* ```json
* {
* "content": "Durante este módulo he aprendido sobre la importancia de verificar las fuentes...",
* "prompts_answered": [
* "¿Qué aprendiste sobre fake news?",
* "¿Cómo aplicarás estas habilidades en tu vida diaria?",
* "¿Qué desafíos encontraste durante el módulo?"
* ]
* }
* ```
*/
export class DiarioReflexivoAnswerDto {
@ApiProperty({
description:
'Contenido reflexivo del estudiante (mínimo 150 palabras). ' +
'Debe ser una reflexión personal sobre el proceso de aprendizaje.',
example:
'Durante este módulo he aprendido sobre la importancia de verificar las fuentes de información ' +
'antes de compartir contenido en redes sociales. Me di cuenta de que muchas veces compartimos ' +
'información sin verificar su veracidad, lo cual contribuye a la desinformación. Los ejercicios ' +
'sobre fake news me ayudaron a desarrollar un pensamiento más crítico. Ahora me tomo el tiempo ' +
'de revisar múltiples fuentes antes de creer o compartir información. También aprendí sobre la ' +
'importancia de la alfabetización digital en el mundo actual, donde estamos constantemente expuestos ' +
'a información de diferentes fuentes. El análisis de memes fue particularmente interesante porque ' +
'me mostró cómo el humor puede ser usado para manipular opiniones. En el futuro, aplicaré estas ' +
'habilidades para ser más consciente de mi consumo de información digital y ayudar a otros a ' +
'desarrollar estas mismas competencias críticas.',
minLength: 1,
})
@IsString({ message: 'content must be a string' })
@MinLength(1, { message: 'content cannot be empty' })
@MinWords(150, {
message: 'content must contain at least 150 words for a meaningful reflection',
})
content: string;
@ApiProperty({
description:
'Lista de prompts o preguntas guía que fueron respondidas en la reflexión',
example: [
'¿Qué aprendiste sobre fake news?',
'¿Cómo aplicarás estas habilidades en tu vida diaria?',
'¿Qué desafíos encontraste durante el módulo?',
],
})
@IsArray({ message: 'prompts_answered must be an array' })
@IsString({ each: true, message: 'each prompt must be a string' })
prompts_answered: string[];
}

View File

@ -1,13 +1,24 @@
/**
* Module 5 DTOs - Barrel Export
*
* @description Exporta todos los DTOs de respuestas del Módulo 5.
* Estos DTOs validan las respuestas de los ejercicios de reflexión y
* producción de contenido sobre alfabetización digital.
* @description Exporta todos los DTOs de respuestas del Módulo 5 (Producción Creativa).
* Solo incluye los 3 ejercicios oficiales según DocumentoDeDiseño v6.1.
*
* @usage import { DiarioReflexivoAnswerDto, VideoCartaAnswerDto, PodcastAnswerDto } from '@/modules/educational/dto/module5';
* Ejercicios oficiales:
* 5.1 Diario Multimedia (diario_multimedia)
* 5.2 Cómic Digital (comic_digital)
* 5.3 Video-Carta (video_carta)
*
* @note El estudiante elige y completa SOLO UNO de los 3 ejercicios.
* @note TODOS los ejercicios del M5 requieren evaluación manual por un docente.
*
* @usage import { DiarioMultimediaAnswerDto, ComicDigitalAnswerDto, VideoCartaAnswerDto } from '@/modules/educational/dto/module5';
*
* @updated 2025-12-18 - CORR-M5: Alineación con DocumentoDeDiseño v6.1
* - Reemplazado DiarioReflexivoAnswerDto por DiarioMultimediaAnswerDto
* - Eliminado PodcastAnswerDto (no está en diseño oficial)
*/
export * from './diario-reflexivo-answer.dto';
export * from './diario-multimedia-answer.dto';
export * from './video-carta-answer.dto';
export * from './podcast-answer.dto';
export * from './comic-digital-answer.dto';

View File

@ -1,61 +0,0 @@
import {
IsUrl,
IsString,
IsNumber,
IsPositive,
IsOptional,
} from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
/**
* PodcastAnswerDto
*
* @description DTO para validar las respuestas del ejercicio "Podcast".
* El estudiante crea un podcast reflexivo sobre alfabetización digital,
* compartiendo sus aprendizajes y perspectivas en formato de audio.
*
* @example
* ```json
* {
* "audio_url": "https://soundcloud.com/user/my-digital-literacy-podcast",
* "transcript": "Hola a todos, bienvenidos a mi podcast sobre alfabetización digital...",
* "duration_seconds": 420
* }
* ```
*/
export class PodcastAnswerDto {
@ApiProperty({
description:
'URL del podcast subido por el estudiante (SoundCloud, Anchor, Spotify, etc.)',
example: 'https://soundcloud.com/user/my-digital-literacy-podcast',
})
@IsUrl(
{
require_protocol: true,
protocols: ['http', 'https'],
},
{ message: 'audio_url must be a valid URL' },
)
audio_url: string;
@ApiProperty({
description:
'Transcripción opcional del contenido del podcast. ' +
'Útil para accesibilidad y análisis del contenido.',
example:
'Hola a todos, bienvenidos a mi podcast sobre alfabetización digital. ' +
'Hoy quiero compartir con ustedes lo que he aprendido durante este módulo...',
required: false,
})
@IsOptional()
@IsString({ message: 'transcript must be a string' })
transcript?: string;
@ApiProperty({
description: 'Duración total del podcast en segundos',
example: 420,
})
@IsNumber({}, { message: 'duration_seconds must be a number' })
@IsPositive({ message: 'duration_seconds must be a positive number' })
duration_seconds: number;
}

View File

@ -1,5 +1,8 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsUUID, IsInt, Min, IsOptional } from 'class-validator';
import { IsString, IsInt, Min, IsOptional, Matches } from 'class-validator';
// UUID regex that matches any UUID format
const UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
/**
* CreatePurchaseDto
@ -12,15 +15,17 @@ export class CreatePurchaseDto {
example: '550e8400-e29b-41d4-a716-446655440000',
description: 'ID del usuario comprador',
})
@IsUUID()
user_id!: string;
@IsString({ message: 'user_id debe ser un string' })
@Matches(UUID_REGEX, { message: 'user_id debe tener formato UUID válido' })
user_id!: string;
@ApiProperty({
example: '660e8400-e29b-41d4-a716-446655440000',
description: 'ID del item a comprar',
})
@IsUUID()
item_id!: string;
@IsString({ message: 'item_id debe ser un string' })
@Matches(UUID_REGEX, { message: 'item_id debe tener formato UUID válido' })
item_id!: string;
@ApiProperty({
example: 1,
@ -31,5 +36,5 @@ export class CreatePurchaseDto {
@IsOptional()
@IsInt()
@Min(1)
quantity?: number;
quantity?: number;
}

View File

@ -2,7 +2,6 @@ import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
Index,
} from 'typeorm';
import { DB_SCHEMAS, DB_TABLES } from '@shared/constants/database.constants';
@ -71,10 +70,10 @@ export class UserPurchase {
price_paid!: number;
/**
* Si se aplicó descuento en esta compra
* Descuento aplicado en ML Coins (valor absoluto)
*/
@Column({ type: 'boolean', default: false })
discount_applied!: boolean;
@Column({ type: 'integer', default: 0 })
discount_applied!: number;
/**
* ID de la transacción de ML Coins (FK ml_coins_transactions)
@ -123,17 +122,12 @@ export class UserPurchase {
metadata!: Record<string, unknown>;
/**
* Fecha y hora de la compra
* Fecha y hora de la compra (timestamp de creación del registro)
* NOTA: La tabla usa purchased_at como timestamp de creación, no tiene created_at
*/
@Column({ type: 'timestamp with time zone', default: () => 'CURRENT_TIMESTAMP' })
@Column({ type: 'timestamp with time zone', default: () => 'gamilit.now_mexico()' })
purchased_at!: Date;
/**
* Fecha y hora de creación del registro
*/
@CreateDateColumn({ type: 'timestamp with time zone' })
created_at!: Date;
// =====================================================
// HELPER METHODS
// =====================================================

View File

@ -7,6 +7,8 @@ import {
Index,
} from 'typeorm';
import { DB_SCHEMAS, DB_TABLES } from '@shared/constants/database.constants';
// CORR-P1-006: Import MayaRank para alinear tipo con DDL
import { MayaRank } from '@shared/constants/enums.constants';
/**
* UserStats Entity (gamification_system.user_stats)
@ -80,9 +82,17 @@ export class UserStats {
/**
* Rango Maya actual del usuario
* Valores: 'Ajaw', 'Nacom', 'Ah K'in', 'Halach Uinic', 'K'uk'ulkan'
*
* CORR-P1-006: Cambiado de 'text' a 'enum' para alinear con DDL
* DDL define como: gamification_system.maya_rank ENUM
*/
@Column({ type: 'text', default: 'Ajaw' })
current_rank!: string;
@Column({
type: 'enum',
enum: MayaRank,
enumName: 'maya_rank',
default: MayaRank.AJAW,
})
current_rank!: MayaRank;
/**
* Progreso hacia el siguiente rango (0-100%)

View File

@ -1,9 +1,49 @@
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Injectable, NotFoundException, BadRequestException, Logger } from '@nestjs/common';
import { InjectRepository, InjectDataSource } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { Achievement, UserAchievement, UserStats } from '../entities';
import { GrantAchievementDto } from '../dto';
/**
* Interfaces para tipos de condiciones de achievements (alineadas con seeds)
*/
interface AchievementConditions {
type: string;
requirements: Record<string, unknown>;
}
interface ExerciseCompletionReqs {
exercises_completed: number;
}
interface StreakReqs {
consecutive_days: number;
}
interface ModuleCompletionReqs {
module_id: string;
completion_percentage: number;
}
interface AllModulesCompletionReqs {
modules_completed: number;
min_score_average: number;
}
interface PerfectScoreReqs {
perfect_exercises: number;
score_required: number;
}
interface SocialReqs {
classrooms_joined?: number;
social_activities?: number;
}
interface SpecialReqs {
first_login?: boolean;
}
/**
* AchievementsService
*
@ -15,6 +55,8 @@ import { GrantAchievementDto } from '../dto';
*/
@Injectable()
export class AchievementsService {
private readonly logger = new Logger(AchievementsService.name);
constructor(
@InjectRepository(Achievement, 'gamification')
private readonly achievementRepo: Repository<Achievement>,
@ -22,6 +64,8 @@ export class AchievementsService {
private readonly userAchievementRepo: Repository<UserAchievement>,
@InjectRepository(UserStats, 'gamification')
private readonly userStatsRepo: Repository<UserStats>,
@InjectDataSource('gamification')
private readonly dataSource: DataSource,
) {}
/**
@ -223,70 +267,262 @@ export class AchievementsService {
continue; // Saltar si no es repetible y ya está completado
}
// Evaluar condiciones
if (this.meetsConditions(userStats, achievement.conditions)) {
// Evaluar condiciones (ahora async para soportar queries complejas)
const conditionsMet = await this.meetsConditions(userId, userStats, achievement.conditions);
if (conditionsMet) {
this.logger.log(`Achievement ${achievement.name} conditions met for user ${userId}`);
const grantDto = new GrantAchievementDto();
grantDto.user_id = userId;
grantDto.achievement_id = achievement.id;
const conditionsTyped = achievement.conditions as { progress?: number; max_progress?: number };
grantDto.progress = conditionsTyped.progress || conditionsTyped.max_progress || 100;
grantDto.max_progress = conditionsTyped.max_progress || 100;
const conditionsTyped = achievement.conditions as { requirements?: { exercises_completed?: number } };
const reqs = conditionsTyped.requirements || {};
grantDto.progress = reqs.exercises_completed || 100;
grantDto.max_progress = reqs.exercises_completed || 100;
grantDto.is_completed = true;
grantDto.progress_data = { auto_detected: true };
grantDto.progress_data = { auto_detected: true, detected_at: new Date().toISOString() };
const granted = await this.grantAchievement(userId, grantDto);
grantedAchievements.push(granted);
}
}
this.logger.log(`Detected and granted ${grantedAchievements.length} achievements for user ${userId}`);
return grantedAchievements;
}
/**
* Evalúa si las estadísticas del usuario cumplen con las condiciones del logro
* ACTUALIZADO: Soporta todos los tipos definidos en seeds de achievements
*
* Tipos soportados:
* - exercise_completion: Completar N ejercicios
* - streak: Mantener racha de N días consecutivos
* - module_completion: Completar un módulo específico
* - all_modules_completion: Completar todos los módulos
* - perfect_score: Obtener N puntuaciones perfectas
* - social: Actividades sociales (unirse a aulas, etc.)
* - special: Eventos especiales (primer login, etc.)
*/
private meetsConditions(userStats: UserStats, conditions: Record<string, unknown>): boolean {
// Type cast for accessing condition properties
const cond = conditions as {
type?: string;
exercises_completed?: number;
modules_completed?: number;
min_streak?: number;
min_level?: number;
min_average_score?: number;
min_perfect_scores?: number;
target_rank?: string;
min_coins_earned?: number;
};
private async meetsConditions(
userId: string,
userStats: UserStats,
conditions: Record<string, unknown>,
): Promise<boolean> {
const cond = conditions as unknown as AchievementConditions;
const type = cond.type || 'generic';
const reqs = (cond.requirements || {}) as unknown as Record<string, unknown>;
switch (type) {
case 'progress':
return (
userStats.exercises_completed >= (cond.exercises_completed || 0) &&
userStats.modules_completed >= (cond.modules_completed || 0)
);
try {
switch (type) {
// =====================================================
// TIPO: exercise_completion
// Condición: Completar N ejercicios
// =====================================================
case 'exercise_completion': {
const r = reqs as unknown as ExerciseCompletionReqs;
const met = userStats.exercises_completed >= (r.exercises_completed || 0);
this.logger.debug(`[exercise_completion] User has ${userStats.exercises_completed}, needs ${r.exercises_completed}: ${met}`);
return met;
}
case 'streak':
return userStats.current_streak >= (cond.min_streak || 0);
// =====================================================
// TIPO: streak
// Condición: Mantener racha de N días consecutivos
// Seeds usan: consecutive_days (no min_streak)
// =====================================================
case 'streak': {
const r = reqs as unknown as StreakReqs;
const required = r.consecutive_days || 0;
const met = userStats.current_streak >= required;
this.logger.debug(`[streak] User has ${userStats.current_streak} days, needs ${required}: ${met}`);
return met;
}
case 'level':
return userStats.level >= (cond.min_level || 0);
// =====================================================
// TIPO: module_completion
// Condición: Completar un módulo específico al 100%
// Requiere query adicional a progress_tracking.module_progress
// =====================================================
case 'module_completion': {
const r = reqs as unknown as ModuleCompletionReqs;
case 'score':
return (
(userStats.average_score || 0) >= (cond.min_average_score || 0) &&
userStats.perfect_scores >= (cond.min_perfect_scores || 0)
);
const result = await this.dataSource.query(
`
SELECT mp.completion_percentage
FROM progress_tracking.module_progress mp
JOIN educational_content.modules m ON mp.module_id = m.id
WHERE mp.user_id = $1
AND m.slug = $2
`,
[userId, r.module_id],
);
case 'rank':
return this.userReachedRank(userStats.current_rank, cond.target_rank || '');
if (!result || result.length === 0) {
this.logger.debug(`[module_completion] No progress found for module ${r.module_id}`);
return false;
}
case 'ml_coins':
return userStats.ml_coins_earned_total >= (cond.min_coins_earned || 0);
const percentage = parseFloat(result[0].completion_percentage) || 0;
const met = percentage >= (r.completion_percentage || 100);
this.logger.debug(`[module_completion] Module ${r.module_id}: ${percentage}% / ${r.completion_percentage}%: ${met}`);
return met;
}
default:
return false;
// =====================================================
// TIPO: all_modules_completion
// Condición: Completar todos los módulos con score promedio mínimo
// =====================================================
case 'all_modules_completion': {
const r = reqs as unknown as AllModulesCompletionReqs;
const modulesRequired = r.modules_completed || 5;
const scoreRequired = r.min_score_average || 70;
const met =
userStats.modules_completed >= modulesRequired &&
(userStats.average_score || 0) >= scoreRequired;
this.logger.debug(
`[all_modules_completion] Modules: ${userStats.modules_completed}/${modulesRequired}, ` +
`Score: ${userStats.average_score || 0}/${scoreRequired}: ${met}`,
);
return met;
}
// =====================================================
// TIPO: perfect_score
// Condición: Obtener N puntuaciones perfectas (100%)
// =====================================================
case 'perfect_score': {
const r = reqs as unknown as PerfectScoreReqs;
const required = r.perfect_exercises || 0;
const met = userStats.perfect_scores >= required;
this.logger.debug(`[perfect_score] User has ${userStats.perfect_scores}, needs ${required}: ${met}`);
return met;
}
// =====================================================
// TIPO: skill_mastery
// Condición: Dominar un skill específico con score mínimo
// Nota: Requiere consulta a exercise_responses por tipo de skill
// Por ahora, simplificado a verificar perfect_scores
// =====================================================
case 'skill_mastery': {
// TODO: Implementar consulta por skill_type cuando esté disponible en metadata
this.logger.debug(`[skill_mastery] Type not fully implemented, checking perfect_scores`);
return userStats.perfect_scores >= 10;
}
// =====================================================
// TIPO: exploration
// Condición: Explorar diferentes módulos o niveles de dificultad
// Simplificado a verificar modules_completed > 0
// =====================================================
case 'exploration': {
const met = userStats.modules_completed > 0 || userStats.exercises_completed >= 5;
this.logger.debug(`[exploration] Modules: ${userStats.modules_completed}, Exercises: ${userStats.exercises_completed}: ${met}`);
return met;
}
// =====================================================
// TIPO: social
// Condición: Actividades sociales (unirse a aulas, etc.)
// Requiere query a social_features.classroom_members
// =====================================================
case 'social': {
const r = reqs as unknown as SocialReqs;
if (r.classrooms_joined !== undefined) {
const result = await this.dataSource.query(
`
SELECT COUNT(*) as count
FROM social_features.classroom_members
WHERE user_id = $1 AND is_active = true
`,
[userId],
);
const count = parseInt(result[0]?.count || '0');
const met = count >= (r.classrooms_joined || 1);
this.logger.debug(`[social:classrooms] User in ${count} classrooms, needs ${r.classrooms_joined}: ${met}`);
return met;
}
if (r.social_activities !== undefined) {
// Contar total de actividades sociales (classroom + friendships)
const result = await this.dataSource.query(
`
SELECT
(SELECT COUNT(*) FROM social_features.classroom_members WHERE user_id = $1 AND is_active = true) +
(SELECT COUNT(*) FROM social_features.friendships WHERE user_id = $1 AND status = 'accepted') as total
`,
[userId],
);
const total = parseInt(result[0]?.total || '0');
const met = total >= (r.social_activities || 5);
this.logger.debug(`[social:activities] Total social activities: ${total}, needs ${r.social_activities}: ${met}`);
return met;
}
return false;
}
// =====================================================
// TIPO: special
// Condición: Eventos especiales (primer login)
// =====================================================
case 'special': {
const r = reqs as SpecialReqs;
if (r.first_login === true) {
// Verificar si ya se otorgó este achievement antes
// Si el usuario existe y tiene stats, asumimos que ya completó primer login
const met = userStats.exercises_completed === 0 && !userStats.last_activity_at;
this.logger.debug(`[special:first_login] First login check: ${met}`);
// Para primer login, lo otorgamos si es usuario nuevo
return !userStats.last_activity_at;
}
return false;
}
// =====================================================
// TIPOS LEGACY (mantener compatibilidad)
// =====================================================
case 'progress':
return (
userStats.exercises_completed >= ((reqs as Record<string, number>).exercises_completed || 0) &&
userStats.modules_completed >= ((reqs as Record<string, number>).modules_completed || 0)
);
case 'level':
return userStats.level >= ((reqs as Record<string, number>).min_level || 0);
case 'score':
return (
(userStats.average_score || 0) >= ((reqs as Record<string, number>).min_average_score || 0) &&
userStats.perfect_scores >= ((reqs as Record<string, number>).min_perfect_scores || 0)
);
case 'rank':
return this.userReachedRank(userStats.current_rank, (reqs as Record<string, string>).target_rank || '');
case 'ml_coins':
return userStats.ml_coins_earned_total >= ((reqs as Record<string, number>).min_coins_earned || 0);
// =====================================================
// DEFAULT: Tipo no reconocido
// =====================================================
default:
this.logger.warn(`[meetsConditions] Unrecognized condition type: ${type}`);
return false;
}
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
this.logger.error(`[meetsConditions] Error evaluating ${type}: ${errorMsg}`);
return false;
}
}

View File

@ -246,12 +246,17 @@ export class ShopService {
await this.userStatsRepository.save(userStats);
// 9. Crear registro en user_purchases
// discount_applied is the discount amount in ML Coins (integer)
const discountAmount = item.hasActiveDiscount() && item.discount_price
? (item.price - item.discount_price) * quantity
: 0;
const purchase = this.purchaseRepository.create({
user_id: userId,
item_id: itemId,
quantity: quantity,
price_paid: currentPrice,
discount_applied: item.hasActiveDiscount(),
discount_applied: discountAmount,
transaction_id: transaction.id,
status: 'completed',
is_active: true,
@ -304,12 +309,45 @@ export class ShopService {
throw new NotFoundException(`User stats not found for ${userId}`);
}
// Validar rank requerido
// Validar rank requerido (usa rank_order para >= comparacion)
if (item.required_rank) {
if (userStats.current_rank !== item.required_rank) {
throw new BadRequestException(
`Required rank: ${item.required_rank}. Current rank: ${userStats.current_rank}`,
// Consulta directa para obtener rank_order de ambos ranks
const rankQuery = `
SELECT rank_name, rank_order
FROM gamification_system.maya_ranks
WHERE rank_name IN ($1, $2) AND is_active = true
`;
try {
const ranks = await this.userStatsRepository.query(rankQuery, [
item.required_rank,
userStats.current_rank,
]);
const requiredRank = ranks.find(
(r: { rank_name: string; rank_order: number }) =>
r.rank_name === item.required_rank,
);
const userRank = ranks.find(
(r: { rank_name: string; rank_order: number }) =>
r.rank_name === userStats.current_rank,
);
if (!requiredRank || !userRank) {
this.logger.warn(
`Rank validation skipped: requiredRank=${item.required_rank}, userRank=${userStats.current_rank}`,
);
} else if (userRank.rank_order < requiredRank.rank_order) {
// Usuario necesita rank igual o superior (mayor rank_order = rank superior)
throw new BadRequestException(
`Required rank: ${item.required_rank} (or higher). Current rank: ${userStats.current_rank}`,
);
}
} catch (error) {
if (error instanceof BadRequestException) {
throw error;
}
this.logger.error(`Failed to validate rank requirement: ${error}`);
}
}
@ -322,13 +360,12 @@ export class ShopService {
}
}
// Validar achievement requerido (si aplica)
// Validar achievement requerido
// Nota: Para implementar completamente, inyectar AchievementsService
if (item.required_achievement_id) {
// Aquí podrías implementar validación de achievements
// const hasAchievement = await this.achievementsService.hasAchievement(userId, item.required_achievement_id);
// if (!hasAchievement) {
// throw new BadRequestException('Required achievement not unlocked');
// }
this.logger.warn(
`Achievement validation not implemented for item ${item.id}, required achievement: ${item.required_achievement_id}`,
);
}
}

View File

@ -3,6 +3,8 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserStats } from '../entities';
import { UserGamificationSummaryDto } from '../dto/user-gamification-summary.dto';
// CORR-CASCADA-001: Import MayaRank para alinear con entity corregida
import { MayaRank } from '@shared/constants/enums.constants';
/**
* UserStatsService
@ -20,7 +22,14 @@ export class UserStatsService {
private readonly XP_BASE = 100; // Base para cálculo cuadrático
// Rangos disponibles en el sistema (ordenado de menor a mayor)
private readonly RANKS = ['Ajaw', 'Nacom', "Ah K'in", 'Halach Uinic', "K'uk'ulkan"];
// CORR-CASCADA-001: Usar valores de MayaRank enum
private readonly RANKS: MayaRank[] = [
MayaRank.AJAW,
MayaRank.NACOM,
MayaRank.AH_KIN,
MayaRank.HALACH_UINIC,
MayaRank.KUKULKAN,
];
constructor(
@InjectRepository(UserStats, 'gamification')

View File

@ -116,15 +116,15 @@ export class HealthService {
try {
// Critical tables to check across all schemas
// NOTE: auth.users is the correct location (not auth_management.users)
const criticalTables = [
{ schema: 'auth_management', table: 'users', connection: this.authDataSource },
{ schema: 'auth', table: 'users', connection: this.authDataSource },
{ schema: 'auth_management', table: 'profiles', connection: this.authDataSource },
{ schema: 'educational_content', table: 'modules', connection: this.educationalDataSource },
{ schema: 'educational_content', table: 'exercises', connection: this.educationalDataSource },
{ schema: 'gamification_system', table: 'achievements', connection: this.gamificationDataSource },
{ schema: 'progress_tracking', table: 'module_progress', connection: this.progressDataSource },
{ schema: 'social_features', table: 'friendships', connection: this.socialDataSource },
{ schema: 'content_management', table: 'user_content', connection: this.contentDataSource },
{ schema: 'audit_logging', table: 'audit_logs', connection: this.auditDataSource },
];

View File

@ -2,7 +2,7 @@ import { BadRequestException } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate, ValidationError } from 'class-validator';
// Import all 15 DTOs
// Import all 15 DTOs - Module 1, 2, 3
import { WordSearchAnswersDto } from './word-search-answers.dto';
import { TrueFalseAnswersDto } from './true-false-answers.dto';
import { CrucigramaAnswersDto } from './crucigrama-answers.dto';
@ -24,6 +24,24 @@ import { CauseEffectMatchingAnswersDto } from './cause-effect-matching-answers.d
import { MapaConceptualAnswersDto } from './mapa-conceptual-answers.dto';
import { EmparejamientoAnswersDto } from './emparejamiento-answers.dto';
// Import Module 4 DTOs - Lectura Digital y Multimodal (5 ejercicios oficiales)
// @updated 2025-12-18 - LIMPIEZA-M4: Solo ejercicios oficiales según DocumentoDeDiseño v6.1
import {
VerificadorFakeNewsAnswerDto,
InfografiaInteractivaAnswerDto,
QuizTikTokAnswerDto,
NavegacionHipertextualAnswerDto,
AnalisisMemesAnswerDto,
} from '../../../educational/dto/module4';
// Import Module 5 DTOs - Producción y Expresión Lectora (3 ejercicios oficiales)
// @updated 2025-12-18 - CORR-M5: Alineación con DocumentoDeDiseño v6.1
import {
DiarioMultimediaAnswerDto,
VideoCartaAnswerDto,
ComicDigitalAnswerDto,
} from '../../../educational/dto/module5';
/**
* ExerciseAnswerValidator
*
@ -119,14 +137,51 @@ export class ExerciseAnswerValidator {
case 'cause_effect_matching':
return CauseEffectMatchingAnswersDto;
// Module 4 - Lectura Digital y Multimodal
case 'verificador_fake_news':
return VerificadorFakeNewsAnswerDto;
case 'infografia_interactiva':
return InfografiaInteractivaAnswerDto;
case 'quiz_tiktok':
return QuizTikTokAnswerDto;
case 'navegacion_hipertextual':
return NavegacionHipertextualAnswerDto;
case 'analisis_memes':
return AnalisisMemesAnswerDto;
// Module 5 - Producción y Expresión Lectora (3 ejercicios oficiales)
// @updated 2025-12-18 - CORR-M5: Alineación con DocumentoDeDiseño v6.1
case 'diario_multimedia':
return DiarioMultimediaAnswerDto;
case 'comic_digital':
return ComicDigitalAnswerDto;
case 'video_carta':
return VideoCartaAnswerDto;
default:
// @updated 2025-12-18 - Alineación con DocumentoDeDiseño v6.1
// Removidos: podcast, diario_reflexivo (M5), resena_critica, chat_literario, email_formal, ensayo_argumentativo (M4)
throw new BadRequestException(
`Unknown exercise type: ${exerciseType}. ` +
'Valid types: sopa_letras, verdadero_falso, crucigrama, linea_tiempo, completar_espacios, ' +
'mapa_conceptual, emparejamiento, ' +
'Valid types: ' +
// Module 1 - Comprensión Literal
'sopa_letras, verdadero_falso, crucigrama, linea_tiempo, completar_espacios, mapa_conceptual, emparejamiento, ' +
// Module 2 - Comprensión Inferencial
'detective_textual, construccion_hipotesis, prediccion_narrativa, puzzle_contexto, rueda_inferencias, ' +
// Module 3 - Comprensión Crítica
'tribunal_opiniones, analisis_fuentes, debate_digital, podcast_argumentativo, matriz_perspectivas, ' +
'detective_connections, prediction_scenarios, cause_effect_matching',
// Auxiliary types
'detective_connections, prediction_scenarios, cause_effect_matching, ' +
// Module 4 - Lectura Digital (5 oficiales)
'verificador_fake_news, infografia_interactiva, quiz_tiktok, navegacion_hipertextual, analisis_memes, ' +
// Module 5 - Producción Creativa (3 oficiales)
'diario_multimedia, comic_digital, video_carta',
);
}
}

View File

@ -643,6 +643,39 @@ export class ExerciseAttemptService {
this.logger.log('[BUG-002 FIX] ✅ Module progress updated successfully');
// IMPL-002: Si el módulo acaba de completarse por primera vez, incrementar modules_completed en user_stats
if (newStatus === 'completed') {
// Solo incrementar si el módulo no estaba previamente completado
const updateResult = await this.entityManager.query(`
UPDATE gamification_system.user_stats
SET modules_completed = modules_completed + 1,
updated_at = NOW()
WHERE user_id = $1
AND NOT EXISTS (
SELECT 1 FROM progress_tracking.module_progress mp
WHERE mp.user_id = $1 AND mp.module_id = $2
AND mp.status = 'completed'
AND mp.completed_at < NOW() - INTERVAL '5 seconds'
)
`, [userId, moduleId]);
if (updateResult?.[1] > 0) {
this.logger.log(`[IMPL-002] ✅ Incremented modules_completed for user ${userId}`);
}
}
// IMPL-003: Actualizar streak del usuario después de completar ejercicio
try {
await this.entityManager.query(
`SELECT * FROM gamification_system.update_leaderboard_streaks($1)`,
[userId]
);
this.logger.log(`[IMPL-003] ✅ Updated streak for user ${userId}`);
} catch (streakError) {
const streakMsg = streakError instanceof Error ? streakError.message : String(streakError);
this.logger.warn(`[IMPL-003] ⚠️ Could not update streak: ${streakMsg}`);
}
} catch (error) {
// Log error pero no bloquear el claim de rewards
const errorMessage = error instanceof Error ? error.message : String(error);

View File

@ -10,6 +10,7 @@ import { Profile } from '@/modules/auth/entities';
import { UserStatsService } from '@/modules/gamification/services/user-stats.service';
import { MLCoinsService } from '@/modules/gamification/services/ml-coins.service';
import { MissionsService } from '@/modules/gamification/services/missions.service';
import { AchievementsService } from '@/modules/gamification/services/achievements.service';
import { MissionTypeEnum } from '@/modules/gamification/entities/mission.entity';
import { NotificationsService } from '@/modules/notifications/services/notifications.service';
import { MailService } from '@/modules/mail/mail.service';
@ -90,6 +91,7 @@ export class ExerciseSubmissionService {
private readonly userStatsService: UserStatsService,
private readonly mlCoinsService: MLCoinsService,
private readonly missionsService: MissionsService,
private readonly achievementsService: AchievementsService,
private readonly notificationsService: NotificationsService,
private readonly mailService: MailService,
) {}
@ -398,7 +400,19 @@ export class ExerciseSubmissionService {
console.log(`[P1-003] Manual grading applied: ${submission.score}/${submission.max_score}, correct=${submission.is_correct}`);
return this.submissionRepo.save(submission);
const savedSubmission = await this.submissionRepo.save(submission);
// IMPL-004: Detectar y otorgar achievements después de calificación manual
try {
const earned = await this.achievementsService.detectAndGrantEarned(submission.user_id);
if (earned.length > 0) {
console.log(`[IMPL-004] ✅ Granted ${earned.length} achievements to user ${submission.user_id} after manual grading`);
}
} catch (achievementError) {
console.error(`[IMPL-004] ❌ Error detecting achievements: ${achievementError instanceof Error ? achievementError.message : String(achievementError)}`);
}
return savedSubmission;
}
// Default: Auto-grading using SQL validate_and_audit()
@ -446,7 +460,19 @@ export class ExerciseSubmissionService {
}
}
return this.submissionRepo.save(submission);
const savedSubmission = await this.submissionRepo.save(submission);
// IMPL-004: Detectar y otorgar achievements después de auto-grading
try {
const earned = await this.achievementsService.detectAndGrantEarned(submission.user_id);
if (earned.length > 0) {
console.log(`[IMPL-004] ✅ Granted ${earned.length} achievements to user ${submission.user_id} after auto-grading`);
}
} catch (achievementError) {
console.error(`[IMPL-004] ❌ Error detecting achievements: ${achievementError instanceof Error ? achievementError.message : String(achievementError)}`);
}
return savedSubmission;
}
/**

View File

@ -33,9 +33,11 @@ import { AuthRequest } from '@shared/types';
* - POST /api/v1/teacher/reviews/:id/start - Iniciar review (marcar como in_progress)
* - POST /api/v1/teacher/reviews/:id/complete - Completar review
* - POST /api/v1/teacher/reviews/:id/return - Devolver para revisión
*
* NOTA: La ruta base es 'teacher/reviews' porque el prefijo global 'api/v1' se agrega en main.ts
*/
@ApiTags('Teacher - Manual Reviews')
@Controller('api/v1/teacher/reviews')
@Controller('teacher/reviews')
@UseGuards(JwtAuthGuard, RolesGuard)
@ApiBearerAuth()
export class ManualReviewController {

View File

@ -54,9 +54,9 @@ export class AnalyticsService {
private readonly classroomRepository: Repository<Classroom>,
@InjectRepository(ClassroomMember, 'social')
private readonly classroomMemberRepository: Repository<ClassroomMember>,
@InjectRepository(Assignment, 'content')
@InjectRepository(Assignment, 'educational')
private readonly assignmentRepository: Repository<Assignment>,
@InjectRepository(AssignmentSubmission, 'content')
@InjectRepository(AssignmentSubmission, 'educational')
private readonly assignmentSubmissionRepository: Repository<AssignmentSubmission>,
@InjectRepository(UserStats, 'gamification')
private readonly userStatsRepository: Repository<UserStats>,

View File

@ -11,6 +11,8 @@ import { ClassroomMember } from '@modules/social/entities/classroom-member.entit
import { Classroom } from '@modules/social/entities/classroom.entity';
import { Profile } from '@modules/auth/entities/profile.entity';
import { GrantBonusDto, GrantBonusResponseDto } from '../dto/grant-bonus.dto';
// CORR-CASCADA-001: Import MayaRank para alinear con entity corregida
import { MayaRank } from '@shared/constants/enums.constants';
/**
* BonusCoinsService
@ -93,12 +95,13 @@ export class BonusCoinsService {
this.logger.warn(
`UserStats not found for student ${studentId}. Creating initial record.`,
);
// CORR-CASCADA-001: Usar MayaRank enum en lugar de string
userStats = userStatsRepo.create({
user_id: studentId,
level: 1,
total_xp: 0,
xp_to_next_level: 100,
current_rank: 'Ajaw',
current_rank: MayaRank.AJAW,
ml_coins: 100,
ml_coins_earned_total: 100,
ml_coins_spent_total: 0,
@ -217,13 +220,14 @@ export class BonusCoinsService {
* @param userId - ID del usuario (profile.id)
* @returns UserStats creado
*/
// CORR-CASCADA-001: Usar MayaRank enum en lugar de string
private async createInitialUserStats(userId: string): Promise<UserStats> {
const newStats = this.userStatsRepo.create({
user_id: userId,
level: 1,
total_xp: 0,
xp_to_next_level: 100,
current_rank: 'Ajaw',
current_rank: MayaRank.AJAW,
ml_coins: 100, // Balance inicial
ml_coins_earned_total: 100,
ml_coins_spent_total: 0,

View File

@ -372,6 +372,10 @@ export class ExerciseResponsesService {
}
}
// Extract correct answers based on exercise type
// Different exercise types store correct answers in different fields
const correctAnswer = this.extractCorrectAnswers(exerciseContent, row.exercise_type);
return {
id: row.attempt_id,
student_id: row.attempt_user_id,
@ -390,12 +394,117 @@ export class ExerciseResponsesService {
ml_coins_earned: row.attempt_ml_coins_earned,
submitted_at: row.attempt_submitted_at ? new Date(row.attempt_submitted_at).toISOString() : new Date().toISOString(),
// Additional detail fields
correct_answer: exerciseContent?.correct_answers || [],
correct_answer: correctAnswer,
exercise_type: row.exercise_type || 'unknown',
max_score: row.exercise_max_points || 100,
};
}
/**
* Extract correct answers from exercise content based on exercise type
* Different exercise types store correct answers in different fields
*/
private extractCorrectAnswers(content: any, exerciseType: string): Record<string, unknown> {
if (!content) return {};
// Try common correct answer fields first
if (content.correct_answers) {
return { answers: content.correct_answers };
}
// Handle specific exercise types
switch (exerciseType) {
case 'verdadero_falso':
// Extract correct answer from statements
// Return with 'statements' key to match frontend format
// DB stores: stmt.answer (boolean), not correctAnswer or isTrue
if (content.statements && Array.isArray(content.statements)) {
const statements: Record<string, boolean> = {};
content.statements.forEach((stmt: any, idx: number) => {
// Use stmt.id if available, otherwise use index+1
const key = stmt.id ? String(stmt.id) : String(idx + 1);
// Priority: answer (DB field) > correctAnswer > isTrue > false
statements[key] = stmt.answer ?? stmt.correctAnswer ?? stmt.isTrue ?? false;
});
return { statements };
}
break;
case 'completar_espacios':
// Extract correctAnswer from blanks
if (content.blanks && Array.isArray(content.blanks)) {
const blanks: Record<string, string> = {};
content.blanks.forEach((blank: any, idx: number) => {
blanks[String(idx + 1)] = blank.correctAnswer || blank.answer || '';
});
return { blanks };
}
break;
case 'crucigrama':
// Return words/answers for crossword
if (content.words) {
return { words: content.words };
}
if (content.across_clues || content.down_clues) {
const words: Record<string, string> = {};
(content.across_clues || []).forEach((clue: any) => {
if (clue.answer) words[`H${clue.number}`] = clue.answer;
});
(content.down_clues || []).forEach((clue: any) => {
if (clue.answer) words[`V${clue.number}`] = clue.answer;
});
return { words };
}
break;
case 'sopa_letras':
// Return words to find
if (content.words) {
return { foundWords: content.words };
}
break;
case 'lectura_inferencial':
case 'prediccion_narrativa':
case 'puzzle_contexto':
case 'detective_textual':
case 'rueda_inferencias':
case 'causa_efecto':
// Multiple choice - extract from questions
if (content.questions && Array.isArray(content.questions)) {
const answers: Record<string, string | number> = {};
content.questions.forEach((q: any, idx: number) => {
answers[`question_${idx + 1}`] = q.correctAnswer ?? q.correct_answer ?? '';
});
return answers;
}
break;
case 'mapa_conceptual':
// Return expected connections
if (content.connections || content.expectedConnections) {
return { connections: content.connections || content.expectedConnections };
}
break;
case 'timeline':
// Return correct order
if (content.events || content.correctOrder) {
return { events: content.correctOrder || content.events };
}
break;
default:
// Return full content for creative/multimedia exercises (modules 4, 5)
// These don't have "correct" answers, just submitted content
return content;
}
// Fallback: return the full content
return content;
}
/**
* Verify teacher has access to a specific student
*

View File

@ -131,8 +131,9 @@ export class StudentProgressService {
* Get student overview information
*/
async getStudentOverview(studentId: string): Promise<StudentOverview> {
// studentId is actually user_id from frontend (StudentInClassroomDto.user_id)
const profile = await this.profileRepository.findOne({
where: { id: studentId },
where: { user_id: studentId },
});
if (!profile) {
@ -171,8 +172,9 @@ export class StudentProgressService {
* Get student statistics
*/
async getStudentStats(studentId: string): Promise<StudentStats> {
// studentId is actually user_id from frontend
const profile = await this.profileRepository.findOne({
where: { id: studentId },
where: { user_id: studentId },
});
if (!profile) {
@ -239,8 +241,9 @@ export class StudentProgressService {
async getModuleProgress(
studentId: string,
): Promise<ModuleProgressDetail[]> {
// studentId is actually user_id from frontend
const profile = await this.profileRepository.findOne({
where: { id: studentId },
where: { user_id: studentId },
});
if (!profile) {
@ -275,8 +278,9 @@ export class StudentProgressService {
studentId: string,
query: GetStudentProgressQueryDto,
): Promise<ExerciseAttempt[]> {
// studentId is actually user_id from frontend
const profile = await this.profileRepository.findOne({
where: { id: studentId },
where: { user_id: studentId },
});
if (!profile) {
@ -331,8 +335,9 @@ export class StudentProgressService {
* Identify struggle areas for student
*/
async getStruggleAreas(studentId: string): Promise<StruggleArea[]> {
// studentId is actually user_id from frontend
const profile = await this.profileRepository.findOne({
where: { id: studentId },
where: { user_id: studentId },
});
if (!profile) {
@ -486,18 +491,18 @@ export class StudentProgressService {
studentId: string,
teacherId: string,
): Promise<StudentNoteResponseDto[]> {
// Get student profile
// Get student profile - studentId is actually user_id from frontend
const student = await this.profileRepository.findOne({
where: { id: studentId },
where: { user_id: studentId },
});
if (!student) {
throw new NotFoundException(`Student ${studentId} not found`);
}
// Get student user
// Get student user - studentId is the user_id
const studentUser = await this.userRepository.findOne({
where: { id: student.user_id || undefined },
where: { id: studentId },
});
if (!studentUser) {
@ -553,18 +558,18 @@ export class StudentProgressService {
teacherId: string,
noteDto: AddTeacherNoteDto,
): Promise<StudentNoteResponseDto> {
// Get student profile
// Get student profile - studentId is actually user_id from frontend
const student = await this.profileRepository.findOne({
where: { id: studentId },
where: { user_id: studentId },
});
if (!student) {
throw new NotFoundException(`Student ${studentId} not found`);
}
// Get student user
// Get student user - studentId is the user_id
const studentUser = await this.userRepository.findOne({
where: { id: student.user_id || undefined },
where: { id: studentId },
});
if (!studentUser) {

View File

@ -12,8 +12,8 @@ import {
BadRequestException,
ConflictException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, In } from 'typeorm';
import { InjectRepository, InjectDataSource } from '@nestjs/typeorm';
import { Repository, In, DataSource } from 'typeorm';
import { Classroom } from '@modules/social/entities/classroom.entity';
import {
TeacherClassroom,
@ -26,6 +26,7 @@ import { ModuleProgress } from '@modules/progress/entities/module-progress.entit
import { ExerciseSubmission } from '@modules/progress/entities/exercise-submission.entity';
import { Module } from '@modules/educational/entities/module.entity';
import { Exercise } from '@modules/educational/entities/exercise.entity';
import { UserStats } from '@modules/gamification/entities/user-stats.entity';
import {
CreateTeacherClassroomDto,
UpdateTeacherClassroomDto,
@ -86,6 +87,14 @@ export class TeacherClassroomsCrudService {
@InjectRepository(Exercise, 'educational')
private readonly exerciseRepo: Repository<Exercise>,
@InjectRepository(UserStats, 'gamification')
private readonly userStatsRepo: Repository<UserStats>,
// FIX-2025-12-18: Inyectar DataSource para raw SQL en cross-schema joins
// Ver: orchestration/reportes/ANALISIS-ROOT-CAUSE-TYPEORM-CROSSSCHEMA-2025-12-18.md
@InjectDataSource('progress')
private readonly dataSource: DataSource,
) {}
// ============================================================================
@ -234,6 +243,12 @@ export class TeacherClassroomsCrudService {
/**
* Obtiene estudiantes de un classroom
*
* FIX-2025-12-18: Corregido para que búsqueda se aplique ANTES de paginación
* PROBLEMA ANTERIOR: La búsqueda se aplicaba en memoria DESPUÉS de paginar,
* causando que usuarios en página 2 no aparezcan al buscar desde página 1
* SOLUCIÓN: Usar raw SQL para aplicar filtros ANTES de paginar, luego calcular total correcto
* Ver: orchestration/reportes/PLAN-CORRECCION-TEACHER-MONITORING-2025-12-18.md
*
* @param classroomId - ID del classroom
* @param teacherId - ID del teacher (para validación)
* @param query - Parámetros de búsqueda y filtrado
@ -250,39 +265,20 @@ export class TeacherClassroomsCrudService {
// Validar acceso
await this.validateTeacherAccess(teacherId, classroomId);
const { page = 1, limit = 20, search, status, sort_by = 'name', sort_order = 'asc' } = query;
const { page = 1, limit = 100, search, status, sort_by = 'name', sort_order = 'asc' } = query;
// Query base de miembros del classroom
const queryBuilder = this.classroomMemberRepo
.createQueryBuilder('cm')
.where('cm.classroom_id = :classroomId', { classroomId });
// Filtro de estado
if (status && status !== 'all') {
queryBuilder.andWhere('cm.status = :status', { status });
}
// Total de registros (antes de aplicar paginación)
const total = await queryBuilder.getCount();
// Paginación
// FIX: Obtener estudiantes con búsqueda aplicada ANTES de paginación usando raw SQL
const skip = (page - 1) * limit;
queryBuilder.skip(skip).take(limit);
const { students: members, total } = await this.getStudentsWithSearch(
classroomId,
search,
status,
skip,
limit,
);
// Ordenamiento
const orderDirection = sort_order.toUpperCase() as 'ASC' | 'DESC';
if (sort_by === 'last_activity') {
queryBuilder.orderBy('cm.updated_at', orderDirection);
}
// Ejecutar query
const members = await queryBuilder.getMany();
// Obtener IDs de estudiantes
const studentIds = members.map((m) => m.student_id);
if (studentIds.length === 0) {
// No hay estudiantes en el classroom
if (members.length === 0) {
// No hay estudiantes que coincidan con los filtros
const totalPages = Math.ceil(total / limit);
return {
data: [],
@ -297,40 +293,58 @@ export class TeacherClassroomsCrudService {
};
}
// Obtener información de profiles
const profiles = await this.profileRepo.find({
where: { user_id: In(studentIds) },
});
// Obtener IDs de estudiantes
const studentIds = members.map((m) => m.student_id);
// Obtener información de users
const users = await this.userRepo.find({
where: { id: In(studentIds) },
});
// Obtener datos en paralelo: progreso, gamificacion y actividad actual
const [progressData, userStatsData, currentActivityData] = await Promise.all([
this.getStudentsProgress(studentIds),
this.getStudentsUserStats(studentIds),
this.getStudentsCurrentActivity(studentIds),
]);
// Obtener progreso de estudiantes (si aplica)
const progressData = await this.getStudentsProgress(studentIds);
// Mapear a DTO
// Mapear a DTO con todos los datos (members ya incluye profile y user info)
let data = members.map((member) => {
const profile = profiles.find((p) => p.user_id === member.student_id);
const user = users.find((u) => u.id === member.student_id);
const progress = progressData.get(member.student_id);
const userStats = userStatsData.get(member.student_id);
const currentActivity = currentActivityData.get(member.student_id);
return this.mapToStudentInClassroomDto(member, profile, user, progress);
// Reconstruir Profile y User desde los datos del raw SQL
// FIX: Convertir null a undefined para compatibilidad con TypeScript
const profile: Partial<Profile> = {
user_id: member.student_id,
first_name: member.first_name ?? undefined,
last_name: member.last_name ?? undefined,
avatar_url: member.avatar_url ?? undefined,
};
const user: Partial<User> = {
id: member.student_id,
email: member.email ?? undefined,
};
// Reconstruir ClassroomMember desde los datos del raw SQL
const classroomMember: Partial<ClassroomMember> = {
student_id: member.student_id,
classroom_id: classroomId,
status: member.status,
enrollment_date: member.enrollment_date,
attendance_percentage: member.attendance_percentage ?? undefined,
teacher_notes: member.teacher_notes ?? undefined,
updated_at: member.updated_at,
};
return this.mapToStudentInClassroomDto(
classroomMember as ClassroomMember,
profile as Profile,
user as User,
progress,
userStats,
currentActivity,
);
});
// Aplicar filtro de búsqueda en memoria (después de mapear los datos)
if (search) {
const searchLower = search.toLowerCase();
data = data.filter((student) => {
return (
student.full_name.toLowerCase().includes(searchLower) ||
(student.email && student.email.toLowerCase().includes(searchLower))
);
});
}
// Aplicar ordenamiento en memoria si es por nombre o progreso
// Aplicar ordenamiento en memoria (después de tener todos los datos calculados)
if (sort_by === 'name') {
data.sort((a, b) => {
const comparison = a.full_name.localeCompare(b.full_name);
@ -350,9 +364,16 @@ export class TeacherClassroomsCrudService {
const comparison = aScore - bScore;
return sort_order === 'asc' ? comparison : -comparison;
});
} else if (sort_by === 'last_activity') {
data.sort((a, b) => {
const aDate = a.last_activity ? new Date(a.last_activity).getTime() : 0;
const bDate = b.last_activity ? new Date(b.last_activity).getTime() : 0;
const comparison = aDate - bDate;
return sort_order === 'asc' ? comparison : -comparison;
});
}
// Calcular paginación
// Calcular paginación con el total correcto (después de aplicar búsqueda)
const totalPages = Math.ceil(total / limit);
return {
@ -826,6 +847,98 @@ export class TeacherClassroomsCrudService {
// HELPER METHODS
// ============================================================================
/**
* Obtiene estudiantes con búsqueda aplicada ANTES de paginación (raw SQL)
*
* FIX-2025-12-18: Nuevo método que usa raw SQL para cross-schema joins eficientes
* TypeORM QueryBuilder NO soporta cross-schema joins correctamente
* Ver: orchestration/reportes/ANALISIS-ROOT-CAUSE-TYPEORM-CROSSSCHEMA-2025-12-18.md
*
* @private
* @param classroomId - ID del classroom
* @param search - Término de búsqueda (nombre o email)
* @param status - Filtro de estado (active, inactive, suspended, all)
* @param skip - Número de registros a omitir (paginación)
* @param limit - Número de registros a retornar
* @returns Estudiantes filtrados y total de registros (después de aplicar búsqueda)
*/
private async getStudentsWithSearch(
classroomId: string,
search: string | undefined,
status: string | undefined,
skip: number,
limit: number,
): Promise<{
students: Array<{
student_id: string;
status: string;
enrollment_date: Date;
attendance_percentage: number | null;
teacher_notes: string | null;
updated_at: Date;
first_name: string | null;
last_name: string | null;
avatar_url: string | null;
email: string | null;
}>;
total: number;
}> {
// Query para contar total (con filtros aplicados)
const countSql = `
SELECT COUNT(*) as total
FROM social_features.classroom_members cm
LEFT JOIN auth_management.profiles p ON p.user_id = cm.student_id
LEFT JOIN auth.users u ON u.id = cm.student_id
WHERE cm.classroom_id = $1
AND ($2::text IS NULL OR $2 = ''
OR LOWER(COALESCE(p.first_name, '') || ' ' || COALESCE(p.last_name, '')) LIKE LOWER('%' || $2 || '%')
OR LOWER(COALESCE(u.email, '')) LIKE LOWER('%' || $2 || '%'))
AND ($3::text IS NULL OR $3 = 'all' OR cm.status = $3)
`;
// Query para obtener estudiantes (con filtros y paginación)
const studentsSql = `
SELECT
cm.student_id,
cm.status,
cm.enrollment_date,
cm.attendance_percentage,
cm.teacher_notes,
cm.updated_at,
p.first_name,
p.last_name,
p.avatar_url,
u.email
FROM social_features.classroom_members cm
LEFT JOIN auth_management.profiles p ON p.user_id = cm.student_id
LEFT JOIN auth.users u ON u.id = cm.student_id
WHERE cm.classroom_id = $1
AND ($2::text IS NULL OR $2 = ''
OR LOWER(COALESCE(p.first_name, '') || ' ' || COALESCE(p.last_name, '')) LIKE LOWER('%' || $2 || '%')
OR LOWER(COALESCE(u.email, '')) LIKE LOWER('%' || $2 || '%'))
AND ($3::text IS NULL OR $3 = 'all' OR cm.status = $3)
ORDER BY COALESCE(p.first_name, '') || ' ' || COALESCE(p.last_name, '')
LIMIT $4 OFFSET $5
`;
// Preparar parámetros (manejar undefined como null)
const searchParam = search || null;
const statusParam = status || 'all';
// Ejecutar queries en paralelo
const [countResult, studentsResult] = await Promise.all([
this.dataSource.query(countSql, [classroomId, searchParam, statusParam]),
this.dataSource.query(studentsSql, [classroomId, searchParam, statusParam, limit, skip]),
]);
const total = parseInt(countResult[0]?.total || '0');
return {
students: studentsResult,
total,
};
}
/**
* Valida que un teacher tenga acceso a un classroom
*
@ -874,6 +987,130 @@ export class TeacherClassroomsCrudService {
return resultMap;
}
/**
* Obtiene datos de gamificación de UserStats para estudiantes
* CORR-2025-12-18: Nueva función para obtener datos de gamificación
*
* @private
*/
private async getStudentsUserStats(
studentIds: string[],
): Promise<Map<string, {
ml_coins: number;
current_rank: string;
achievements_count: number;
exercises_completed: number;
time_spent_minutes: number;
last_activity_at: Date | null;
}>> {
if (studentIds.length === 0) {
return new Map();
}
const statsData = await this.userStatsRepo.find({
where: { user_id: In(studentIds) },
select: [
'user_id',
'ml_coins',
'current_rank',
'achievements_earned',
'exercises_completed',
'total_time_spent',
'last_activity_at',
],
});
const resultMap = new Map<string, {
ml_coins: number;
current_rank: string;
achievements_count: number;
exercises_completed: number;
time_spent_minutes: number;
last_activity_at: Date | null;
}>();
statsData.forEach((stats) => {
// Convertir interval total_time_spent a minutos
// El formato es "HH:MM:SS" o "X days HH:MM:SS"
let timeMinutes = 0;
if (stats.total_time_spent) {
const timeStr = String(stats.total_time_spent);
// Parsear formato de interval PostgreSQL
if (timeStr.includes('day')) {
const dayMatch = timeStr.match(/(\d+)\s*day/);
const days = dayMatch ? parseInt(dayMatch[1]) : 0;
timeMinutes += days * 24 * 60;
}
const timeMatch = timeStr.match(/(\d+):(\d+):(\d+)/);
if (timeMatch) {
timeMinutes += parseInt(timeMatch[1]) * 60 + parseInt(timeMatch[2]);
}
}
resultMap.set(stats.user_id, {
ml_coins: stats.ml_coins || 0,
current_rank: stats.current_rank || 'Ajaw',
achievements_count: stats.achievements_earned || 0,
exercises_completed: stats.exercises_completed || 0,
time_spent_minutes: timeMinutes,
last_activity_at: stats.last_activity_at || null,
});
});
return resultMap;
}
/**
* Obtiene la actividad actual (módulo y ejercicio) de los estudiantes
*
* FIX-2025-12-18: Corregido para usar raw SQL en lugar de TypeORM QueryBuilder
* PROBLEMA ANTERIOR: .innerJoin('schema.table', ...) NO funciona en TypeORM QueryBuilder
* SOLUCION: Usar raw SQL con this.dataSource.query() para cross-schema joins
* Ver: orchestration/reportes/ANALISIS-ROOT-CAUSE-TYPEORM-CROSSSCHEMA-2025-12-18.md
*
* @private
*/
private async getStudentsCurrentActivity(
studentIds: string[],
): Promise<Map<string, { current_module: string | null; current_exercise: string | null }>> {
if (studentIds.length === 0) {
return new Map();
}
// FIX: Usar raw SQL para cross-schema joins (progress_tracking -> educational_content)
// TypeORM QueryBuilder NO soporta .innerJoin('schema.table', ...) directamente
const sql = `
SELECT DISTINCT ON (es.user_id)
es.user_id,
e.title as exercise_title,
m.title as module_title
FROM progress_tracking.exercise_submissions es
LEFT JOIN educational_content.exercises e ON e.id = es.exercise_id
LEFT JOIN educational_content.modules m ON m.id = e.module_id
WHERE es.user_id = ANY($1)
ORDER BY es.user_id, es.submitted_at DESC
`;
const latestSubmissions = await this.dataSource.query(sql, [studentIds]);
const resultMap = new Map<string, { current_module: string | null; current_exercise: string | null }>();
// Inicializar todos los estudiantes con valores null
studentIds.forEach(id => {
resultMap.set(id, { current_module: null, current_exercise: null });
});
// Actualizar con los datos obtenidos
latestSubmissions.forEach((row: { user_id: string; module_title: string | null; exercise_title: string | null }) => {
resultMap.set(row.user_id, {
current_module: row.module_title || null,
current_exercise: row.exercise_title || null,
});
});
return resultMap;
}
/**
* Calcula estadísticas de progreso
*
@ -887,7 +1124,7 @@ export class TeacherClassroomsCrudService {
.select('AVG(mp.progress_percentage)', 'avg_progress')
.addSelect('AVG(mp.average_score)', 'avg_score') // Fixed: score_percentage → average_score (GAP-ST-001)
.addSelect(
'SUM(CASE WHEN mp.completion_status = :completed THEN 1 ELSE 0 END)',
'SUM(CASE WHEN mp.status = :completed THEN 1 ELSE 0 END)',
'completed_count',
)
.addSelect('COUNT(*)', 'total_count')
@ -957,6 +1194,7 @@ export class TeacherClassroomsCrudService {
/**
* Mapea ClassroomMember a StudentInClassroomDto
* CORR-2025-12-18: Agregados campos de gamificación y actividad actual
*
* @private
*/
@ -965,11 +1203,24 @@ export class TeacherClassroomsCrudService {
profile?: Profile,
user?: User,
progress?: { progress: number; score: number },
userStats?: {
ml_coins: number;
current_rank: string;
achievements_count: number;
exercises_completed: number;
time_spent_minutes: number;
last_activity_at: Date | null;
},
currentActivity?: { current_module: string | null; current_exercise: string | null },
): StudentInClassroomDto {
const fullName = profile
? `${profile.first_name || ''} ${profile.last_name || ''}`.trim()
: 'Unknown Student';
// Obtener total de ejercicios (valor fijo por ahora, se puede calcular dinámicamente)
// TODO: Calcular dinámicamente basado en módulos asignados al classroom
const totalExercises = 50; // Valor aproximado de ejercicios totales
return {
user_id: member.student_id,
full_name: fullName || 'Unknown Student',
@ -977,11 +1228,21 @@ export class TeacherClassroomsCrudService {
avatar: profile?.avatar_url || undefined,
enrollment_date: member.enrollment_date,
status: member.status,
progress_percentage: progress?.progress,
score_average: progress?.score,
last_activity: member.updated_at,
progress_percentage: progress?.progress ?? 0,
score_average: progress?.score ?? 0,
// Usar last_activity_at de UserStats si está disponible, sino usar updated_at del member
last_activity: userStats?.last_activity_at ?? member.updated_at,
attendance_percentage: member.attendance_percentage || undefined,
teacher_notes: member.teacher_notes || undefined,
// CORR-2025-12-18: Nuevos campos de gamificación y actividad
current_module: currentActivity?.current_module ?? null,
current_exercise: currentActivity?.current_exercise ?? null,
time_spent_minutes: userStats?.time_spent_minutes ?? 0,
exercises_completed: userStats?.exercises_completed ?? 0,
exercises_total: totalExercises,
total_ml_coins: userStats?.ml_coins ?? 0,
current_rank: userStats?.current_rank ?? null,
achievements_count: userStats?.achievements_count ?? 0,
};
}

View File

@ -44,7 +44,7 @@ import {
@Injectable()
export class TeacherContentService {
constructor(
@InjectRepository(TeacherContent, 'content')
@InjectRepository(TeacherContent, 'educational')
private readonly contentRepo: Repository<TeacherContent>,
@InjectRepository(Profile, 'auth')

View File

@ -142,8 +142,10 @@ import { ProgressModule } from '@modules/progress/progress.module';
// Entities from 'gamification' datasource
TypeOrmModule.forFeature([UserStats, Achievement, UserAchievement], 'gamification'),
// Entities from 'content' datasource
TypeOrmModule.forFeature([Assignment, AssignmentSubmission, TeacherContent], 'content'),
// Entities from 'educational' datasource (schema: educational_content)
// CORRECTED (2025-12-18): Cambiado de 'content' a 'educational'
// Assignment, AssignmentSubmission y TeacherContent pertenecen a educational_content schema
TypeOrmModule.forFeature([Assignment, AssignmentSubmission, TeacherContent], 'educational'),
// Entities from 'progress' datasource (teacher entities)
TypeOrmModule.forFeature([StudentInterventionAlert], 'progress'),

View File

@ -30,7 +30,7 @@ export const DB_SCHEMAS = {
SYSTEM_CONFIGURATION: 'system_configuration',
LTI_INTEGRATION: 'lti_integration',
STORAGE: 'storage',
AUTH_SUPABASE: 'auth', // Schema de Supabase Auth (diferente de auth_management)
AUTH_BASE: 'auth', // Schema base de autenticación (diferente de auth_management)
} as const;
/**
@ -233,11 +233,11 @@ export const DB_TABLES = {
},
/**
* Auth Base Schema (Supabase)
* Tabla base de usuarios de Supabase (diferente de auth_management)
* Auth Base Schema
* Tabla base de usuarios para autenticación (diferente de auth_management)
*/
AUTH_BASE: {
USERS: 'users', // ✨ NUEVO - P0 (nota: puede no necesitar entidad si usamos Supabase directamente)
USERS: 'users', // ✨ NUEVO - P0
},
/**

View File

@ -253,7 +253,8 @@ export enum TransactionTypeEnum {
/**
* Categorías de logros (achievements)
* @see DDL: achievement_category ENUM
* @see DDL: gamification_system.achievement_category ENUM
* @version 1.1 (2025-12-15) - Agregados 'collection' y 'hidden' para alineación con Frontend
*/
export enum AchievementCategoryEnum {
PROGRESS = 'progress',
@ -263,6 +264,8 @@ export enum AchievementCategoryEnum {
SPECIAL = 'special',
MASTERY = 'mastery',
EXPLORATION = 'exploration',
COLLECTION = 'collection', // v1.1: Logros de colección
HIDDEN = 'hidden', // v1.1: Logros ocultos/secretos
}
/**

View File

@ -79,8 +79,8 @@ El script `create-database.sh` ejecuta los archivos DDL en este orden:
1. **Prerequisites** - Schemas y ENUMs base
2. **Gamilit Schema** - Funciones y vistas compartidas (utilities)
3. **Auth Schema** - Autenticación Supabase
4. **Storage Schema** - Storage Supabase
3. **Auth Schema** - Autenticación base
4. **Storage Schema** - Almacenamiento
5. **Auth Management** - Gestión de usuarios
6. **Educational Content** - Contenido educativo
7. **Gamification System** - Sistema de gamificación

View File

@ -0,0 +1,260 @@
-- ============================================================================
-- GAMILIT - RESPALDO DE USUARIOS DE PRODUCCIÓN
-- Fecha de generación: $(date +%Y-%m-%d)
-- Total de usuarios: 49
-- ============================================================================
--
-- INSTRUCCIONES DE USO:
-- ---------------------
-- 1. Este script debe ejecutarse DESPUÉS de crear el esquema de la base de datos
-- 2. Asegúrate de que los schemas auth, auth_management y gamification_system existan
-- 3. Asegúrate de que el tenant principal exista en auth_management.tenants
--
-- ORDEN DE EJECUCIÓN:
-- 1. Crear base de datos y schemas
-- 2. Ejecutar DDL completo
-- 3. Ejecutar este script
--
-- COMANDO:
-- psql -U gamilit_user -d gamilit_platform -h localhost -f RESTORE_USUARIOS_PRODUCCION.sql
--
-- ============================================================================
-- Desactivar triggers temporalmente para evitar conflictos
SET session_replication_role = replica;
-- ============================================================================
-- SECCIÓN 1: USUARIOS (auth.users)
-- ============================================================================
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'authenticated', NULL, 'teacher@gamilit.com', '$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga', '2025-11-29 13:26:50.289631+00', NULL, '', NULL, '', NULL, '', '', NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"name": "Profesor Testing", "role": "admin_teacher", "description": "Usuario profesor de testing"}', false, '2025-11-29 13:26:50.289631+00', '2025-11-29 13:26:50.289631+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'admin_teacher', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'b017b792-b327-40dd-aefb-a80312776952', 'authenticated', NULL, 'joseal.guirre34@gmail.com', '$2b$10$kb9yCB4Y2WBr2.Gth.wC9e8q8bnkZJ6O2X6kFSn.O4VK8d76Cr/xO', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Aguirre", "first_name": "Jose"}', false, '2025-11-18 07:29:05.226874+00', '2025-11-18 07:29:05.226874+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '06a24962-e83d-4e94-aad7-ff69f20a9119', 'authenticated', NULL, 'sergiojimenezesteban63@gmail.com', '$2b$10$8oPdKN15ndCqCOIt12SEO.2yx4D29kQEQGPCC5rtUYWu8Qp5L7/zW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Jimenez", "first_name": "Sergio"}', false, '2025-11-18 08:17:40.925857+00', '2025-11-18 08:17:40.925857+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '24e8c563-8854-43d1-b3c9-2f83e91f5a1e', 'authenticated', NULL, 'Gomezfornite92@gmail.com', '$2b$10$FuEfoSA0jxvBI2f6odMJqux9Gpgvt7Zjk.plRhRatvK0ykkIXxbI.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Gomez", "first_name": "Hugo"}', false, '2025-11-18 08:18:04.240276+00', '2025-11-18 08:18:04.240276+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'bf0d3e34-e077-43d1-9626-292f7fae2bd6', 'authenticated', NULL, 'Aragon494gt54@icloud.com', '$2b$10$lE8M8qWUIsgYLwcHyRGvTOjxdykLVchRVifsMVqCRCZq3bEeXR.xG', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Aragón", "first_name": "Hugo"}', false, '2025-11-18 08:20:17.228812+00', '2025-11-18 08:20:17.228812+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '2f5a9846-3393-40b2-9e87-0f29238c383f', 'authenticated', NULL, 'blu3wt7@gmail.com', '$2b$10$gKRXQ.rmOePqsNKWdxABQuyIZike2oSsYpdfWpQdi5HHDWDUk.3u2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Valentina", "first_name": "Azul"}', false, '2025-11-18 08:32:17.314233+00', '2025-11-18 08:32:17.314233+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5e738038-1743-4aa9-b222-30171300ea9d', 'authenticated', NULL, 'ricardolugo786@icloud.com', '$2b$10$YV1StKIdCPPED/Ft84zR2ONxj/VzzV7zOxjgwMSbDpd2hzvYOGtby', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Lugo", "first_name": "Ricardo"}', false, '2025-11-18 10:15:06.479774+00', '2025-11-18 10:15:06.479774+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '00c742d9-e5f7-4666-9597-5a8ca54d5478', 'authenticated', NULL, 'marbancarlos916@gmail.com', '$2b$10$PfsKOsEEXpGA6YB6eXNBPePo6OV6Am1glUN6Mkunl64bK/ji6uttW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Marban", "first_name": "Carlos"}', false, '2025-11-18 10:29:05.23842+00', '2025-11-18 10:29:05.23842+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '33306a65-a3b1-41d5-a49d-47989957b822', 'authenticated', NULL, 'diego.colores09@gmail.com', '$2b$10$rFlH9alBbgPGVEZMYIV8p.AkeZ30yRCVd5acasFjIt7fpCZhE6RuO', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Colores", "first_name": "Diego"}', false, '2025-11-18 10:29:20.530359+00', '2025-11-18 10:29:20.530359+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '7a6a973e-83f7-4374-a9fc-54258138115f', 'authenticated', NULL, 'hernandezfonsecabenjamin7@gmail.com', '$2b$10$1E6gLqfMojNLYrSKIbatqOh0pHblZ3jWZwbcxTY/DCx7MGADToCVm', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Hernandez", "first_name": "Benjamin"}', false, '2025-11-18 10:37:06.919813+00', '2025-11-18 10:37:06.919813+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'ccd7135c-0fea-4488-9094-9da52df1c98c', 'authenticated', NULL, 'jr7794315@gmail.com', '$2b$10$Ej/Gwx8mGCWg4TnQSjh1r.QZLw/GkUANqXmz4bEfVaNF9E527L02C', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Reyes", "first_name": "Josue"}', false, '2025-11-18 17:53:39.67958+00', '2025-11-18 17:53:39.67958+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '9951ad75-e9cb-47b3-b478-6bb860ee2530', 'authenticated', NULL, 'barraganfer03@gmail.com', '$2b$10$VJ8bS.ksyKpa7oG575r5YOWQYcq8vwmwTa8jMBkCv0dwskF04SHn2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Barragan", "first_name": "Fernando"}', false, '2025-11-18 20:39:27.408624+00', '2025-11-18 20:39:27.408624+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '735235f5-260a-4c9b-913c-14a1efd083ea', 'authenticated', NULL, 'roman.rebollar.marcoantonio1008@gmail.com', '$2b$10$l4eF8UoOB7D8LKDEzTigXOUO7EABhVdYCqknJ/lD6R4p8uF1R4I.W', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Roman", "first_name": "Marco Antonio"}', false, '2025-11-18 21:03:17.326679+00', '2025-11-18 21:03:17.326679+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'ebe48628-5e44-4562-97b7-b4950b216247', 'authenticated', NULL, 'rodrigoguerrero0914@gmail.com', '$2b$10$ihoy7HbOdlqU38zAddpTOuDO7Nqa8.Cr1dEQjCgMpdb30UwCIMhGW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Guerrero", "first_name": "Rodrigo"}', false, '2025-11-18 21:20:52.303128+00', '2025-11-18 21:20:52.303128+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'd089b1af-462f-4d2c-b0f5-d2528cec8506', 'authenticated', NULL, 'santiagoferrara78@gmail.com', '$2b$10$Wjo3EENjiuddS9BwPMAW1OORZrZpU8ECP9zEXmd4Gvn7orwgjo8O2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 09:21:04.898591+00', '2025-11-24 09:21:04.898591+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'b1cadf36-1f07-46b2-b63d-da72d9b54dc6', 'authenticated', NULL, 'alexanserrv917@gmail.com', '$2b$10$8sT/ObLZUNmiu6CpbceHhenfc7E8zZml8AvB1HUiyOddSLqchggZ2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:26:51.934739+00', '2025-11-24 10:26:51.934739+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'af4d8788-f8a8-4971-bb0d-2f48c150dfc2', 'authenticated', NULL, 'aarizmendi434@gmail.com', '$2b$10$2BAG4EskBG0feGOIva6XyOCBtBJbKJE9h27GU6DmuBH3f.2iK6FoS', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:30:54.728262+00', '2025-11-24 10:30:54.728262+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '26fbc469-10af-4fa3-bd65-e5498188cc4f', 'authenticated', NULL, 'ashernarcisobenitezpalomino@gmail.com', '$2b$10$Bv5vo0GDeseWUWTt.5xV0O9nN93TRVN.vHRigs4vF/ww7Hbnjylam', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:37:35.325342+00', '2025-11-24 10:37:35.325342+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '74ed8c97-ec36-43aa-a1cc-b0c99e4be4e8', 'authenticated', NULL, 'ra.alejandrobm@gmail.com', '$2b$10$QZId3lZBIzBulD7AZCeEKOiL0LBJRekGlQTGiacC70IDwDo2wx7py', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:42:33.424367+00', '2025-11-24 10:42:33.424367+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'f4c46f46-3fb9-40bf-a52b-a8ad2e6a92e1', 'authenticated', NULL, 'abdallahxelhaneriavega@gmail.com', '$2b$10$jQ4SquNUxIO70e7IBYqqLeUw1d.gSCleJ/cwinuWMVlW25a8.pRGG', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:45:19.984994+00', '2025-11-24 10:45:19.984994+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '012adac4-8ffd-47bd-9248-f0c5851e981f', 'authenticated', NULL, '09enriquecampos@gmail.com', '$2b$10$95c9hOplonbo/46O5UlPqummq.AIaGVIZ7YgBstSuOWPbgGersKxy', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:51:54.731982+00', '2025-11-24 10:51:54.731982+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '126b9257-7b0a-4bd6-9ab3-c505ee00e10a', 'authenticated', NULL, 'johhkk22@gmail.com', '$2b$10$Bt6IZ19zuBkly.6QmmPWBeF0kfyVN/O/c3/9bqyUGup3gPZu14DGa', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:53:47.029991+00', '2025-11-24 10:53:47.029991+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '9ac1746e-94a6-4efc-a961-951c015d416e', 'authenticated', NULL, 'edangiel4532@gmail.com', '$2b$10$eZap9LmAws7VtY9sHnS17.RJkhIte5SUobIWaWpuTxTPKjbKgzK.6', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:58:12.790316+00', '2025-11-24 10:58:12.790316+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'authenticated', NULL, 'student@gamilit.com', '$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga', '2025-11-29 13:26:50.289631+00', NULL, '', NULL, '', NULL, '', '', NULL, '2025-12-07 03:42:02.528+00', '{"provider": "email", "providers": ["email"]}', '{"name": "Estudiante Testing", "role": "student", "description": "Usuario estudiante de testing"}', false, '2025-11-29 13:26:50.289631+00', '2025-12-07 03:42:02.529507+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '2d9f05d4-44dd-42cd-97aa-d57bd06fecd0', 'authenticated', NULL, 'erickfranco462@gmail.com', '$2b$10$lNzkSO7zbBHQcJJui0O76.a2artcsZHari4Mgkjo4btGww.Wy9/iC', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:00:11.800551+00', '2025-11-24 11:00:11.800551+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'aff5dcc6-32de-4769-9aaf-eda751fa0866', 'authenticated', NULL, 'gallinainsana@gmail.com', '$2b$10$6y/FVa4LqyliI4PXuBxKpepTRwIIRWybFN0NhcAqRM.Kl/cnvXDMq', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:03:17.536383+00', '2025-11-24 11:03:17.536383+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '0cda1645-83c5-445b-80b7-d0e4d436c00c', 'authenticated', NULL, 'leile5257@gmail.com', '$2b$10$ZZX0.z30VPm7BsLF8bNVweQpRZ2ca/1EPlxdIZy0xNaCFugoKL0ci', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:05:17.75852+00', '2025-11-24 11:05:17.75852+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '1364c463-88de-479b-a883-c0b7b362bcf8', 'authenticated', NULL, 'maximiliano.mejia367@gmail.com', '$2b$10$iTfIWKh2ISvPys2bkK2LOOPI24ua7I47oT8dFxHHYW7AuztoZreQa', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:08:58.232003+00', '2025-11-24 11:08:58.232003+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '547eb778-4782-4681-b198-c731bba36147', 'authenticated', NULL, 'fl432025@gmail.com', '$2b$10$aGKv6yhAWwHb07m3N2DxJOXIn5omkP3t2QeSYblhcDo52pB2ZiFQi', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:12:13.692614+00', '2025-11-24 11:12:13.692614+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5fc06693-e408-4eab-a9a3-fcd5f4e01296', 'authenticated', NULL, '7341023901m@gmail.com', '$2b$10$Z/HUBov20g..LZ6RDYax4.NcDuiFD/gn9Nrt7/OPCPBqCoTJUgr3C', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:15:18.276345+00', '2025-11-24 11:15:18.276345+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5d1839f6-b03f-4e12-b236-eca43f4674f2', 'authenticated', NULL, 'segurauriel235@gmail.com', '$2b$10$IfdhPuUOModgrJT7bMfYkODZkXeTcaAReuCQf9BGpK1cT6GiP9UGu', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:17:46.846963+00', '2025-11-24 11:17:46.846963+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '1b310708-6f24-4c6a-88c9-a11f7a7f9763', 'authenticated', NULL, 'angelrabano11@gmail.com', '$2b$10$Sg6q4kErMvxRlZgWM9lCj.PfRg5sCQrwm763d7sfc3iaAUID7y436', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:47:53.790673+00', '2025-11-24 11:47:53.790673+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '3c613b0e-66f9-4640-a599-c9426d8edffb', 'authenticated', NULL, 'daliaayalareyes35@gmail.com', '$2b$10$dd2SQeBqNIZpZWCGMIDu1O8U6MLpWnKF05w641MNOMzHDZ/U5glCe', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:55:08.708961+00', '2025-11-24 11:55:08.708961+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '7ded133e-9b13-4467-9803-edb813f6a9a1', 'authenticated', NULL, 'alexeimongam@gmail.com', '$2b$10$jyQrHAIj6SsnReQ45FrFlOnDgpZtabskpxPuOYgB/h.YPLyZhuld.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:55:11.906996+00', '2025-11-24 11:55:11.906996+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '4cc04f54-7771-462d-98aa-a94448bb6ff5', 'authenticated', NULL, 'davidocampovenegas@gmail.com', '$2b$10$8COk10WE5.bXFJnAucEA0efcGQKU6KUXKV9N7n32ZX6aNKORs4McW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 14:52:46.468737+00', '2025-11-24 14:52:46.468737+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'fbbe7d19-048c-45e4-8a9c-cf86d2098c35', 'authenticated', NULL, 'zaid080809@gmail.com', '$2b$10$kdaUWR1BUqPRY7H8YkR.xuuDbqtLcvP5yKW.B0ooPlb.I6b/UU192', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 16:25:03.689847+00', '2025-11-24 16:25:03.689847+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5b3d74e8-fd1a-4c80-96d2-24c54bfe90c4', 'authenticated', NULL, 'ruizcruzabrahamfrancisco@gmail.com', '$2b$10$DXHr682C4/VpesiHa7fRrOjKceiWSDUSx.1LZTbsvuxpqCdMNh/Ii', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 19:46:06.311558+00', '2025-11-24 19:46:06.311558+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '615adf6e-dbf3-480f-a907-3cfb3a64c6d2', 'authenticated', NULL, 'vituschinchilla@gmail.com', '$2b$10$dA8adTYlfhgqhZfACcQkFOCYjXdsmggXnIUluNDoh1zRFgQ6pq5O2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 21:07:26.037867+00', '2025-11-24 21:07:26.037867+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'bf445960-4c1f-4e29-8fb7-31667b183d7e', 'authenticated', NULL, 'bryan@betanzos.com', '$2b$10$Xdfuf4Tfog9QKd1FRLL.7eAaD6tr2cXgPx1/L8xqT1kLLzNHzSM26', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 06:13:30.263795+00', '2025-11-25 06:13:30.263795+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'd5fa4905-a78a-4040-8ad8-23220881c6a6', 'authenticated', NULL, 'loganalexander816@gmail.com', '$2b$10$8zLduh/9L/priag.nujz5utuloO9RnNFFDGdKgI2UniFCOwocEPLq', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 07:37:04.953164+00', '2025-11-25 07:37:04.953164+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '71734c15-cdaa-431b-90f5-97a57e0316a8', 'authenticated', NULL, 'carlois1974@gmail.com', '$2b$10$IfLfJ.q59DZgicR07ckSVOcrkkBJe42m1FECXxaoaodKYSo6uj5wW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 07:41:38.025764+00', '2025-11-25 07:41:38.025764+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '1efe491d-98ef-4c02-acd1-3135f7289072', 'authenticated', NULL, 'enriquecuevascbtis136@gmail.com', '$2b$10$9BX3OQMZmHruffBtN.3WPOFoyea6zgPd8i72DvhJ7vRAdqWKax6GS', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 08:16:33.977647+00', '2025-11-25 08:16:33.977647+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5ae21325-7450-4c37-82f1-3f9bcd7b6f45', 'authenticated', NULL, 'omarcitogonzalezzavaleta@gmail.com', '$2b$10$RRk3DAgQdiikxVImFIMqquqB.TNpKs3E.RNFtt1rwwTzO24uShri.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 08:17:07.610076+00', '2025-11-25 08:17:07.610076+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'a4d27774-8a51-4660-ad2f-81d0dfd3a5a7', 'authenticated', NULL, 'gustavobm2024cbtis@gmail.com', '$2b$10$lg7KRUTPofcx4Rtyey8J7.XO0gmdBLCFIfK5uP08mqT0qUIl1aTJq', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 08:20:49.649184+00', '2025-11-25 08:20:49.649184+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '6e30164a-78b0-49b0-bd21-23d7c6c03349', 'authenticated', NULL, 'marianaxsotoxt22@gmail.com', '$2b$10$GQC9yTWiP2vP9GUp0gnhUeLjmw70EI4JQhfJBZbMOlCNXGXb/bt5O', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 08:33:18.150784+00', '2025-11-25 08:33:18.150784+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES (NULL, '0ae1bf21-39e3-4168-9632-457418c7a07d', 'authenticated', NULL, 'rckrdmrd@gmail.com', '$2b$10$LiDdaJLA.ZvdFleamkMuvOcIrW0PQMEh5aVZ5Wg5pzhm7gwc5s.1C', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-09 01:22:42.784+00', NULL, '{}', false, '2025-11-29 13:37:09.271457+00', '2025-12-09 01:22:42.785367+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'authenticated', NULL, 'admin@gamilit.com', '$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga', '2025-11-29 13:26:50.289631+00', NULL, '', NULL, '', NULL, '', '', NULL, '2025-12-01 00:54:19.615+00', '{"provider": "email", "providers": ["email"]}', '{"name": "Admin GAMILIT", "role": "super_admin", "description": "Usuario administrador de testing"}', false, '2025-11-29 13:26:50.289631+00', '2025-12-01 00:54:19.617766+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'super_admin', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES (NULL, '69681b09-5077-4f77-84cc-67606abd9755', 'authenticated', NULL, 'javiermar06@hotmail.com', '$2b$10$3RHyXnR4BG3NaxP8Ez82FuiGDMNCG7GhNaOsMFigy3BpIVOzCqHMW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-14 03:51:04.122+00', NULL, '{}', false, '2025-12-08 19:24:06.266895+00', '2025-12-14 03:51:04.123886+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES (NULL, 'f929d6df-8c29-461f-88f5-264facd879e9', 'authenticated', NULL, 'ju188an@gmail.com', '$2b$10$9vUERFnXApdfXuAI7DFve.aa8uDjI5bfm4CI75/EZ2cUre83RytKe', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-17 23:51:43.553+00', NULL, '{}', false, '2025-12-17 17:51:43.530434+00', '2025-12-17 23:51:43.55475+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
-- ============================================================================
-- SECCIÓN 2: PERFILES (auth_management.profiles)
-- ============================================================================
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Admin GAMILIT', 'Administrador GAMILIT', 'Administrador', 'GAMILIT', 'admin@gamilit.com', '/avatars/admin-testing.png', 'Usuario administrador para testing y desarrollo.', '55-0000-0001', '1985-01-01', NULL, NULL, NULL, 'super_admin', 'active', true, true, '{"theme": "professional", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{"description": "Usuario de testing principal", "testing_user": true}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:50.458823+00', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Profesor Testing', 'Profesor de Testing GAMILIT', 'Profesor', 'Testing', 'teacher@gamilit.com', '/avatars/teacher-testing.png', 'Usuario profesor para testing y desarrollo.', '55-0000-0002', '1980-05-15', NULL, NULL, NULL, 'admin_teacher', 'active', true, true, '{"theme": "teacher", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{"subjects": ["Lengua Española", "Comprensión Lectora"], "testing_user": true}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:50.458823+00', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('cccccccc-cccc-cccc-cccc-cccccccccccc', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Estudiante Testing', 'Estudiante de Testing GAMILIT', 'Estudiante', 'Testing', 'student@gamilit.com', '/avatars/student-testing.png', 'Usuario estudiante para testing y desarrollo.', '55-0000-0003', '2013-09-01', '5', 'EST-TEST-001', NULL, 'student', 'active', true, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "gamification": {"show_rank": true, "show_leaderboard": true, "show_achievements": true}, "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{"interests": ["lectura", "ciencia"], "testing_user": true, "learning_style": "visual"}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:50.458823+00', 'cccccccc-cccc-cccc-cccc-cccccccccccc', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('b017b792-b327-40dd-aefb-a80312776952', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Jose Aguirre', 'Jose Aguirre', 'Jose', 'Aguirre', 'joseal.guirre34@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 07:29:05.229254+00', '2025-11-18 07:29:05.229254+00', 'b017b792-b327-40dd-aefb-a80312776952', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('06a24962-e83d-4e94-aad7-ff69f20a9119', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Sergio Jimenez', 'Sergio Jimenez', 'Sergio', 'Jimenez', 'sergiojimenezesteban63@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 08:17:40.928077+00', '2025-11-18 08:17:40.928077+00', '06a24962-e83d-4e94-aad7-ff69f20a9119', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('24e8c563-8854-43d1-b3c9-2f83e91f5a1e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Hugo Gomez', 'Hugo Gomez', 'Hugo', 'Gomez', 'Gomezfornite92@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 08:18:04.242047+00', '2025-11-18 08:18:04.242047+00', '24e8c563-8854-43d1-b3c9-2f83e91f5a1e', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('bf0d3e34-e077-43d1-9626-292f7fae2bd6', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Hugo Aragón', 'Hugo Aragón', 'Hugo', 'Aragón', 'Aragon494gt54@icloud.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 08:20:17.230714+00', '2025-11-18 08:20:17.230714+00', 'bf0d3e34-e077-43d1-9626-292f7fae2bd6', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('2f5a9846-3393-40b2-9e87-0f29238c383f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Azul Valentina', 'Azul Valentina', 'Azul', 'Valentina', 'blu3wt7@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 08:32:17.315932+00', '2025-11-18 08:32:17.315932+00', '2f5a9846-3393-40b2-9e87-0f29238c383f', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('5e738038-1743-4aa9-b222-30171300ea9d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ricardo Lugo', 'Ricardo Lugo', 'Ricardo', 'Lugo', 'ricardolugo786@icloud.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 10:15:06.481498+00', '2025-11-18 10:15:06.481498+00', '5e738038-1743-4aa9-b222-30171300ea9d', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('00c742d9-e5f7-4666-9597-5a8ca54d5478', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Carlos Marban', 'Carlos Marban', 'Carlos', 'Marban', 'marbancarlos916@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 10:29:05.240413+00', '2025-11-18 10:29:05.240413+00', '00c742d9-e5f7-4666-9597-5a8ca54d5478', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('33306a65-a3b1-41d5-a49d-47989957b822', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Diego Colores', 'Diego Colores', 'Diego', 'Colores', 'diego.colores09@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 10:29:20.531883+00', '2025-11-18 10:29:20.531883+00', '33306a65-a3b1-41d5-a49d-47989957b822', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('7a6a973e-83f7-4374-a9fc-54258138115f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Benjamin Hernandez', 'Benjamin Hernandez', 'Benjamin', 'Hernandez', 'hernandezfonsecabenjamin7@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 10:37:06.9215+00', '2025-11-18 10:37:06.9215+00', '7a6a973e-83f7-4374-a9fc-54258138115f', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('ccd7135c-0fea-4488-9094-9da52df1c98c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Josue Reyes', 'Josue Reyes', 'Josue', 'Reyes', 'jr7794315@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 17:53:39.681271+00', '2025-11-18 17:53:39.681271+00', 'ccd7135c-0fea-4488-9094-9da52df1c98c', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('9951ad75-e9cb-47b3-b478-6bb860ee2530', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Fernando Barragan', 'Fernando Barragan', 'Fernando', 'Barragan', 'barraganfer03@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 20:39:27.410436+00', '2025-11-18 20:39:27.410436+00', '9951ad75-e9cb-47b3-b478-6bb860ee2530', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('735235f5-260a-4c9b-913c-14a1efd083ea', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Marco Antonio Roman', 'Marco Antonio Roman', 'Marco Antonio', 'Roman', 'roman.rebollar.marcoantonio1008@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 21:03:17.328254+00', '2025-11-18 21:03:17.328254+00', '735235f5-260a-4c9b-913c-14a1efd083ea', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('ebe48628-5e44-4562-97b7-b4950b216247', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Rodrigo Guerrero', 'Rodrigo Guerrero', 'Rodrigo', 'Guerrero', 'rodrigoguerrero0914@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 21:20:52.304488+00', '2025-11-18 21:20:52.304488+00', 'ebe48628-5e44-4562-97b7-b4950b216247', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('3f255f44-40d9-4dc9-970c-d50ddec197b3', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'alexanserrv917@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'b1cadf36-1f07-46b2-b63d-da72d9b54dc6', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('f1870075-a6e0-47e7-88c6-793320ab3c8f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'carlois1974@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '71734c15-cdaa-431b-90f5-97a57e0316a8', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('ab2425d9-e2da-49ac-b8db-2db605e7283f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'gustavobm2024cbtis@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'a4d27774-8a51-4660-ad2f-81d0dfd3a5a7', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('802f4d68-bbd0-4220-8218-634975c3774a', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'gallinainsana@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'aff5dcc6-32de-4769-9aaf-eda751fa0866', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('142af777-fce1-4067-b84b-f684e2fa1170', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'zaid080809@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'fbbe7d19-048c-45e4-8a9c-cf86d2098c35', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('b5c2d5dc-e753-40ff-8e01-95c4c497710c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'davidocampovenegas@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '4cc04f54-7771-462d-98aa-a94448bb6ff5', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('d29345bb-fd48-4f69-ac81-eeedd4b41e6d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'marianaxsotoxt22@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '6e30164a-78b0-49b0-bd21-23d7c6c03349', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('813055ff-e5b7-4538-825c-eb721360e189', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'leile5257@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '0cda1645-83c5-445b-80b7-d0e4d436c00c', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('6c9bbb36-0b2d-49ea-9c1b-63209f009773', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'ashernarcisobenitezpalomino@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '26fbc469-10af-4fa3-bd65-e5498188cc4f', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('8daf8ed9-d15f-407f-b827-3a9c01907e62', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'ruizcruzabrahamfrancisco@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '5b3d74e8-fd1a-4c80-96d2-24c54bfe90c4', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('bd028538-520d-45cf-a6f7-27c9f675d663', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'daliaayalareyes35@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '3c613b0e-66f9-4640-a599-c9426d8edffb', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('de1511df-f963-4ff6-8e3f-2225ba493879', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'ra.alejandrobm@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '74ed8c97-ec36-43aa-a1cc-b0c99e4be4e8', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('26168044-3b5c-43f6-a757-833ba1485d41', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'enriquecuevascbtis136@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '1efe491d-98ef-4c02-acd1-3135f7289072', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('e742724a-0ff6-4760-884b-866835460045', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'fl432025@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '547eb778-4782-4681-b198-c731bba36147', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('3ce354c8-bcac-44c6-9a94-5274e5f9b389', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'abdallahxelhaneriavega@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'f4c46f46-3fb9-40bf-a52b-a8ad2e6a92e1', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('188fa4e3-985c-4048-8913-754cb0560875', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', '7341023901m@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '5fc06693-e408-4eab-a9a3-fcd5f4e01296', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('caa05325-b8e7-4b1c-9d95-03d4e0c7372d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'vituschinchilla@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '615adf6e-dbf3-480f-a907-3cfb3a64c6d2', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('128ac756-bdb8-49d7-8fdb-cdb8fd241d06', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'alexeimongam@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '7ded133e-9b13-4467-9803-edb813f6a9a1', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('7f3bb769-4d7e-4ca9-8527-708da0368be5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'angelrabano11@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '1b310708-6f24-4c6a-88c9-a11f7a7f9763', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('6a565d40-9012-4c89-878c-05bb8b6e2d81', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'loganalexander816@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'd5fa4905-a78a-4040-8ad8-23220881c6a6', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('7ede7b67-42d2-44cd-a530-66f62a68cd54', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'bryan@betanzos.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'bf445960-4c1f-4e29-8fb7-31667b183d7e', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('2df90a89-455e-4637-8b96-ad01c45f5701', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'johhkk22@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '126b9257-7b0a-4bd6-9ab3-c505ee00e10a', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('43560c6b-fda2-4b45-bc0b-7dbbbffff05c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'edangiel4532@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '9ac1746e-94a6-4efc-a961-951c015d416e', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('ff4760c8-5359-43e9-9b42-95a0bf3e3d36', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'aarizmendi434@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'af4d8788-f8a8-4971-bb0d-2f48c150dfc2', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('a4c43698-c276-4430-b15e-8373b7bbb662', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'santiagoferrara78@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'd089b1af-462f-4d2c-b0f5-d2528cec8506', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('30462f07-1c6b-4706-b4fb-288845b3631e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', '09enriquecampos@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '012adac4-8ffd-47bd-9248-f0c5851e981f', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('4f5170f2-1d35-4130-a535-1d93383e406b', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'maximiliano.mejia367@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '1364c463-88de-479b-a883-c0b7b362bcf8', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('c0aecfcc-3b2f-4117-9f20-e0920df97dc0', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'segurauriel235@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '5d1839f6-b03f-4e12-b236-eca43f4674f2', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('3dfcdc9d-de8a-45b3-a05f-b83b51097ef5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'omarcitogonzalezzavaleta@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '5ae21325-7450-4c37-82f1-3f9bcd7b6f45', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('bb74b280-db90-4240-ab09-b8c6cf63d553', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'erickfranco462@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '2d9f05d4-44dd-42cd-97aa-d57bd06fecd0', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('0ae1bf21-39e3-4168-9632-457418c7a07d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, 'rckrdmrd@gmail.com', NULL, 'rckrdmrd@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:37:09.278078+00', '2025-11-29 13:37:09.278078+00', '0ae1bf21-39e3-4168-9632-457418c7a07d', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('69681b09-5077-4f77-84cc-67606abd9755', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, 'Javier', ' Mar', 'javiermar06@hotmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-12-08 19:24:06.272257+00', '2025-12-08 19:24:06.272257+00', '69681b09-5077-4f77-84cc-67606abd9755', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('f929d6df-8c29-461f-88f5-264facd879e9', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, 'Juan', 'pa', 'ju188an@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-12-17 17:51:43.536295+00', '2025-12-17 17:51:43.536295+00', 'f929d6df-8c29-461f-88f5-264facd879e9', NULL);
-- ============================================================================
-- SECCIÓN 3: ESTADÍSTICAS DE USUARIOS (gamification_system.user_stats)
-- ============================================================================
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('88b149bb-5f3b-41bb-885f-e226eb9cac22', 'b017b792-b327-40dd-aefb-a80312776952', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('1cb60bdb-800a-4ebc-a9c3-16ecf78d3535', '06a24962-e83d-4e94-aad7-ff69f20a9119', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('5cba623a-015f-41e9-9de0-da67bdd6b5fb', '24e8c563-8854-43d1-b3c9-2f83e91f5a1e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('c6a7e9dd-ade4-4860-a4e0-882fd5aa0ed1', 'bf0d3e34-e077-43d1-9626-292f7fae2bd6', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('ee39d06d-d9c5-492a-9855-2210c74b74fd', 'ccd7135c-0fea-4488-9094-9da52df1c98c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e6be8348-29af-49c4-b49d-4b2d978c951b', 'ebe48628-5e44-4562-97b7-b4950b216247', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('9c4cf796-3768-4182-b1e0-1a38f8187c87', '00c742d9-e5f7-4666-9597-5a8ca54d5478', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 3, 525, 100, 'Nacom', 0.00, 395, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('1f6076c1-7b54-43f7-9fca-519407e65c4f', '2f5a9846-3393-40b2-9e87-0f29238c383f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 2, 150, 100, 'Ajaw', 0.00, 140, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('1bec7e38-0109-4e25-bbad-8e28cdc211a2', '0ae1bf21-39e3-4168-9632-457418c7a07d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 4, 1180, 100, 'Ah K''in', 0.00, 710, 360, 0, 40, '2025-11-29 19:41:58.551+00', 0, 0, NULL, 0, 9, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, '2025-11-29 13:41:42.417785+00', NULL, '{}', '2025-11-29 13:37:09.278078+00', '2025-11-29 13:41:59.942645+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('524efcd5-9c89-4a79-ac4c-f58f92f9fd28', '7a6a973e-83f7-4374-a9fc-54258138115f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 25, 100, 'Ajaw', 0.00, 110, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('5035c591-f320-4182-981a-9a1416030d75', '69681b09-5077-4f77-84cc-67606abd9755', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-12-08 19:24:06.272257+00', '2025-12-08 19:24:06.272257+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('fe110986-762c-459f-acde-b2c865c237bb', '33306a65-a3b1-41d5-a49d-47989957b822', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 75, 100, 'Ajaw', 0.00, 120, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('06fd9e66-cefc-4c64-a446-37cef9668b36', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 2, 375, 100, 'Ajaw', 0.00, 260, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('f0734a0b-1d9c-4999-bcba-8e3b8f229c80', '9951ad75-e9cb-47b3-b478-6bb860ee2530', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 2, 375, 100, 'Ajaw', 0.00, 260, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('7446ef44-11a1-451d-9624-abd95f0eb2ec', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 6, 2525, 100, 'Halach Uinic', 0.00, 1960, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('0145f432-c383-45d1-9d0f-0c7783a48612', '735235f5-260a-4c9b-913c-14a1efd083ea', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 75, 100, 'Ajaw', 0.00, 135, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('c29ffaef-0392-4fe1-ac41-b502a4052111', '5e738038-1743-4aa9-b222-30171300ea9d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 25, 100, 'Ajaw', 0.00, 110, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('762397ff-699f-4bb8-bef6-2e03959fe4c1', '3f255f44-40d9-4dc9-970c-d50ddec197b3', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e8a5e302-93c4-4f6a-8da6-b81ed01dde7a', 'f1870075-a6e0-47e7-88c6-793320ab3c8f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('bc3dda37-e131-45c1-8595-e047eb751a2f', 'ab2425d9-e2da-49ac-b8db-2db605e7283f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('7e0781fc-ab59-4ea4-a57a-3b95b45c151f', '802f4d68-bbd0-4220-8218-634975c3774a', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('5b11ed88-05e5-4edb-94a1-13a9b7a93ec2', '142af777-fce1-4067-b84b-f684e2fa1170', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('f5b9530d-0587-44d5-9bd9-890a1ff8ed26', 'b5c2d5dc-e753-40ff-8e01-95c4c497710c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('82e45270-b5a0-478e-a81f-8330e638921c', 'd29345bb-fd48-4f69-ac81-eeedd4b41e6d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('94ad1072-16af-401b-b32f-3c33fb07c22b', '813055ff-e5b7-4538-825c-eb721360e189', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('a51cd72a-1d76-4367-84ee-5fd448eec673', '6c9bbb36-0b2d-49ea-9c1b-63209f009773', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('9ac32e07-bde6-4d8d-b172-2cf8c28b3cb6', '8daf8ed9-d15f-407f-b827-3a9c01907e62', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('6a89fb69-f4f9-409e-8687-1927a9c9931a', 'bd028538-520d-45cf-a6f7-27c9f675d663', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e08417c1-a015-4820-bab2-0e3bafda8c81', 'de1511df-f963-4ff6-8e3f-2225ba493879', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('27b913c1-b6c1-41a8-ac80-b8aec18dfdcb', '26168044-3b5c-43f6-a757-833ba1485d41', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('d3a33394-f4dc-4e3e-b817-eb6309b17b59', 'e742724a-0ff6-4760-884b-866835460045', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('3e6f2e70-0113-42ae-beaf-f2fed10d70f2', '3ce354c8-bcac-44c6-9a94-5274e5f9b389', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('207b92d0-39d0-4f81-b00d-9119d7a20626', '188fa4e3-985c-4048-8913-754cb0560875', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e0ece833-4e73-4ada-b7d2-25197cf9097d', 'caa05325-b8e7-4b1c-9d95-03d4e0c7372d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e58e13b1-cc53-40da-8ecf-3fa4c2c97672', '128ac756-bdb8-49d7-8fdb-cdb8fd241d06', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('719b10c0-2de5-43a3-b9e4-d38730a92ad2', '7f3bb769-4d7e-4ca9-8527-708da0368be5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('66570bed-28ce-407d-a5df-43236bba500a', '6a565d40-9012-4c89-878c-05bb8b6e2d81', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('f9cb12f8-523f-47c9-b3f3-ac55aac11502', '7ede7b67-42d2-44cd-a530-66f62a68cd54', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('026b8072-f628-4bda-aeda-ce76d2fbccce', '2df90a89-455e-4637-8b96-ad01c45f5701', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('713232b8-54d8-49b8-bcc5-9fabb3bd5c76', '43560c6b-fda2-4b45-bc0b-7dbbbffff05c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('4223a8af-8011-4234-b71d-520c3f7b23b0', 'ff4760c8-5359-43e9-9b42-95a0bf3e3d36', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('b54503c1-f3fd-411d-9830-882aa2c54dc2', 'a4c43698-c276-4430-b15e-8373b7bbb662', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('a657e586-ce3a-4c5c-b244-f704c13fff5e', '30462f07-1c6b-4706-b4fb-288845b3631e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('ce3898e2-403d-4fc1-8bfd-eb78be76b86a', '4f5170f2-1d35-4130-a535-1d93383e406b', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('28dac481-b80a-47c3-9de4-693f2774c470', 'c0aecfcc-3b2f-4117-9f20-e0920df97dc0', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('6732ab00-bca6-4a4b-b9ac-34adfb108299', '3dfcdc9d-de8a-45b3-a05f-b83b51097ef5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('ef81f3a4-9995-4c4c-b2b0-927235077174', 'bb74b280-db90-4240-ab09-b8c6cf63d553', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('b3830215-9623-46a6-9624-2c7183f13737', 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 5, 1825, 100, 'Halach Uinic', 0.00, 1625, 180, 0, 0, NULL, 0, 0, NULL, 0, 8, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, '2025-12-02 10:55:24.674923+00', NULL, '{}', '2025-11-29 13:26:50.458823+00', '2025-12-02 10:55:24.674923+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('5bc3c779-e7f4-4c4a-9bca-c0854ea1e288', 'f929d6df-8c29-461f-88f5-264facd879e9', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-12-17 17:51:43.536295+00', '2025-12-17 17:51:43.536295+00');
-- ============================================================================
-- SECCIÓN 4: RANGOS DE USUARIOS (gamification_system.user_ranks)
-- ============================================================================
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('aef81f6b-b9c4-4f80-b27f-8f9bf8c2cd97', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.458823+00', NULL, true, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:50.458823+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('4cadc6a3-c15e-410a-88f5-c0254463ca8a', 'b017b792-b327-40dd-aefb-a80312776952', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('8c1d72aa-fead-4bff-bf47-b34ceab62a40', '06a24962-e83d-4e94-aad7-ff69f20a9119', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('840cabba-4a80-40fa-a3e0-0e218e09463e', '24e8c563-8854-43d1-b3c9-2f83e91f5a1e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('913ae601-8ab4-4056-864c-517e100bef5b', 'bf0d3e34-e077-43d1-9626-292f7fae2bd6', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('eb382620-70b8-4842-b8cf-ad51eb1c7266', '2f5a9846-3393-40b2-9e87-0f29238c383f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('207ff6ef-a56d-4fc1-942f-5a50e0c842da', '5e738038-1743-4aa9-b222-30171300ea9d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('64946395-a46c-4e93-abf7-5b827e4dcf12', '33306a65-a3b1-41d5-a49d-47989957b822', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('66cb0dd1-2c47-4572-99ec-c97ccee95e53', '7a6a973e-83f7-4374-a9fc-54258138115f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('241b6cea-03d0-4f9c-97b6-7d49d9175cfb', 'ccd7135c-0fea-4488-9094-9da52df1c98c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b14b22be-bd9d-485c-9477-b4122c63cbfb', '9951ad75-e9cb-47b3-b478-6bb860ee2530', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('4e7cf7a1-8ef4-4d20-902b-ba1c57faad51', '735235f5-260a-4c9b-913c-14a1efd083ea', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('d0500d4e-17ec-46be-94a1-4e2500e4b9a8', 'ebe48628-5e44-4562-97b7-b4950b216247', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('9a4e06cc-0a50-4ff9-b781-d29edff7bbd6', '00c742d9-e5f7-4666-9597-5a8ca54d5478', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Nacom', 'Ajaw', 0, NULL, 0, NULL, 0, 100, NULL, NULL, '2025-11-29 13:26:52.138221+00', '2025-11-29 13:26:50.539509+00', true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.138221+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('33b12003-65b0-4f50-8bda-6eeebedc3413', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Halach Uinic', 'Ah K''in', 0, NULL, 0, NULL, 0, 500, NULL, NULL, '2025-11-29 13:26:52.158657+00', '2025-11-29 13:26:52.158657+00', true, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:52.138221+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('7c3b01ab-b75b-4464-8858-91c1ff805c32', '3dfcdc9d-de8a-45b3-a05f-b83b51097ef5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('53ec34ee-bd3c-462f-b5b0-317705c0399d', '3f255f44-40d9-4dc9-970c-d50ddec197b3', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b2461bb7-7107-48dd-923f-de4ff8e86a67', 'e742724a-0ff6-4760-884b-866835460045', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('890ba444-c64f-4680-894d-56bf30cbcf5c', 'f1870075-a6e0-47e7-88c6-793320ab3c8f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('a7b16bb9-efa6-4f10-8fe0-992adbd8c482', 'b5c2d5dc-e753-40ff-8e01-95c4c497710c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('c6eb5dd4-a987-4560-b22d-645ca31791e6', '142af777-fce1-4067-b84b-f684e2fa1170', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('520cd26c-5222-4579-8f1d-72f4be8e98d3', 'c0aecfcc-3b2f-4117-9f20-e0920df97dc0', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('2971dbbf-33de-4f12-9e47-48c9a3b145df', '7ede7b67-42d2-44cd-a530-66f62a68cd54', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('cb9feef2-0f2d-4949-b212-3b6d7dbfe2fa', 'caa05325-b8e7-4b1c-9d95-03d4e0c7372d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('89181d4a-a47b-4449-81fa-09a7e1d67534', 'a4c43698-c276-4430-b15e-8373b7bbb662', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('998f3c88-8932-4d91-af11-7bca6c03bbc3', 'bb74b280-db90-4240-ab09-b8c6cf63d553', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('e22e4620-57fc-47ad-ae53-f45ecc17932f', '4f5170f2-1d35-4130-a535-1d93383e406b', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b9e35a4b-ade2-4fa0-bd58-38ffcf5ca614', '802f4d68-bbd0-4220-8218-634975c3774a', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('365f3ac3-2880-42a8-8799-0c465b0a4ed9', 'de1511df-f963-4ff6-8e3f-2225ba493879', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('21152c4c-b082-40a7-938b-e7486730e2bb', '188fa4e3-985c-4048-8913-754cb0560875', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b1c76243-62c4-4e73-8e7b-152b82e41c93', '128ac756-bdb8-49d7-8fdb-cdb8fd241d06', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('e521b5a1-250b-4e96-a2cd-e8736f1f3fbe', '6c9bbb36-0b2d-49ea-9c1b-63209f009773', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('a106676f-8723-492b-b4f1-1b9256da8a4d', '813055ff-e5b7-4538-825c-eb721360e189', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('8cf5754b-7af4-429f-8e57-b0f2e4f740d6', '3ce354c8-bcac-44c6-9a94-5274e5f9b389', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('89526d39-7d29-4d97-a65b-94a42dfb45e2', 'ab2425d9-e2da-49ac-b8db-2db605e7283f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('fa25a282-3568-481a-878d-c424f6eaee95', 'ff4760c8-5359-43e9-9b42-95a0bf3e3d36', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('aee1d9bf-b4fe-4512-9cf0-4cc90413692e', '8daf8ed9-d15f-407f-b827-3a9c01907e62', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('69621cdf-cc64-4f2b-85f3-d1f09b54cbf0', '7f3bb769-4d7e-4ca9-8527-708da0368be5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b4c93d8d-fb84-4ba2-91d7-78abd5a780de', '26168044-3b5c-43f6-a757-833ba1485d41', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('3444f9aa-7c1b-452c-bfbb-af58dc70e70b', 'bd028538-520d-45cf-a6f7-27c9f675d663', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('c8aec5d3-4a66-40b6-a8e7-9b2edd4225b1', '2df90a89-455e-4637-8b96-ad01c45f5701', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('e284ffd8-9d58-4564-95c4-075721724643', '6a565d40-9012-4c89-878c-05bb8b6e2d81', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('abfa66bf-dc3d-426a-b4ec-538677b39cd5', '43560c6b-fda2-4b45-bc0b-7dbbbffff05c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b26939b5-2dc1-4643-b46c-c4a3d6a5203f', 'd29345bb-fd48-4f69-ac81-eeedd4b41e6d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('564433a1-e5f1-48ce-8807-06f5b9ea1418', '30462f07-1c6b-4706-b4fb-288845b3631e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('3c88a791-ad9b-4988-9351-b5e9df60c9a4', '0ae1bf21-39e3-4168-9632-457418c7a07d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ah K''in', 'Nacom', 0, NULL, 0, NULL, 0, 250, NULL, NULL, '2025-11-29 13:41:42.417785+00', '2025-11-29 13:40:27.516619+00', true, '{}', '2025-11-29 13:37:09.278078+00', '2025-11-29 13:41:42.417785+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('cb04ef70-2738-4c9e-b32a-a92643b8a3f9', 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Halach Uinic', 'Ah K''in', 0, NULL, 0, NULL, 0, 500, NULL, NULL, '2025-11-30 20:12:46.263821+00', '2025-11-29 13:26:52.146305+00', true, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-30 20:12:46.263821+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('1de77cef-003a-4d08-8ccc-8bd4001fa62c', '69681b09-5077-4f77-84cc-67606abd9755', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-12-08 19:24:06.272257+00', NULL, true, '{}', '2025-12-08 19:24:06.272257+00', '2025-12-08 19:24:06.272257+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('63b40546-38a8-4c80-bf11-3504c73150bb', 'f929d6df-8c29-461f-88f5-264facd879e9', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-12-17 17:51:43.536295+00', NULL, true, '{}', '2025-12-17 17:51:43.536295+00', '2025-12-17 17:51:43.536295+00');
-- ============================================================================
-- FINALIZACIÓN
-- ============================================================================
-- Reactivar triggers
SET session_replication_role = DEFAULT;
-- Verificar conteos
SELECT 'auth.users' as tabla, COUNT(*) as registros FROM auth.users
UNION ALL
SELECT 'auth_management.profiles', COUNT(*) FROM auth_management.profiles
UNION ALL
SELECT 'gamification_system.user_stats', COUNT(*) FROM gamification_system.user_stats
UNION ALL
SELECT 'gamification_system.user_ranks', COUNT(*) FROM gamification_system.user_ranks;
-- ============================================================================
-- FIN DEL SCRIPT DE RESTAURACIÓN
-- ============================================================================

View File

@ -0,0 +1,50 @@
instance_id,id,aud,role,email,encrypted_password,email_confirmed_at,invited_at,confirmation_token,confirmation_sent_at,recovery_token,recovery_sent_at,email_change_token_new,email_change,email_change_sent_at,last_sign_in_at,raw_app_meta_data,raw_user_meta_data,is_super_admin,created_at,updated_at,phone,phone_confirmed_at,phone_change,phone_change_token,phone_change_sent_at,confirmed_at,email_change_token_current,email_change_confirm_status,banned_until,reauthentication_token,reauthentication_sent_at,is_sso_user,deleted_at,gamilit_role,status
00000000-0000-0000-0000-000000000000,b017b792-b327-40dd-aefb-a80312776952,authenticated,,joseal.guirre34@gmail.com,$2b$10$kb9yCB4Y2WBr2.Gth.wC9e8q8bnkZJ6O2X6kFSn.O4VK8d76Cr/xO,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Aguirre"", ""first_name"": ""Jose""}",f,2025-11-18 07:29:05.226874+00,2025-11-18 07:29:05.226874+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,06a24962-e83d-4e94-aad7-ff69f20a9119,authenticated,,sergiojimenezesteban63@gmail.com,$2b$10$8oPdKN15ndCqCOIt12SEO.2yx4D29kQEQGPCC5rtUYWu8Qp5L7/zW,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Jimenez"", ""first_name"": ""Sergio""}",f,2025-11-18 08:17:40.925857+00,2025-11-18 08:17:40.925857+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,24e8c563-8854-43d1-b3c9-2f83e91f5a1e,authenticated,,Gomezfornite92@gmail.com,$2b$10$FuEfoSA0jxvBI2f6odMJqux9Gpgvt7Zjk.plRhRatvK0ykkIXxbI.,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Gomez"", ""first_name"": ""Hugo""}",f,2025-11-18 08:18:04.240276+00,2025-11-18 08:18:04.240276+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,bf0d3e34-e077-43d1-9626-292f7fae2bd6,authenticated,,Aragon494gt54@icloud.com,$2b$10$lE8M8qWUIsgYLwcHyRGvTOjxdykLVchRVifsMVqCRCZq3bEeXR.xG,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Aragón"", ""first_name"": ""Hugo""}",f,2025-11-18 08:20:17.228812+00,2025-11-18 08:20:17.228812+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,2f5a9846-3393-40b2-9e87-0f29238c383f,authenticated,,blu3wt7@gmail.com,$2b$10$gKRXQ.rmOePqsNKWdxABQuyIZike2oSsYpdfWpQdi5HHDWDUk.3u2,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Valentina"", ""first_name"": ""Azul""}",f,2025-11-18 08:32:17.314233+00,2025-11-18 08:32:17.314233+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,5e738038-1743-4aa9-b222-30171300ea9d,authenticated,,ricardolugo786@icloud.com,$2b$10$YV1StKIdCPPED/Ft84zR2ONxj/VzzV7zOxjgwMSbDpd2hzvYOGtby,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Lugo"", ""first_name"": ""Ricardo""}",f,2025-11-18 10:15:06.479774+00,2025-11-18 10:15:06.479774+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,00c742d9-e5f7-4666-9597-5a8ca54d5478,authenticated,,marbancarlos916@gmail.com,$2b$10$PfsKOsEEXpGA6YB6eXNBPePo6OV6Am1glUN6Mkunl64bK/ji6uttW,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Marban"", ""first_name"": ""Carlos""}",f,2025-11-18 10:29:05.23842+00,2025-11-18 10:29:05.23842+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,33306a65-a3b1-41d5-a49d-47989957b822,authenticated,,diego.colores09@gmail.com,$2b$10$rFlH9alBbgPGVEZMYIV8p.AkeZ30yRCVd5acasFjIt7fpCZhE6RuO,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Colores"", ""first_name"": ""Diego""}",f,2025-11-18 10:29:20.530359+00,2025-11-18 10:29:20.530359+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,7a6a973e-83f7-4374-a9fc-54258138115f,authenticated,,hernandezfonsecabenjamin7@gmail.com,$2b$10$1E6gLqfMojNLYrSKIbatqOh0pHblZ3jWZwbcxTY/DCx7MGADToCVm,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Hernandez"", ""first_name"": ""Benjamin""}",f,2025-11-18 10:37:06.919813+00,2025-11-18 10:37:06.919813+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,ccd7135c-0fea-4488-9094-9da52df1c98c,authenticated,,jr7794315@gmail.com,$2b$10$Ej/Gwx8mGCWg4TnQSjh1r.QZLw/GkUANqXmz4bEfVaNF9E527L02C,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Reyes"", ""first_name"": ""Josue""}",f,2025-11-18 17:53:39.67958+00,2025-11-18 17:53:39.67958+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,9951ad75-e9cb-47b3-b478-6bb860ee2530,authenticated,,barraganfer03@gmail.com,$2b$10$VJ8bS.ksyKpa7oG575r5YOWQYcq8vwmwTa8jMBkCv0dwskF04SHn2,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Barragan"", ""first_name"": ""Fernando""}",f,2025-11-18 20:39:27.408624+00,2025-11-18 20:39:27.408624+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,735235f5-260a-4c9b-913c-14a1efd083ea,authenticated,,roman.rebollar.marcoantonio1008@gmail.com,$2b$10$l4eF8UoOB7D8LKDEzTigXOUO7EABhVdYCqknJ/lD6R4p8uF1R4I.W,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Roman"", ""first_name"": ""Marco Antonio""}",f,2025-11-18 21:03:17.326679+00,2025-11-18 21:03:17.326679+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,ebe48628-5e44-4562-97b7-b4950b216247,authenticated,,rodrigoguerrero0914@gmail.com,$2b$10$ihoy7HbOdlqU38zAddpTOuDO7Nqa8.Cr1dEQjCgMpdb30UwCIMhGW,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": ""Guerrero"", ""first_name"": ""Rodrigo""}",f,2025-11-18 21:20:52.303128+00,2025-11-18 21:20:52.303128+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,d089b1af-462f-4d2c-b0f5-d2528cec8506,authenticated,,santiagoferrara78@gmail.com,$2b$10$Wjo3EENjiuddS9BwPMAW1OORZrZpU8ECP9zEXmd4Gvn7orwgjo8O2,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 09:21:04.898591+00,2025-11-24 09:21:04.898591+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,b1cadf36-1f07-46b2-b63d-da72d9b54dc6,authenticated,,alexanserrv917@gmail.com,$2b$10$8sT/ObLZUNmiu6CpbceHhenfc7E8zZml8AvB1HUiyOddSLqchggZ2,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 10:26:51.934739+00,2025-11-24 10:26:51.934739+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,af4d8788-f8a8-4971-bb0d-2f48c150dfc2,authenticated,,aarizmendi434@gmail.com,$2b$10$2BAG4EskBG0feGOIva6XyOCBtBJbKJE9h27GU6DmuBH3f.2iK6FoS,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 10:30:54.728262+00,2025-11-24 10:30:54.728262+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,26fbc469-10af-4fa3-bd65-e5498188cc4f,authenticated,,ashernarcisobenitezpalomino@gmail.com,$2b$10$Bv5vo0GDeseWUWTt.5xV0O9nN93TRVN.vHRigs4vF/ww7Hbnjylam,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 10:37:35.325342+00,2025-11-24 10:37:35.325342+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,74ed8c97-ec36-43aa-a1cc-b0c99e4be4e8,authenticated,,ra.alejandrobm@gmail.com,$2b$10$QZId3lZBIzBulD7AZCeEKOiL0LBJRekGlQTGiacC70IDwDo2wx7py,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 10:42:33.424367+00,2025-11-24 10:42:33.424367+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,f4c46f46-3fb9-40bf-a52b-a8ad2e6a92e1,authenticated,,abdallahxelhaneriavega@gmail.com,$2b$10$jQ4SquNUxIO70e7IBYqqLeUw1d.gSCleJ/cwinuWMVlW25a8.pRGG,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 10:45:19.984994+00,2025-11-24 10:45:19.984994+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,012adac4-8ffd-47bd-9248-f0c5851e981f,authenticated,,09enriquecampos@gmail.com,$2b$10$95c9hOplonbo/46O5UlPqummq.AIaGVIZ7YgBstSuOWPbgGersKxy,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 10:51:54.731982+00,2025-11-24 10:51:54.731982+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,126b9257-7b0a-4bd6-9ab3-c505ee00e10a,authenticated,,johhkk22@gmail.com,$2b$10$Bt6IZ19zuBkly.6QmmPWBeF0kfyVN/O/c3/9bqyUGup3gPZu14DGa,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 10:53:47.029991+00,2025-11-24 10:53:47.029991+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,9ac1746e-94a6-4efc-a961-951c015d416e,authenticated,,edangiel4532@gmail.com,$2b$10$eZap9LmAws7VtY9sHnS17.RJkhIte5SUobIWaWpuTxTPKjbKgzK.6,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 10:58:12.790316+00,2025-11-24 10:58:12.790316+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,2d9f05d4-44dd-42cd-97aa-d57bd06fecd0,authenticated,,erickfranco462@gmail.com,$2b$10$lNzkSO7zbBHQcJJui0O76.a2artcsZHari4Mgkjo4btGww.Wy9/iC,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:00:11.800551+00,2025-11-24 11:00:11.800551+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,aff5dcc6-32de-4769-9aaf-eda751fa0866,authenticated,,gallinainsana@gmail.com,$2b$10$6y/FVa4LqyliI4PXuBxKpepTRwIIRWybFN0NhcAqRM.Kl/cnvXDMq,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:03:17.536383+00,2025-11-24 11:03:17.536383+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,0cda1645-83c5-445b-80b7-d0e4d436c00c,authenticated,,leile5257@gmail.com,$2b$10$ZZX0.z30VPm7BsLF8bNVweQpRZ2ca/1EPlxdIZy0xNaCFugoKL0ci,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:05:17.75852+00,2025-11-24 11:05:17.75852+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,1364c463-88de-479b-a883-c0b7b362bcf8,authenticated,,maximiliano.mejia367@gmail.com,$2b$10$iTfIWKh2ISvPys2bkK2LOOPI24ua7I47oT8dFxHHYW7AuztoZreQa,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:08:58.232003+00,2025-11-24 11:08:58.232003+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,547eb778-4782-4681-b198-c731bba36147,authenticated,,fl432025@gmail.com,$2b$10$aGKv6yhAWwHb07m3N2DxJOXIn5omkP3t2QeSYblhcDo52pB2ZiFQi,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:12:13.692614+00,2025-11-24 11:12:13.692614+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,5fc06693-e408-4eab-a9a3-fcd5f4e01296,authenticated,,7341023901m@gmail.com,$2b$10$Z/HUBov20g..LZ6RDYax4.NcDuiFD/gn9Nrt7/OPCPBqCoTJUgr3C,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:15:18.276345+00,2025-11-24 11:15:18.276345+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,5d1839f6-b03f-4e12-b236-eca43f4674f2,authenticated,,segurauriel235@gmail.com,$2b$10$IfdhPuUOModgrJT7bMfYkODZkXeTcaAReuCQf9BGpK1cT6GiP9UGu,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:17:46.846963+00,2025-11-24 11:17:46.846963+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,1b310708-6f24-4c6a-88c9-a11f7a7f9763,authenticated,,angelrabano11@gmail.com,$2b$10$Sg6q4kErMvxRlZgWM9lCj.PfRg5sCQrwm763d7sfc3iaAUID7y436,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:47:53.790673+00,2025-11-24 11:47:53.790673+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,3c613b0e-66f9-4640-a599-c9426d8edffb,authenticated,,daliaayalareyes35@gmail.com,$2b$10$dd2SQeBqNIZpZWCGMIDu1O8U6MLpWnKF05w641MNOMzHDZ/U5glCe,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:55:08.708961+00,2025-11-24 11:55:08.708961+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,7ded133e-9b13-4467-9803-edb813f6a9a1,authenticated,,alexeimongam@gmail.com,$2b$10$jyQrHAIj6SsnReQ45FrFlOnDgpZtabskpxPuOYgB/h.YPLyZhuld.,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 11:55:11.906996+00,2025-11-24 11:55:11.906996+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,4cc04f54-7771-462d-98aa-a94448bb6ff5,authenticated,,davidocampovenegas@gmail.com,$2b$10$8COk10WE5.bXFJnAucEA0efcGQKU6KUXKV9N7n32ZX6aNKORs4McW,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 14:52:46.468737+00,2025-11-24 14:52:46.468737+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,fbbe7d19-048c-45e4-8a9c-cf86d2098c35,authenticated,,zaid080809@gmail.com,$2b$10$kdaUWR1BUqPRY7H8YkR.xuuDbqtLcvP5yKW.B0ooPlb.I6b/UU192,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 16:25:03.689847+00,2025-11-24 16:25:03.689847+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,5b3d74e8-fd1a-4c80-96d2-24c54bfe90c4,authenticated,,ruizcruzabrahamfrancisco@gmail.com,$2b$10$DXHr682C4/VpesiHa7fRrOjKceiWSDUSx.1LZTbsvuxpqCdMNh/Ii,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 19:46:06.311558+00,2025-11-24 19:46:06.311558+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,615adf6e-dbf3-480f-a907-3cfb3a64c6d2,authenticated,,vituschinchilla@gmail.com,$2b$10$dA8adTYlfhgqhZfACcQkFOCYjXdsmggXnIUluNDoh1zRFgQ6pq5O2,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-24 21:07:26.037867+00,2025-11-24 21:07:26.037867+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,bf445960-4c1f-4e29-8fb7-31667b183d7e,authenticated,,bryan@betanzos.com,$2b$10$Xdfuf4Tfog9QKd1FRLL.7eAaD6tr2cXgPx1/L8xqT1kLLzNHzSM26,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-25 06:13:30.263795+00,2025-11-25 06:13:30.263795+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,d5fa4905-a78a-4040-8ad8-23220881c6a6,authenticated,,loganalexander816@gmail.com,$2b$10$8zLduh/9L/priag.nujz5utuloO9RnNFFDGdKgI2UniFCOwocEPLq,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-25 07:37:04.953164+00,2025-11-25 07:37:04.953164+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,71734c15-cdaa-431b-90f5-97a57e0316a8,authenticated,,carlois1974@gmail.com,$2b$10$IfLfJ.q59DZgicR07ckSVOcrkkBJe42m1FECXxaoaodKYSo6uj5wW,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-25 07:41:38.025764+00,2025-11-25 07:41:38.025764+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,1efe491d-98ef-4c02-acd1-3135f7289072,authenticated,,enriquecuevascbtis136@gmail.com,$2b$10$9BX3OQMZmHruffBtN.3WPOFoyea6zgPd8i72DvhJ7vRAdqWKax6GS,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-25 08:16:33.977647+00,2025-11-25 08:16:33.977647+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,5ae21325-7450-4c37-82f1-3f9bcd7b6f45,authenticated,,omarcitogonzalezzavaleta@gmail.com,$2b$10$RRk3DAgQdiikxVImFIMqquqB.TNpKs3E.RNFtt1rwwTzO24uShri.,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-25 08:17:07.610076+00,2025-11-25 08:17:07.610076+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,a4d27774-8a51-4660-ad2f-81d0dfd3a5a7,authenticated,,gustavobm2024cbtis@gmail.com,$2b$10$lg7KRUTPofcx4Rtyey8J7.XO0gmdBLCFIfK5uP08mqT0qUIl1aTJq,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-25 08:20:49.649184+00,2025-11-25 08:20:49.649184+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,6e30164a-78b0-49b0-bd21-23d7c6c03349,authenticated,,marianaxsotoxt22@gmail.com,$2b$10$GQC9yTWiP2vP9GUp0gnhUeLjmw70EI4JQhfJBZbMOlCNXGXb/bt5O,,,,,,,,,,,"{""provider"": ""email"", ""providers"": [""email""]}","{""last_name"": """", ""first_name"": """"}",f,2025-11-25 08:33:18.150784+00,2025-11-25 08:33:18.150784+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,cccccccc-cccc-cccc-cccc-cccccccccccc,authenticated,,student@gamilit.com,$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga,2025-11-29 13:26:50.289631+00,,"",,"",,"","",,2025-12-07 03:42:02.528+00,"{""provider"": ""email"", ""providers"": [""email""]}","{""name"": ""Estudiante Testing"", ""role"": ""student"", ""description"": ""Usuario estudiante de testing""}",f,2025-11-29 13:26:50.289631+00,2025-12-07 03:42:02.529507+00,,,,,,,,0,,,,f,,student,active
00000000-0000-0000-0000-000000000000,bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,authenticated,,teacher@gamilit.com,$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga,2025-11-29 13:26:50.289631+00,,"",,"",,"","",,,"{""provider"": ""email"", ""providers"": [""email""]}","{""name"": ""Profesor Testing"", ""role"": ""admin_teacher"", ""description"": ""Usuario profesor de testing""}",f,2025-11-29 13:26:50.289631+00,2025-11-29 13:26:50.289631+00,,,,,,,,0,,,,f,,admin_teacher,active
00000000-0000-0000-0000-000000000000,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,authenticated,,admin@gamilit.com,$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga,2025-11-29 13:26:50.289631+00,,"",,"",,"","",,2025-12-01 00:54:19.615+00,"{""provider"": ""email"", ""providers"": [""email""]}","{""name"": ""Admin GAMILIT"", ""role"": ""super_admin"", ""description"": ""Usuario administrador de testing""}",f,2025-11-29 13:26:50.289631+00,2025-12-01 00:54:19.617766+00,,,,,,,,0,,,,f,,super_admin,active
,0ae1bf21-39e3-4168-9632-457418c7a07d,authenticated,,rckrdmrd@gmail.com,$2b$10$LiDdaJLA.ZvdFleamkMuvOcIrW0PQMEh5aVZ5Wg5pzhm7gwc5s.1C,,,,,,,,,,2025-12-09 01:22:42.784+00,,{},f,2025-11-29 13:37:09.271457+00,2025-12-09 01:22:42.785367+00,,,,,,,,0,,,,f,,student,active
,69681b09-5077-4f77-84cc-67606abd9755,authenticated,,javiermar06@hotmail.com,$2b$10$3RHyXnR4BG3NaxP8Ez82FuiGDMNCG7GhNaOsMFigy3BpIVOzCqHMW,,,,,,,,,,2025-12-14 03:51:04.122+00,,{},f,2025-12-08 19:24:06.266895+00,2025-12-14 03:51:04.123886+00,,,,,,,,0,,,,f,,student,active
,f929d6df-8c29-461f-88f5-264facd879e9,authenticated,,ju188an@gmail.com,$2b$10$9vUERFnXApdfXuAI7DFve.aa8uDjI5bfm4CI75/EZ2cUre83RytKe,,,,,,,,,,2025-12-17 23:51:43.553+00,,{},f,2025-12-17 17:51:43.530434+00,2025-12-17 23:51:43.55475+00,,,,,,,,0,,,,f,,student,active
1 instance_id id aud role email encrypted_password email_confirmed_at invited_at confirmation_token confirmation_sent_at recovery_token recovery_sent_at email_change_token_new email_change email_change_sent_at last_sign_in_at raw_app_meta_data raw_user_meta_data is_super_admin created_at updated_at phone phone_confirmed_at phone_change phone_change_token phone_change_sent_at confirmed_at email_change_token_current email_change_confirm_status banned_until reauthentication_token reauthentication_sent_at is_sso_user deleted_at gamilit_role status
2 00000000-0000-0000-0000-000000000000 b017b792-b327-40dd-aefb-a80312776952 authenticated joseal.guirre34@gmail.com $2b$10$kb9yCB4Y2WBr2.Gth.wC9e8q8bnkZJ6O2X6kFSn.O4VK8d76Cr/xO {"provider": "email", "providers": ["email"]} {"last_name": "Aguirre", "first_name": "Jose"} f 2025-11-18 07:29:05.226874+00 2025-11-18 07:29:05.226874+00 0 f student active
3 00000000-0000-0000-0000-000000000000 06a24962-e83d-4e94-aad7-ff69f20a9119 authenticated sergiojimenezesteban63@gmail.com $2b$10$8oPdKN15ndCqCOIt12SEO.2yx4D29kQEQGPCC5rtUYWu8Qp5L7/zW {"provider": "email", "providers": ["email"]} {"last_name": "Jimenez", "first_name": "Sergio"} f 2025-11-18 08:17:40.925857+00 2025-11-18 08:17:40.925857+00 0 f student active
4 00000000-0000-0000-0000-000000000000 24e8c563-8854-43d1-b3c9-2f83e91f5a1e authenticated Gomezfornite92@gmail.com $2b$10$FuEfoSA0jxvBI2f6odMJqux9Gpgvt7Zjk.plRhRatvK0ykkIXxbI. {"provider": "email", "providers": ["email"]} {"last_name": "Gomez", "first_name": "Hugo"} f 2025-11-18 08:18:04.240276+00 2025-11-18 08:18:04.240276+00 0 f student active
5 00000000-0000-0000-0000-000000000000 bf0d3e34-e077-43d1-9626-292f7fae2bd6 authenticated Aragon494gt54@icloud.com $2b$10$lE8M8qWUIsgYLwcHyRGvTOjxdykLVchRVifsMVqCRCZq3bEeXR.xG {"provider": "email", "providers": ["email"]} {"last_name": "Aragón", "first_name": "Hugo"} f 2025-11-18 08:20:17.228812+00 2025-11-18 08:20:17.228812+00 0 f student active
6 00000000-0000-0000-0000-000000000000 2f5a9846-3393-40b2-9e87-0f29238c383f authenticated blu3wt7@gmail.com $2b$10$gKRXQ.rmOePqsNKWdxABQuyIZike2oSsYpdfWpQdi5HHDWDUk.3u2 {"provider": "email", "providers": ["email"]} {"last_name": "Valentina", "first_name": "Azul"} f 2025-11-18 08:32:17.314233+00 2025-11-18 08:32:17.314233+00 0 f student active
7 00000000-0000-0000-0000-000000000000 5e738038-1743-4aa9-b222-30171300ea9d authenticated ricardolugo786@icloud.com $2b$10$YV1StKIdCPPED/Ft84zR2ONxj/VzzV7zOxjgwMSbDpd2hzvYOGtby {"provider": "email", "providers": ["email"]} {"last_name": "Lugo", "first_name": "Ricardo"} f 2025-11-18 10:15:06.479774+00 2025-11-18 10:15:06.479774+00 0 f student active
8 00000000-0000-0000-0000-000000000000 00c742d9-e5f7-4666-9597-5a8ca54d5478 authenticated marbancarlos916@gmail.com $2b$10$PfsKOsEEXpGA6YB6eXNBPePo6OV6Am1glUN6Mkunl64bK/ji6uttW {"provider": "email", "providers": ["email"]} {"last_name": "Marban", "first_name": "Carlos"} f 2025-11-18 10:29:05.23842+00 2025-11-18 10:29:05.23842+00 0 f student active
9 00000000-0000-0000-0000-000000000000 33306a65-a3b1-41d5-a49d-47989957b822 authenticated diego.colores09@gmail.com $2b$10$rFlH9alBbgPGVEZMYIV8p.AkeZ30yRCVd5acasFjIt7fpCZhE6RuO {"provider": "email", "providers": ["email"]} {"last_name": "Colores", "first_name": "Diego"} f 2025-11-18 10:29:20.530359+00 2025-11-18 10:29:20.530359+00 0 f student active
10 00000000-0000-0000-0000-000000000000 7a6a973e-83f7-4374-a9fc-54258138115f authenticated hernandezfonsecabenjamin7@gmail.com $2b$10$1E6gLqfMojNLYrSKIbatqOh0pHblZ3jWZwbcxTY/DCx7MGADToCVm {"provider": "email", "providers": ["email"]} {"last_name": "Hernandez", "first_name": "Benjamin"} f 2025-11-18 10:37:06.919813+00 2025-11-18 10:37:06.919813+00 0 f student active
11 00000000-0000-0000-0000-000000000000 ccd7135c-0fea-4488-9094-9da52df1c98c authenticated jr7794315@gmail.com $2b$10$Ej/Gwx8mGCWg4TnQSjh1r.QZLw/GkUANqXmz4bEfVaNF9E527L02C {"provider": "email", "providers": ["email"]} {"last_name": "Reyes", "first_name": "Josue"} f 2025-11-18 17:53:39.67958+00 2025-11-18 17:53:39.67958+00 0 f student active
12 00000000-0000-0000-0000-000000000000 9951ad75-e9cb-47b3-b478-6bb860ee2530 authenticated barraganfer03@gmail.com $2b$10$VJ8bS.ksyKpa7oG575r5YOWQYcq8vwmwTa8jMBkCv0dwskF04SHn2 {"provider": "email", "providers": ["email"]} {"last_name": "Barragan", "first_name": "Fernando"} f 2025-11-18 20:39:27.408624+00 2025-11-18 20:39:27.408624+00 0 f student active
13 00000000-0000-0000-0000-000000000000 735235f5-260a-4c9b-913c-14a1efd083ea authenticated roman.rebollar.marcoantonio1008@gmail.com $2b$10$l4eF8UoOB7D8LKDEzTigXOUO7EABhVdYCqknJ/lD6R4p8uF1R4I.W {"provider": "email", "providers": ["email"]} {"last_name": "Roman", "first_name": "Marco Antonio"} f 2025-11-18 21:03:17.326679+00 2025-11-18 21:03:17.326679+00 0 f student active
14 00000000-0000-0000-0000-000000000000 ebe48628-5e44-4562-97b7-b4950b216247 authenticated rodrigoguerrero0914@gmail.com $2b$10$ihoy7HbOdlqU38zAddpTOuDO7Nqa8.Cr1dEQjCgMpdb30UwCIMhGW {"provider": "email", "providers": ["email"]} {"last_name": "Guerrero", "first_name": "Rodrigo"} f 2025-11-18 21:20:52.303128+00 2025-11-18 21:20:52.303128+00 0 f student active
15 00000000-0000-0000-0000-000000000000 d089b1af-462f-4d2c-b0f5-d2528cec8506 authenticated santiagoferrara78@gmail.com $2b$10$Wjo3EENjiuddS9BwPMAW1OORZrZpU8ECP9zEXmd4Gvn7orwgjo8O2 {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 09:21:04.898591+00 2025-11-24 09:21:04.898591+00 0 f student active
16 00000000-0000-0000-0000-000000000000 b1cadf36-1f07-46b2-b63d-da72d9b54dc6 authenticated alexanserrv917@gmail.com $2b$10$8sT/ObLZUNmiu6CpbceHhenfc7E8zZml8AvB1HUiyOddSLqchggZ2 {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 10:26:51.934739+00 2025-11-24 10:26:51.934739+00 0 f student active
17 00000000-0000-0000-0000-000000000000 af4d8788-f8a8-4971-bb0d-2f48c150dfc2 authenticated aarizmendi434@gmail.com $2b$10$2BAG4EskBG0feGOIva6XyOCBtBJbKJE9h27GU6DmuBH3f.2iK6FoS {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 10:30:54.728262+00 2025-11-24 10:30:54.728262+00 0 f student active
18 00000000-0000-0000-0000-000000000000 26fbc469-10af-4fa3-bd65-e5498188cc4f authenticated ashernarcisobenitezpalomino@gmail.com $2b$10$Bv5vo0GDeseWUWTt.5xV0O9nN93TRVN.vHRigs4vF/ww7Hbnjylam {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 10:37:35.325342+00 2025-11-24 10:37:35.325342+00 0 f student active
19 00000000-0000-0000-0000-000000000000 74ed8c97-ec36-43aa-a1cc-b0c99e4be4e8 authenticated ra.alejandrobm@gmail.com $2b$10$QZId3lZBIzBulD7AZCeEKOiL0LBJRekGlQTGiacC70IDwDo2wx7py {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 10:42:33.424367+00 2025-11-24 10:42:33.424367+00 0 f student active
20 00000000-0000-0000-0000-000000000000 f4c46f46-3fb9-40bf-a52b-a8ad2e6a92e1 authenticated abdallahxelhaneriavega@gmail.com $2b$10$jQ4SquNUxIO70e7IBYqqLeUw1d.gSCleJ/cwinuWMVlW25a8.pRGG {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 10:45:19.984994+00 2025-11-24 10:45:19.984994+00 0 f student active
21 00000000-0000-0000-0000-000000000000 012adac4-8ffd-47bd-9248-f0c5851e981f authenticated 09enriquecampos@gmail.com $2b$10$95c9hOplonbo/46O5UlPqummq.AIaGVIZ7YgBstSuOWPbgGersKxy {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 10:51:54.731982+00 2025-11-24 10:51:54.731982+00 0 f student active
22 00000000-0000-0000-0000-000000000000 126b9257-7b0a-4bd6-9ab3-c505ee00e10a authenticated johhkk22@gmail.com $2b$10$Bt6IZ19zuBkly.6QmmPWBeF0kfyVN/O/c3/9bqyUGup3gPZu14DGa {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 10:53:47.029991+00 2025-11-24 10:53:47.029991+00 0 f student active
23 00000000-0000-0000-0000-000000000000 9ac1746e-94a6-4efc-a961-951c015d416e authenticated edangiel4532@gmail.com $2b$10$eZap9LmAws7VtY9sHnS17.RJkhIte5SUobIWaWpuTxTPKjbKgzK.6 {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 10:58:12.790316+00 2025-11-24 10:58:12.790316+00 0 f student active
24 00000000-0000-0000-0000-000000000000 2d9f05d4-44dd-42cd-97aa-d57bd06fecd0 authenticated erickfranco462@gmail.com $2b$10$lNzkSO7zbBHQcJJui0O76.a2artcsZHari4Mgkjo4btGww.Wy9/iC {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:00:11.800551+00 2025-11-24 11:00:11.800551+00 0 f student active
25 00000000-0000-0000-0000-000000000000 aff5dcc6-32de-4769-9aaf-eda751fa0866 authenticated gallinainsana@gmail.com $2b$10$6y/FVa4LqyliI4PXuBxKpepTRwIIRWybFN0NhcAqRM.Kl/cnvXDMq {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:03:17.536383+00 2025-11-24 11:03:17.536383+00 0 f student active
26 00000000-0000-0000-0000-000000000000 0cda1645-83c5-445b-80b7-d0e4d436c00c authenticated leile5257@gmail.com $2b$10$ZZX0.z30VPm7BsLF8bNVweQpRZ2ca/1EPlxdIZy0xNaCFugoKL0ci {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:05:17.75852+00 2025-11-24 11:05:17.75852+00 0 f student active
27 00000000-0000-0000-0000-000000000000 1364c463-88de-479b-a883-c0b7b362bcf8 authenticated maximiliano.mejia367@gmail.com $2b$10$iTfIWKh2ISvPys2bkK2LOOPI24ua7I47oT8dFxHHYW7AuztoZreQa {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:08:58.232003+00 2025-11-24 11:08:58.232003+00 0 f student active
28 00000000-0000-0000-0000-000000000000 547eb778-4782-4681-b198-c731bba36147 authenticated fl432025@gmail.com $2b$10$aGKv6yhAWwHb07m3N2DxJOXIn5omkP3t2QeSYblhcDo52pB2ZiFQi {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:12:13.692614+00 2025-11-24 11:12:13.692614+00 0 f student active
29 00000000-0000-0000-0000-000000000000 5fc06693-e408-4eab-a9a3-fcd5f4e01296 authenticated 7341023901m@gmail.com $2b$10$Z/HUBov20g..LZ6RDYax4.NcDuiFD/gn9Nrt7/OPCPBqCoTJUgr3C {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:15:18.276345+00 2025-11-24 11:15:18.276345+00 0 f student active
30 00000000-0000-0000-0000-000000000000 5d1839f6-b03f-4e12-b236-eca43f4674f2 authenticated segurauriel235@gmail.com $2b$10$IfdhPuUOModgrJT7bMfYkODZkXeTcaAReuCQf9BGpK1cT6GiP9UGu {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:17:46.846963+00 2025-11-24 11:17:46.846963+00 0 f student active
31 00000000-0000-0000-0000-000000000000 1b310708-6f24-4c6a-88c9-a11f7a7f9763 authenticated angelrabano11@gmail.com $2b$10$Sg6q4kErMvxRlZgWM9lCj.PfRg5sCQrwm763d7sfc3iaAUID7y436 {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:47:53.790673+00 2025-11-24 11:47:53.790673+00 0 f student active
32 00000000-0000-0000-0000-000000000000 3c613b0e-66f9-4640-a599-c9426d8edffb authenticated daliaayalareyes35@gmail.com $2b$10$dd2SQeBqNIZpZWCGMIDu1O8U6MLpWnKF05w641MNOMzHDZ/U5glCe {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:55:08.708961+00 2025-11-24 11:55:08.708961+00 0 f student active
33 00000000-0000-0000-0000-000000000000 7ded133e-9b13-4467-9803-edb813f6a9a1 authenticated alexeimongam@gmail.com $2b$10$jyQrHAIj6SsnReQ45FrFlOnDgpZtabskpxPuOYgB/h.YPLyZhuld. {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 11:55:11.906996+00 2025-11-24 11:55:11.906996+00 0 f student active
34 00000000-0000-0000-0000-000000000000 4cc04f54-7771-462d-98aa-a94448bb6ff5 authenticated davidocampovenegas@gmail.com $2b$10$8COk10WE5.bXFJnAucEA0efcGQKU6KUXKV9N7n32ZX6aNKORs4McW {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 14:52:46.468737+00 2025-11-24 14:52:46.468737+00 0 f student active
35 00000000-0000-0000-0000-000000000000 fbbe7d19-048c-45e4-8a9c-cf86d2098c35 authenticated zaid080809@gmail.com $2b$10$kdaUWR1BUqPRY7H8YkR.xuuDbqtLcvP5yKW.B0ooPlb.I6b/UU192 {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 16:25:03.689847+00 2025-11-24 16:25:03.689847+00 0 f student active
36 00000000-0000-0000-0000-000000000000 5b3d74e8-fd1a-4c80-96d2-24c54bfe90c4 authenticated ruizcruzabrahamfrancisco@gmail.com $2b$10$DXHr682C4/VpesiHa7fRrOjKceiWSDUSx.1LZTbsvuxpqCdMNh/Ii {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 19:46:06.311558+00 2025-11-24 19:46:06.311558+00 0 f student active
37 00000000-0000-0000-0000-000000000000 615adf6e-dbf3-480f-a907-3cfb3a64c6d2 authenticated vituschinchilla@gmail.com $2b$10$dA8adTYlfhgqhZfACcQkFOCYjXdsmggXnIUluNDoh1zRFgQ6pq5O2 {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-24 21:07:26.037867+00 2025-11-24 21:07:26.037867+00 0 f student active
38 00000000-0000-0000-0000-000000000000 bf445960-4c1f-4e29-8fb7-31667b183d7e authenticated bryan@betanzos.com $2b$10$Xdfuf4Tfog9QKd1FRLL.7eAaD6tr2cXgPx1/L8xqT1kLLzNHzSM26 {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-25 06:13:30.263795+00 2025-11-25 06:13:30.263795+00 0 f student active
39 00000000-0000-0000-0000-000000000000 d5fa4905-a78a-4040-8ad8-23220881c6a6 authenticated loganalexander816@gmail.com $2b$10$8zLduh/9L/priag.nujz5utuloO9RnNFFDGdKgI2UniFCOwocEPLq {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-25 07:37:04.953164+00 2025-11-25 07:37:04.953164+00 0 f student active
40 00000000-0000-0000-0000-000000000000 71734c15-cdaa-431b-90f5-97a57e0316a8 authenticated carlois1974@gmail.com $2b$10$IfLfJ.q59DZgicR07ckSVOcrkkBJe42m1FECXxaoaodKYSo6uj5wW {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-25 07:41:38.025764+00 2025-11-25 07:41:38.025764+00 0 f student active
41 00000000-0000-0000-0000-000000000000 1efe491d-98ef-4c02-acd1-3135f7289072 authenticated enriquecuevascbtis136@gmail.com $2b$10$9BX3OQMZmHruffBtN.3WPOFoyea6zgPd8i72DvhJ7vRAdqWKax6GS {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-25 08:16:33.977647+00 2025-11-25 08:16:33.977647+00 0 f student active
42 00000000-0000-0000-0000-000000000000 5ae21325-7450-4c37-82f1-3f9bcd7b6f45 authenticated omarcitogonzalezzavaleta@gmail.com $2b$10$RRk3DAgQdiikxVImFIMqquqB.TNpKs3E.RNFtt1rwwTzO24uShri. {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-25 08:17:07.610076+00 2025-11-25 08:17:07.610076+00 0 f student active
43 00000000-0000-0000-0000-000000000000 a4d27774-8a51-4660-ad2f-81d0dfd3a5a7 authenticated gustavobm2024cbtis@gmail.com $2b$10$lg7KRUTPofcx4Rtyey8J7.XO0gmdBLCFIfK5uP08mqT0qUIl1aTJq {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-25 08:20:49.649184+00 2025-11-25 08:20:49.649184+00 0 f student active
44 00000000-0000-0000-0000-000000000000 6e30164a-78b0-49b0-bd21-23d7c6c03349 authenticated marianaxsotoxt22@gmail.com $2b$10$GQC9yTWiP2vP9GUp0gnhUeLjmw70EI4JQhfJBZbMOlCNXGXb/bt5O {"provider": "email", "providers": ["email"]} {"last_name": "", "first_name": ""} f 2025-11-25 08:33:18.150784+00 2025-11-25 08:33:18.150784+00 0 f student active
45 00000000-0000-0000-0000-000000000000 cccccccc-cccc-cccc-cccc-cccccccccccc authenticated student@gamilit.com $2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga 2025-11-29 13:26:50.289631+00 2025-12-07 03:42:02.528+00 {"provider": "email", "providers": ["email"]} {"name": "Estudiante Testing", "role": "student", "description": "Usuario estudiante de testing"} f 2025-11-29 13:26:50.289631+00 2025-12-07 03:42:02.529507+00 0 f student active
46 00000000-0000-0000-0000-000000000000 bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb authenticated teacher@gamilit.com $2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga 2025-11-29 13:26:50.289631+00 {"provider": "email", "providers": ["email"]} {"name": "Profesor Testing", "role": "admin_teacher", "description": "Usuario profesor de testing"} f 2025-11-29 13:26:50.289631+00 2025-11-29 13:26:50.289631+00 0 f admin_teacher active
47 00000000-0000-0000-0000-000000000000 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa authenticated admin@gamilit.com $2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga 2025-11-29 13:26:50.289631+00 2025-12-01 00:54:19.615+00 {"provider": "email", "providers": ["email"]} {"name": "Admin GAMILIT", "role": "super_admin", "description": "Usuario administrador de testing"} f 2025-11-29 13:26:50.289631+00 2025-12-01 00:54:19.617766+00 0 f super_admin active
48 0ae1bf21-39e3-4168-9632-457418c7a07d authenticated rckrdmrd@gmail.com $2b$10$LiDdaJLA.ZvdFleamkMuvOcIrW0PQMEh5aVZ5Wg5pzhm7gwc5s.1C 2025-12-09 01:22:42.784+00 {} f 2025-11-29 13:37:09.271457+00 2025-12-09 01:22:42.785367+00 0 f student active
49 69681b09-5077-4f77-84cc-67606abd9755 authenticated javiermar06@hotmail.com $2b$10$3RHyXnR4BG3NaxP8Ez82FuiGDMNCG7GhNaOsMFigy3BpIVOzCqHMW 2025-12-14 03:51:04.122+00 {} f 2025-12-08 19:24:06.266895+00 2025-12-14 03:51:04.123886+00 0 f student active
50 f929d6df-8c29-461f-88f5-264facd879e9 authenticated ju188an@gmail.com $2b$10$9vUERFnXApdfXuAI7DFve.aa8uDjI5bfm4CI75/EZ2cUre83RytKe 2025-12-17 23:51:43.553+00 {} f 2025-12-17 17:51:43.530434+00 2025-12-17 23:51:43.55475+00 0 f student active

View File

@ -0,0 +1,50 @@
id,tenant_id,display_name,full_name,first_name,last_name,email,avatar_url,bio,phone,date_of_birth,grade_level,student_id,school_id,role,status,email_verified,phone_verified,preferences,last_sign_in_at,last_activity_at,metadata,created_at,updated_at,user_id,deleted_at
b017b792-b327-40dd-aefb-a80312776952,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Jose Aguirre,Jose Aguirre,Jose,Aguirre,joseal.guirre34@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 07:29:05.229254+00,2025-11-18 07:29:05.229254+00,b017b792-b327-40dd-aefb-a80312776952,
06a24962-e83d-4e94-aad7-ff69f20a9119,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Sergio Jimenez,Sergio Jimenez,Sergio,Jimenez,sergiojimenezesteban63@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 08:17:40.928077+00,2025-11-18 08:17:40.928077+00,06a24962-e83d-4e94-aad7-ff69f20a9119,
24e8c563-8854-43d1-b3c9-2f83e91f5a1e,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Hugo Gomez,Hugo Gomez,Hugo,Gomez,Gomezfornite92@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 08:18:04.242047+00,2025-11-18 08:18:04.242047+00,24e8c563-8854-43d1-b3c9-2f83e91f5a1e,
bf0d3e34-e077-43d1-9626-292f7fae2bd6,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Hugo Aragón,Hugo Aragón,Hugo,Aragón,Aragon494gt54@icloud.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 08:20:17.230714+00,2025-11-18 08:20:17.230714+00,bf0d3e34-e077-43d1-9626-292f7fae2bd6,
2f5a9846-3393-40b2-9e87-0f29238c383f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Azul Valentina,Azul Valentina,Azul,Valentina,blu3wt7@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 08:32:17.315932+00,2025-11-18 08:32:17.315932+00,2f5a9846-3393-40b2-9e87-0f29238c383f,
5e738038-1743-4aa9-b222-30171300ea9d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ricardo Lugo,Ricardo Lugo,Ricardo,Lugo,ricardolugo786@icloud.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 10:15:06.481498+00,2025-11-18 10:15:06.481498+00,5e738038-1743-4aa9-b222-30171300ea9d,
00c742d9-e5f7-4666-9597-5a8ca54d5478,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Carlos Marban,Carlos Marban,Carlos,Marban,marbancarlos916@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 10:29:05.240413+00,2025-11-18 10:29:05.240413+00,00c742d9-e5f7-4666-9597-5a8ca54d5478,
33306a65-a3b1-41d5-a49d-47989957b822,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Diego Colores,Diego Colores,Diego,Colores,diego.colores09@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 10:29:20.531883+00,2025-11-18 10:29:20.531883+00,33306a65-a3b1-41d5-a49d-47989957b822,
7a6a973e-83f7-4374-a9fc-54258138115f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Benjamin Hernandez,Benjamin Hernandez,Benjamin,Hernandez,hernandezfonsecabenjamin7@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 10:37:06.9215+00,2025-11-18 10:37:06.9215+00,7a6a973e-83f7-4374-a9fc-54258138115f,
ccd7135c-0fea-4488-9094-9da52df1c98c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Josue Reyes,Josue Reyes,Josue,Reyes,jr7794315@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 17:53:39.681271+00,2025-11-18 17:53:39.681271+00,ccd7135c-0fea-4488-9094-9da52df1c98c,
9951ad75-e9cb-47b3-b478-6bb860ee2530,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Fernando Barragan,Fernando Barragan,Fernando,Barragan,barraganfer03@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 20:39:27.410436+00,2025-11-18 20:39:27.410436+00,9951ad75-e9cb-47b3-b478-6bb860ee2530,
735235f5-260a-4c9b-913c-14a1efd083ea,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Marco Antonio Roman,Marco Antonio Roman,Marco Antonio,Roman,roman.rebollar.marcoantonio1008@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 21:03:17.328254+00,2025-11-18 21:03:17.328254+00,735235f5-260a-4c9b-913c-14a1efd083ea,
ebe48628-5e44-4562-97b7-b4950b216247,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Rodrigo Guerrero,Rodrigo Guerrero,Rodrigo,Guerrero,rodrigoguerrero0914@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-18 21:20:52.304488+00,2025-11-18 21:20:52.304488+00,ebe48628-5e44-4562-97b7-b4950b216247,
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Admin GAMILIT,Administrador GAMILIT,Administrador,GAMILIT,admin@gamilit.com,/avatars/admin-testing.png,Usuario administrador para testing y desarrollo.,55-0000-0001,1985-01-01,,,,super_admin,active,t,t,"{""theme"": ""professional"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,"{""description"": ""Usuario de testing principal"", ""testing_user"": true}",2025-11-29 13:26:50.458823+00,2025-11-29 13:26:50.458823+00,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,
cccccccc-cccc-cccc-cccc-cccccccccccc,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Estudiante Testing,Estudiante de Testing GAMILIT,Estudiante,Testing,student@gamilit.com,/avatars/student-testing.png,Usuario estudiante para testing y desarrollo.,55-0000-0003,2013-09-01,5,EST-TEST-001,,student,active,t,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""gamification"": {""show_rank"": true, ""show_leaderboard"": true, ""show_achievements"": true}, ""sound_enabled"": true, ""notifications_enabled"": true}",,,"{""interests"": [""lectura"", ""ciencia""], ""testing_user"": true, ""learning_style"": ""visual""}",2025-11-29 13:26:50.458823+00,2025-11-29 13:26:50.458823+00,cccccccc-cccc-cccc-cccc-cccccccccccc,
bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Profesor Testing,Profesor de Testing GAMILIT,Profesor,Testing,teacher@gamilit.com,/avatars/teacher-testing.png,Usuario profesor para testing y desarrollo.,55-0000-0002,1980-05-15,,,,admin_teacher,active,t,t,"{""theme"": ""teacher"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,"{""subjects"": [""Lengua Española"", ""Comprensión Lectora""], ""testing_user"": true}",2025-11-29 13:26:50.458823+00,2025-11-29 13:26:50.458823+00,bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,
188fa4e3-985c-4048-8913-754cb0560875,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",7341023901m@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,5fc06693-e408-4eab-a9a3-fcd5f4e01296,
caa05325-b8e7-4b1c-9d95-03d4e0c7372d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",vituschinchilla@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,615adf6e-dbf3-480f-a907-3cfb3a64c6d2,
128ac756-bdb8-49d7-8fdb-cdb8fd241d06,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",alexeimongam@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,7ded133e-9b13-4467-9803-edb813f6a9a1,
7f3bb769-4d7e-4ca9-8527-708da0368be5,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",angelrabano11@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,1b310708-6f24-4c6a-88c9-a11f7a7f9763,
6a565d40-9012-4c89-878c-05bb8b6e2d81,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",loganalexander816@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,d5fa4905-a78a-4040-8ad8-23220881c6a6,
2df90a89-455e-4637-8b96-ad01c45f5701,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",johhkk22@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,126b9257-7b0a-4bd6-9ab3-c505ee00e10a,
43560c6b-fda2-4b45-bc0b-7dbbbffff05c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",edangiel4532@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,9ac1746e-94a6-4efc-a961-951c015d416e,
ff4760c8-5359-43e9-9b42-95a0bf3e3d36,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",aarizmendi434@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,af4d8788-f8a8-4971-bb0d-2f48c150dfc2,
a4c43698-c276-4430-b15e-8373b7bbb662,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",santiagoferrara78@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,d089b1af-462f-4d2c-b0f5-d2528cec8506,
30462f07-1c6b-4706-b4fb-288845b3631e,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",09enriquecampos@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,012adac4-8ffd-47bd-9248-f0c5851e981f,
4f5170f2-1d35-4130-a535-1d93383e406b,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",maximiliano.mejia367@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,1364c463-88de-479b-a883-c0b7b362bcf8,
c0aecfcc-3b2f-4117-9f20-e0920df97dc0,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",segurauriel235@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,5d1839f6-b03f-4e12-b236-eca43f4674f2,
3dfcdc9d-de8a-45b3-a05f-b83b51097ef5,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",omarcitogonzalezzavaleta@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,5ae21325-7450-4c37-82f1-3f9bcd7b6f45,
bb74b280-db90-4240-ab09-b8c6cf63d553,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",erickfranco462@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,2d9f05d4-44dd-42cd-97aa-d57bd06fecd0,
7ede7b67-42d2-44cd-a530-66f62a68cd54,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",bryan@betanzos.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,bf445960-4c1f-4e29-8fb7-31667b183d7e,
3f255f44-40d9-4dc9-970c-d50ddec197b3,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",alexanserrv917@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,b1cadf36-1f07-46b2-b63d-da72d9b54dc6,
f1870075-a6e0-47e7-88c6-793320ab3c8f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",carlois1974@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,71734c15-cdaa-431b-90f5-97a57e0316a8,
ab2425d9-e2da-49ac-b8db-2db605e7283f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",gustavobm2024cbtis@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,a4d27774-8a51-4660-ad2f-81d0dfd3a5a7,
802f4d68-bbd0-4220-8218-634975c3774a,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",gallinainsana@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,aff5dcc6-32de-4769-9aaf-eda751fa0866,
142af777-fce1-4067-b84b-f684e2fa1170,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",zaid080809@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,fbbe7d19-048c-45e4-8a9c-cf86d2098c35,
b5c2d5dc-e753-40ff-8e01-95c4c497710c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",davidocampovenegas@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,4cc04f54-7771-462d-98aa-a94448bb6ff5,
d29345bb-fd48-4f69-ac81-eeedd4b41e6d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",marianaxsotoxt22@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,6e30164a-78b0-49b0-bd21-23d7c6c03349,
813055ff-e5b7-4538-825c-eb721360e189,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",leile5257@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,0cda1645-83c5-445b-80b7-d0e4d436c00c,
6c9bbb36-0b2d-49ea-9c1b-63209f009773,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",ashernarcisobenitezpalomino@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,26fbc469-10af-4fa3-bd65-e5498188cc4f,
8daf8ed9-d15f-407f-b827-3a9c01907e62,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",ruizcruzabrahamfrancisco@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,5b3d74e8-fd1a-4c80-96d2-24c54bfe90c4,
bd028538-520d-45cf-a6f7-27c9f675d663,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",daliaayalareyes35@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,3c613b0e-66f9-4640-a599-c9426d8edffb,
de1511df-f963-4ff6-8e3f-2225ba493879,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",ra.alejandrobm@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,74ed8c97-ec36-43aa-a1cc-b0c99e4be4e8,
26168044-3b5c-43f6-a757-833ba1485d41,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",enriquecuevascbtis136@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,1efe491d-98ef-4c02-acd1-3135f7289072,
e742724a-0ff6-4760-884b-866835460045,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",fl432025@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,547eb778-4782-4681-b198-c731bba36147,
3ce354c8-bcac-44c6-9a94-5274e5f9b389,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,"","",abdallahxelhaneriavega@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:30:54.277737+00,2025-11-29 13:30:54.277737+00,f4c46f46-3fb9-40bf-a52b-a8ad2e6a92e1,
0ae1bf21-39e3-4168-9632-457418c7a07d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,rckrdmrd@gmail.com,,rckrdmrd@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-11-29 13:37:09.278078+00,2025-11-29 13:37:09.278078+00,0ae1bf21-39e3-4168-9632-457418c7a07d,
69681b09-5077-4f77-84cc-67606abd9755,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,Javier, Mar,javiermar06@hotmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-12-08 19:24:06.272257+00,2025-12-08 19:24:06.272257+00,69681b09-5077-4f77-84cc-67606abd9755,
f929d6df-8c29-461f-88f5-264facd879e9,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,,,Juan,pa,ju188an@gmail.com,,,,,,,,student,active,f,f,"{""theme"": ""detective"", ""language"": ""es"", ""timezone"": ""America/Mexico_City"", ""sound_enabled"": true, ""notifications_enabled"": true}",,,{},2025-12-17 17:51:43.536295+00,2025-12-17 17:51:43.536295+00,f929d6df-8c29-461f-88f5-264facd879e9,
1 id tenant_id display_name full_name first_name last_name email avatar_url bio phone date_of_birth grade_level student_id school_id role status email_verified phone_verified preferences last_sign_in_at last_activity_at metadata created_at updated_at user_id deleted_at
2 b017b792-b327-40dd-aefb-a80312776952 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Jose Aguirre Jose Aguirre Jose Aguirre joseal.guirre34@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 07:29:05.229254+00 2025-11-18 07:29:05.229254+00 b017b792-b327-40dd-aefb-a80312776952
3 06a24962-e83d-4e94-aad7-ff69f20a9119 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Sergio Jimenez Sergio Jimenez Sergio Jimenez sergiojimenezesteban63@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 08:17:40.928077+00 2025-11-18 08:17:40.928077+00 06a24962-e83d-4e94-aad7-ff69f20a9119
4 24e8c563-8854-43d1-b3c9-2f83e91f5a1e a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Hugo Gomez Hugo Gomez Hugo Gomez Gomezfornite92@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 08:18:04.242047+00 2025-11-18 08:18:04.242047+00 24e8c563-8854-43d1-b3c9-2f83e91f5a1e
5 bf0d3e34-e077-43d1-9626-292f7fae2bd6 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Hugo Aragón Hugo Aragón Hugo Aragón Aragon494gt54@icloud.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 08:20:17.230714+00 2025-11-18 08:20:17.230714+00 bf0d3e34-e077-43d1-9626-292f7fae2bd6
6 2f5a9846-3393-40b2-9e87-0f29238c383f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Azul Valentina Azul Valentina Azul Valentina blu3wt7@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 08:32:17.315932+00 2025-11-18 08:32:17.315932+00 2f5a9846-3393-40b2-9e87-0f29238c383f
7 5e738038-1743-4aa9-b222-30171300ea9d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ricardo Lugo Ricardo Lugo Ricardo Lugo ricardolugo786@icloud.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 10:15:06.481498+00 2025-11-18 10:15:06.481498+00 5e738038-1743-4aa9-b222-30171300ea9d
8 00c742d9-e5f7-4666-9597-5a8ca54d5478 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Carlos Marban Carlos Marban Carlos Marban marbancarlos916@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 10:29:05.240413+00 2025-11-18 10:29:05.240413+00 00c742d9-e5f7-4666-9597-5a8ca54d5478
9 33306a65-a3b1-41d5-a49d-47989957b822 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Diego Colores Diego Colores Diego Colores diego.colores09@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 10:29:20.531883+00 2025-11-18 10:29:20.531883+00 33306a65-a3b1-41d5-a49d-47989957b822
10 7a6a973e-83f7-4374-a9fc-54258138115f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Benjamin Hernandez Benjamin Hernandez Benjamin Hernandez hernandezfonsecabenjamin7@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 10:37:06.9215+00 2025-11-18 10:37:06.9215+00 7a6a973e-83f7-4374-a9fc-54258138115f
11 ccd7135c-0fea-4488-9094-9da52df1c98c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Josue Reyes Josue Reyes Josue Reyes jr7794315@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 17:53:39.681271+00 2025-11-18 17:53:39.681271+00 ccd7135c-0fea-4488-9094-9da52df1c98c
12 9951ad75-e9cb-47b3-b478-6bb860ee2530 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Fernando Barragan Fernando Barragan Fernando Barragan barraganfer03@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 20:39:27.410436+00 2025-11-18 20:39:27.410436+00 9951ad75-e9cb-47b3-b478-6bb860ee2530
13 735235f5-260a-4c9b-913c-14a1efd083ea a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Marco Antonio Roman Marco Antonio Roman Marco Antonio Roman roman.rebollar.marcoantonio1008@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 21:03:17.328254+00 2025-11-18 21:03:17.328254+00 735235f5-260a-4c9b-913c-14a1efd083ea
14 ebe48628-5e44-4562-97b7-b4950b216247 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Rodrigo Guerrero Rodrigo Guerrero Rodrigo Guerrero rodrigoguerrero0914@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-18 21:20:52.304488+00 2025-11-18 21:20:52.304488+00 ebe48628-5e44-4562-97b7-b4950b216247
15 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Admin GAMILIT Administrador GAMILIT Administrador GAMILIT admin@gamilit.com /avatars/admin-testing.png Usuario administrador para testing y desarrollo. 55-0000-0001 1985-01-01 super_admin active t t {"theme": "professional", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {"description": "Usuario de testing principal", "testing_user": true} 2025-11-29 13:26:50.458823+00 2025-11-29 13:26:50.458823+00 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
16 cccccccc-cccc-cccc-cccc-cccccccccccc a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Estudiante Testing Estudiante de Testing GAMILIT Estudiante Testing student@gamilit.com /avatars/student-testing.png Usuario estudiante para testing y desarrollo. 55-0000-0003 2013-09-01 5 EST-TEST-001 student active t f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "gamification": {"show_rank": true, "show_leaderboard": true, "show_achievements": true}, "sound_enabled": true, "notifications_enabled": true} {"interests": ["lectura", "ciencia"], "testing_user": true, "learning_style": "visual"} 2025-11-29 13:26:50.458823+00 2025-11-29 13:26:50.458823+00 cccccccc-cccc-cccc-cccc-cccccccccccc
17 bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Profesor Testing Profesor de Testing GAMILIT Profesor Testing teacher@gamilit.com /avatars/teacher-testing.png Usuario profesor para testing y desarrollo. 55-0000-0002 1980-05-15 admin_teacher active t t {"theme": "teacher", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {"subjects": ["Lengua Española", "Comprensión Lectora"], "testing_user": true} 2025-11-29 13:26:50.458823+00 2025-11-29 13:26:50.458823+00 bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb
18 188fa4e3-985c-4048-8913-754cb0560875 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 7341023901m@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 5fc06693-e408-4eab-a9a3-fcd5f4e01296
19 caa05325-b8e7-4b1c-9d95-03d4e0c7372d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 vituschinchilla@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 615adf6e-dbf3-480f-a907-3cfb3a64c6d2
20 128ac756-bdb8-49d7-8fdb-cdb8fd241d06 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 alexeimongam@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 7ded133e-9b13-4467-9803-edb813f6a9a1
21 7f3bb769-4d7e-4ca9-8527-708da0368be5 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 angelrabano11@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 1b310708-6f24-4c6a-88c9-a11f7a7f9763
22 6a565d40-9012-4c89-878c-05bb8b6e2d81 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 loganalexander816@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 d5fa4905-a78a-4040-8ad8-23220881c6a6
23 2df90a89-455e-4637-8b96-ad01c45f5701 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 johhkk22@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 126b9257-7b0a-4bd6-9ab3-c505ee00e10a
24 43560c6b-fda2-4b45-bc0b-7dbbbffff05c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 edangiel4532@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 9ac1746e-94a6-4efc-a961-951c015d416e
25 ff4760c8-5359-43e9-9b42-95a0bf3e3d36 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 aarizmendi434@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 af4d8788-f8a8-4971-bb0d-2f48c150dfc2
26 a4c43698-c276-4430-b15e-8373b7bbb662 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 santiagoferrara78@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 d089b1af-462f-4d2c-b0f5-d2528cec8506
27 30462f07-1c6b-4706-b4fb-288845b3631e a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 09enriquecampos@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 012adac4-8ffd-47bd-9248-f0c5851e981f
28 4f5170f2-1d35-4130-a535-1d93383e406b a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 maximiliano.mejia367@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 1364c463-88de-479b-a883-c0b7b362bcf8
29 c0aecfcc-3b2f-4117-9f20-e0920df97dc0 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 segurauriel235@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 5d1839f6-b03f-4e12-b236-eca43f4674f2
30 3dfcdc9d-de8a-45b3-a05f-b83b51097ef5 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 omarcitogonzalezzavaleta@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 5ae21325-7450-4c37-82f1-3f9bcd7b6f45
31 bb74b280-db90-4240-ab09-b8c6cf63d553 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 erickfranco462@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 2d9f05d4-44dd-42cd-97aa-d57bd06fecd0
32 7ede7b67-42d2-44cd-a530-66f62a68cd54 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 bryan@betanzos.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 bf445960-4c1f-4e29-8fb7-31667b183d7e
33 3f255f44-40d9-4dc9-970c-d50ddec197b3 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 alexanserrv917@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 b1cadf36-1f07-46b2-b63d-da72d9b54dc6
34 f1870075-a6e0-47e7-88c6-793320ab3c8f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 carlois1974@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 71734c15-cdaa-431b-90f5-97a57e0316a8
35 ab2425d9-e2da-49ac-b8db-2db605e7283f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 gustavobm2024cbtis@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 a4d27774-8a51-4660-ad2f-81d0dfd3a5a7
36 802f4d68-bbd0-4220-8218-634975c3774a a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 gallinainsana@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 aff5dcc6-32de-4769-9aaf-eda751fa0866
37 142af777-fce1-4067-b84b-f684e2fa1170 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 zaid080809@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 fbbe7d19-048c-45e4-8a9c-cf86d2098c35
38 b5c2d5dc-e753-40ff-8e01-95c4c497710c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 davidocampovenegas@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 4cc04f54-7771-462d-98aa-a94448bb6ff5
39 d29345bb-fd48-4f69-ac81-eeedd4b41e6d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 marianaxsotoxt22@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 6e30164a-78b0-49b0-bd21-23d7c6c03349
40 813055ff-e5b7-4538-825c-eb721360e189 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 leile5257@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 0cda1645-83c5-445b-80b7-d0e4d436c00c
41 6c9bbb36-0b2d-49ea-9c1b-63209f009773 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 ashernarcisobenitezpalomino@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 26fbc469-10af-4fa3-bd65-e5498188cc4f
42 8daf8ed9-d15f-407f-b827-3a9c01907e62 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 ruizcruzabrahamfrancisco@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 5b3d74e8-fd1a-4c80-96d2-24c54bfe90c4
43 bd028538-520d-45cf-a6f7-27c9f675d663 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 daliaayalareyes35@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 3c613b0e-66f9-4640-a599-c9426d8edffb
44 de1511df-f963-4ff6-8e3f-2225ba493879 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 ra.alejandrobm@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 74ed8c97-ec36-43aa-a1cc-b0c99e4be4e8
45 26168044-3b5c-43f6-a757-833ba1485d41 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 enriquecuevascbtis136@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 1efe491d-98ef-4c02-acd1-3135f7289072
46 e742724a-0ff6-4760-884b-866835460045 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 fl432025@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 547eb778-4782-4681-b198-c731bba36147
47 3ce354c8-bcac-44c6-9a94-5274e5f9b389 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 abdallahxelhaneriavega@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:30:54.277737+00 2025-11-29 13:30:54.277737+00 f4c46f46-3fb9-40bf-a52b-a8ad2e6a92e1
48 0ae1bf21-39e3-4168-9632-457418c7a07d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 rckrdmrd@gmail.com rckrdmrd@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-11-29 13:37:09.278078+00 2025-11-29 13:37:09.278078+00 0ae1bf21-39e3-4168-9632-457418c7a07d
49 69681b09-5077-4f77-84cc-67606abd9755 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Javier Mar javiermar06@hotmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-12-08 19:24:06.272257+00 2025-12-08 19:24:06.272257+00 69681b09-5077-4f77-84cc-67606abd9755
50 f929d6df-8c29-461f-88f5-264facd879e9 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Juan pa ju188an@gmail.com student active f f {"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true} {} 2025-12-17 17:51:43.536295+00 2025-12-17 17:51:43.536295+00 f929d6df-8c29-461f-88f5-264facd879e9

View File

@ -0,0 +1,50 @@
id,user_id,tenant_id,current_rank,previous_rank,rank_progress_percentage,modules_required_for_next,modules_completed_for_rank,xp_required_for_next,xp_earned_for_rank,ml_coins_bonus,certificate_url,badge_url,achieved_at,previous_rank_achieved_at,is_current,rank_metadata,created_at,updated_at
33b12003-65b0-4f50-8bda-6eeebedc3413,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Halach Uinic,Ah K'in,0,,0,,0,500,,,2025-11-29 13:26:52.158657+00,2025-11-29 13:26:52.158657+00,t,{},2025-11-29 13:26:50.458823+00,2025-11-29 13:26:52.138221+00
aef81f6b-b9c4-4f80-b27f-8f9bf8c2cd97,bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.458823+00,,t,{},2025-11-29 13:26:50.458823+00,2025-11-29 13:26:50.458823+00
cb04ef70-2738-4c9e-b32a-a92643b8a3f9,cccccccc-cccc-cccc-cccc-cccccccccccc,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Halach Uinic,Ah K'in,0,,0,,0,500,,,2025-11-30 20:12:46.263821+00,2025-11-29 13:26:52.146305+00,t,{},2025-11-29 13:26:50.458823+00,2025-11-30 20:12:46.263821+00
eb382620-70b8-4842-b8cf-ad51eb1c7266,2f5a9846-3393-40b2-9e87-0f29238c383f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
207ff6ef-a56d-4fc1-942f-5a50e0c842da,5e738038-1743-4aa9-b222-30171300ea9d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
64946395-a46c-4e93-abf7-5b827e4dcf12,33306a65-a3b1-41d5-a49d-47989957b822,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
66cb0dd1-2c47-4572-99ec-c97ccee95e53,7a6a973e-83f7-4374-a9fc-54258138115f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
8c1d72aa-fead-4bff-bf47-b34ceab62a40,06a24962-e83d-4e94-aad7-ff69f20a9119,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
b14b22be-bd9d-485c-9477-b4122c63cbfb,9951ad75-e9cb-47b3-b478-6bb860ee2530,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
4e7cf7a1-8ef4-4d20-902b-ba1c57faad51,735235f5-260a-4c9b-913c-14a1efd083ea,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
d0500d4e-17ec-46be-94a1-4e2500e4b9a8,ebe48628-5e44-4562-97b7-b4950b216247,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
9a4e06cc-0a50-4ff9-b781-d29edff7bbd6,00c742d9-e5f7-4666-9597-5a8ca54d5478,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Nacom,Ajaw,0,,0,,0,100,,,2025-11-29 13:26:52.138221+00,2025-11-29 13:26:50.539509+00,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:52.138221+00
4cadc6a3-c15e-410a-88f5-c0254463ca8a,b017b792-b327-40dd-aefb-a80312776952,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
241b6cea-03d0-4f9c-97b6-7d49d9175cfb,ccd7135c-0fea-4488-9094-9da52df1c98c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
840cabba-4a80-40fa-a3e0-0e218e09463e,24e8c563-8854-43d1-b3c9-2f83e91f5a1e,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
913ae601-8ab4-4056-864c-517e100bef5b,bf0d3e34-e077-43d1-9626-292f7fae2bd6,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:26:50.539509+00,,t,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
b1c76243-62c4-4e73-8e7b-152b82e41c93,128ac756-bdb8-49d7-8fdb-cdb8fd241d06,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
e521b5a1-250b-4e96-a2cd-e8736f1f3fbe,6c9bbb36-0b2d-49ea-9c1b-63209f009773,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
a106676f-8723-492b-b4f1-1b9256da8a4d,813055ff-e5b7-4538-825c-eb721360e189,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
8cf5754b-7af4-429f-8e57-b0f2e4f740d6,3ce354c8-bcac-44c6-9a94-5274e5f9b389,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
89526d39-7d29-4d97-a65b-94a42dfb45e2,ab2425d9-e2da-49ac-b8db-2db605e7283f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
fa25a282-3568-481a-878d-c424f6eaee95,ff4760c8-5359-43e9-9b42-95a0bf3e3d36,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
69621cdf-cc64-4f2b-85f3-d1f09b54cbf0,7f3bb769-4d7e-4ca9-8527-708da0368be5,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
b4c93d8d-fb84-4ba2-91d7-78abd5a780de,26168044-3b5c-43f6-a757-833ba1485d41,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
3444f9aa-7c1b-452c-bfbb-af58dc70e70b,bd028538-520d-45cf-a6f7-27c9f675d663,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
c8aec5d3-4a66-40b6-a8e7-9b2edd4225b1,2df90a89-455e-4637-8b96-ad01c45f5701,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
e284ffd8-9d58-4564-95c4-075721724643,6a565d40-9012-4c89-878c-05bb8b6e2d81,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
abfa66bf-dc3d-426a-b4ec-538677b39cd5,43560c6b-fda2-4b45-bc0b-7dbbbffff05c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
b26939b5-2dc1-4643-b46c-c4a3d6a5203f,d29345bb-fd48-4f69-ac81-eeedd4b41e6d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
564433a1-e5f1-48ce-8807-06f5b9ea1418,30462f07-1c6b-4706-b4fb-288845b3631e,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
aee1d9bf-b4fe-4512-9cf0-4cc90413692e,8daf8ed9-d15f-407f-b827-3a9c01907e62,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
7c3b01ab-b75b-4464-8858-91c1ff805c32,3dfcdc9d-de8a-45b3-a05f-b83b51097ef5,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
53ec34ee-bd3c-462f-b5b0-317705c0399d,3f255f44-40d9-4dc9-970c-d50ddec197b3,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
b2461bb7-7107-48dd-923f-de4ff8e86a67,e742724a-0ff6-4760-884b-866835460045,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
890ba444-c64f-4680-894d-56bf30cbcf5c,f1870075-a6e0-47e7-88c6-793320ab3c8f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
a7b16bb9-efa6-4f10-8fe0-992adbd8c482,b5c2d5dc-e753-40ff-8e01-95c4c497710c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
c6eb5dd4-a987-4560-b22d-645ca31791e6,142af777-fce1-4067-b84b-f684e2fa1170,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
520cd26c-5222-4579-8f1d-72f4be8e98d3,c0aecfcc-3b2f-4117-9f20-e0920df97dc0,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
2971dbbf-33de-4f12-9e47-48c9a3b145df,7ede7b67-42d2-44cd-a530-66f62a68cd54,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
cb9feef2-0f2d-4949-b212-3b6d7dbfe2fa,caa05325-b8e7-4b1c-9d95-03d4e0c7372d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
89181d4a-a47b-4449-81fa-09a7e1d67534,a4c43698-c276-4430-b15e-8373b7bbb662,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
998f3c88-8932-4d91-af11-7bca6c03bbc3,bb74b280-db90-4240-ab09-b8c6cf63d553,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
e22e4620-57fc-47ad-ae53-f45ecc17932f,4f5170f2-1d35-4130-a535-1d93383e406b,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
b9e35a4b-ade2-4fa0-bd58-38ffcf5ca614,802f4d68-bbd0-4220-8218-634975c3774a,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
365f3ac3-2880-42a8-8799-0c465b0a4ed9,de1511df-f963-4ff6-8e3f-2225ba493879,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
21152c4c-b082-40a7-938b-e7486730e2bb,188fa4e3-985c-4048-8913-754cb0560875,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-11-29 13:33:25.124715+00,,t,{},2025-11-29 13:33:25.124715+00,2025-11-29 13:33:25.124715+00
3c88a791-ad9b-4988-9351-b5e9df60c9a4,0ae1bf21-39e3-4168-9632-457418c7a07d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ah K'in,Nacom,0,,0,,0,250,,,2025-11-29 13:41:42.417785+00,2025-11-29 13:40:27.516619+00,t,{},2025-11-29 13:37:09.278078+00,2025-11-29 13:41:42.417785+00
1de77cef-003a-4d08-8ccc-8bd4001fa62c,69681b09-5077-4f77-84cc-67606abd9755,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-12-08 19:24:06.272257+00,,t,{},2025-12-08 19:24:06.272257+00,2025-12-08 19:24:06.272257+00
63b40546-38a8-4c80-bf11-3504c73150bb,f929d6df-8c29-461f-88f5-264facd879e9,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,Ajaw,,0,,0,,0,0,,,2025-12-17 17:51:43.536295+00,,t,{},2025-12-17 17:51:43.536295+00,2025-12-17 17:51:43.536295+00
1 id user_id tenant_id current_rank previous_rank rank_progress_percentage modules_required_for_next modules_completed_for_rank xp_required_for_next xp_earned_for_rank ml_coins_bonus certificate_url badge_url achieved_at previous_rank_achieved_at is_current rank_metadata created_at updated_at
2 33b12003-65b0-4f50-8bda-6eeebedc3413 aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Halach Uinic Ah K'in 0 0 0 500 2025-11-29 13:26:52.158657+00 2025-11-29 13:26:52.158657+00 t {} 2025-11-29 13:26:50.458823+00 2025-11-29 13:26:52.138221+00
3 aef81f6b-b9c4-4f80-b27f-8f9bf8c2cd97 bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.458823+00 t {} 2025-11-29 13:26:50.458823+00 2025-11-29 13:26:50.458823+00
4 cb04ef70-2738-4c9e-b32a-a92643b8a3f9 cccccccc-cccc-cccc-cccc-cccccccccccc a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Halach Uinic Ah K'in 0 0 0 500 2025-11-30 20:12:46.263821+00 2025-11-29 13:26:52.146305+00 t {} 2025-11-29 13:26:50.458823+00 2025-11-30 20:12:46.263821+00
5 eb382620-70b8-4842-b8cf-ad51eb1c7266 2f5a9846-3393-40b2-9e87-0f29238c383f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
6 207ff6ef-a56d-4fc1-942f-5a50e0c842da 5e738038-1743-4aa9-b222-30171300ea9d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
7 64946395-a46c-4e93-abf7-5b827e4dcf12 33306a65-a3b1-41d5-a49d-47989957b822 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
8 66cb0dd1-2c47-4572-99ec-c97ccee95e53 7a6a973e-83f7-4374-a9fc-54258138115f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
9 8c1d72aa-fead-4bff-bf47-b34ceab62a40 06a24962-e83d-4e94-aad7-ff69f20a9119 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
10 b14b22be-bd9d-485c-9477-b4122c63cbfb 9951ad75-e9cb-47b3-b478-6bb860ee2530 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
11 4e7cf7a1-8ef4-4d20-902b-ba1c57faad51 735235f5-260a-4c9b-913c-14a1efd083ea a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
12 d0500d4e-17ec-46be-94a1-4e2500e4b9a8 ebe48628-5e44-4562-97b7-b4950b216247 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
13 9a4e06cc-0a50-4ff9-b781-d29edff7bbd6 00c742d9-e5f7-4666-9597-5a8ca54d5478 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Nacom Ajaw 0 0 0 100 2025-11-29 13:26:52.138221+00 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:52.138221+00
14 4cadc6a3-c15e-410a-88f5-c0254463ca8a b017b792-b327-40dd-aefb-a80312776952 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
15 241b6cea-03d0-4f9c-97b6-7d49d9175cfb ccd7135c-0fea-4488-9094-9da52df1c98c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
16 840cabba-4a80-40fa-a3e0-0e218e09463e 24e8c563-8854-43d1-b3c9-2f83e91f5a1e a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
17 913ae601-8ab4-4056-864c-517e100bef5b bf0d3e34-e077-43d1-9626-292f7fae2bd6 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:26:50.539509+00 t {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
18 b1c76243-62c4-4e73-8e7b-152b82e41c93 128ac756-bdb8-49d7-8fdb-cdb8fd241d06 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
19 e521b5a1-250b-4e96-a2cd-e8736f1f3fbe 6c9bbb36-0b2d-49ea-9c1b-63209f009773 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
20 a106676f-8723-492b-b4f1-1b9256da8a4d 813055ff-e5b7-4538-825c-eb721360e189 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
21 8cf5754b-7af4-429f-8e57-b0f2e4f740d6 3ce354c8-bcac-44c6-9a94-5274e5f9b389 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
22 89526d39-7d29-4d97-a65b-94a42dfb45e2 ab2425d9-e2da-49ac-b8db-2db605e7283f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
23 fa25a282-3568-481a-878d-c424f6eaee95 ff4760c8-5359-43e9-9b42-95a0bf3e3d36 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
24 69621cdf-cc64-4f2b-85f3-d1f09b54cbf0 7f3bb769-4d7e-4ca9-8527-708da0368be5 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
25 b4c93d8d-fb84-4ba2-91d7-78abd5a780de 26168044-3b5c-43f6-a757-833ba1485d41 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
26 3444f9aa-7c1b-452c-bfbb-af58dc70e70b bd028538-520d-45cf-a6f7-27c9f675d663 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
27 c8aec5d3-4a66-40b6-a8e7-9b2edd4225b1 2df90a89-455e-4637-8b96-ad01c45f5701 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
28 e284ffd8-9d58-4564-95c4-075721724643 6a565d40-9012-4c89-878c-05bb8b6e2d81 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
29 abfa66bf-dc3d-426a-b4ec-538677b39cd5 43560c6b-fda2-4b45-bc0b-7dbbbffff05c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
30 b26939b5-2dc1-4643-b46c-c4a3d6a5203f d29345bb-fd48-4f69-ac81-eeedd4b41e6d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
31 564433a1-e5f1-48ce-8807-06f5b9ea1418 30462f07-1c6b-4706-b4fb-288845b3631e a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
32 aee1d9bf-b4fe-4512-9cf0-4cc90413692e 8daf8ed9-d15f-407f-b827-3a9c01907e62 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
33 7c3b01ab-b75b-4464-8858-91c1ff805c32 3dfcdc9d-de8a-45b3-a05f-b83b51097ef5 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
34 53ec34ee-bd3c-462f-b5b0-317705c0399d 3f255f44-40d9-4dc9-970c-d50ddec197b3 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
35 b2461bb7-7107-48dd-923f-de4ff8e86a67 e742724a-0ff6-4760-884b-866835460045 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
36 890ba444-c64f-4680-894d-56bf30cbcf5c f1870075-a6e0-47e7-88c6-793320ab3c8f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
37 a7b16bb9-efa6-4f10-8fe0-992adbd8c482 b5c2d5dc-e753-40ff-8e01-95c4c497710c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
38 c6eb5dd4-a987-4560-b22d-645ca31791e6 142af777-fce1-4067-b84b-f684e2fa1170 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
39 520cd26c-5222-4579-8f1d-72f4be8e98d3 c0aecfcc-3b2f-4117-9f20-e0920df97dc0 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
40 2971dbbf-33de-4f12-9e47-48c9a3b145df 7ede7b67-42d2-44cd-a530-66f62a68cd54 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
41 cb9feef2-0f2d-4949-b212-3b6d7dbfe2fa caa05325-b8e7-4b1c-9d95-03d4e0c7372d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
42 89181d4a-a47b-4449-81fa-09a7e1d67534 a4c43698-c276-4430-b15e-8373b7bbb662 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
43 998f3c88-8932-4d91-af11-7bca6c03bbc3 bb74b280-db90-4240-ab09-b8c6cf63d553 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
44 e22e4620-57fc-47ad-ae53-f45ecc17932f 4f5170f2-1d35-4130-a535-1d93383e406b a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
45 b9e35a4b-ade2-4fa0-bd58-38ffcf5ca614 802f4d68-bbd0-4220-8218-634975c3774a a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
46 365f3ac3-2880-42a8-8799-0c465b0a4ed9 de1511df-f963-4ff6-8e3f-2225ba493879 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
47 21152c4c-b082-40a7-938b-e7486730e2bb 188fa4e3-985c-4048-8913-754cb0560875 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-11-29 13:33:25.124715+00 t {} 2025-11-29 13:33:25.124715+00 2025-11-29 13:33:25.124715+00
48 3c88a791-ad9b-4988-9351-b5e9df60c9a4 0ae1bf21-39e3-4168-9632-457418c7a07d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ah K'in Nacom 0 0 0 250 2025-11-29 13:41:42.417785+00 2025-11-29 13:40:27.516619+00 t {} 2025-11-29 13:37:09.278078+00 2025-11-29 13:41:42.417785+00
49 1de77cef-003a-4d08-8ccc-8bd4001fa62c 69681b09-5077-4f77-84cc-67606abd9755 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-12-08 19:24:06.272257+00 t {} 2025-12-08 19:24:06.272257+00 2025-12-08 19:24:06.272257+00
50 63b40546-38a8-4c80-bf11-3504c73150bb f929d6df-8c29-461f-88f5-264facd879e9 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 Ajaw 0 0 0 0 2025-12-17 17:51:43.536295+00 t {} 2025-12-17 17:51:43.536295+00 2025-12-17 17:51:43.536295+00

View File

@ -0,0 +1,50 @@
id,user_id,tenant_id,level,total_xp,xp_to_next_level,current_rank,rank_progress,ml_coins,ml_coins_earned_total,ml_coins_spent_total,ml_coins_earned_today,last_ml_coins_reset,current_streak,max_streak,streak_started_at,days_active_total,exercises_completed,modules_completed,total_score,average_score,perfect_scores,achievements_earned,certificates_earned,total_time_spent,weekly_time_spent,sessions_count,weekly_xp,monthly_xp,weekly_exercises,global_rank_position,class_rank_position,school_rank_position,last_activity_at,last_login_at,metadata,created_at,updated_at
7446ef44-11a1-451d-9624-abd95f0eb2ec,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,6,2525,100,Halach Uinic,0.00,1960,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.458823+00,2025-11-29 13:26:52.120683+00
06fd9e66-cefc-4c64-a446-37cef9668b36,bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,2,375,100,Ajaw,0.00,260,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.458823+00,2025-11-29 13:26:52.120683+00
b3830215-9623-46a6-9624-2c7183f13737,cccccccc-cccc-cccc-cccc-cccccccccccc,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,5,1825,100,Halach Uinic,0.00,1625,180,0,0,,0,0,,0,8,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,2025-12-02 10:55:24.674923+00,,{},2025-11-29 13:26:50.458823+00,2025-12-02 10:55:24.674923+00
1f6076c1-7b54-43f7-9fca-519407e65c4f,2f5a9846-3393-40b2-9e87-0f29238c383f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,2,150,100,Ajaw,0.00,140,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:52.120683+00
524efcd5-9c89-4a79-ac4c-f58f92f9fd28,7a6a973e-83f7-4374-a9fc-54258138115f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,25,100,Ajaw,0.00,110,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:52.120683+00
88b149bb-5f3b-41bb-885f-e226eb9cac22,b017b792-b327-40dd-aefb-a80312776952,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
fe110986-762c-459f-acde-b2c865c237bb,33306a65-a3b1-41d5-a49d-47989957b822,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,75,100,Ajaw,0.00,120,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:52.120683+00
f0734a0b-1d9c-4999-bcba-8e3b8f229c80,9951ad75-e9cb-47b3-b478-6bb860ee2530,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,2,375,100,Ajaw,0.00,260,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:52.120683+00
0145f432-c383-45d1-9d0f-0c7783a48612,735235f5-260a-4c9b-913c-14a1efd083ea,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,75,100,Ajaw,0.00,135,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:52.120683+00
c29ffaef-0392-4fe1-ac41-b502a4052111,5e738038-1743-4aa9-b222-30171300ea9d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,25,100,Ajaw,0.00,110,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:52.120683+00
1cb60bdb-800a-4ebc-a9c3-16ecf78d3535,06a24962-e83d-4e94-aad7-ff69f20a9119,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
5cba623a-015f-41e9-9de0-da67bdd6b5fb,24e8c563-8854-43d1-b3c9-2f83e91f5a1e,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
ee39d06d-d9c5-492a-9855-2210c74b74fd,ccd7135c-0fea-4488-9094-9da52df1c98c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
c6a7e9dd-ade4-4860-a4e0-882fd5aa0ed1,bf0d3e34-e077-43d1-9626-292f7fae2bd6,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
e6be8348-29af-49c4-b49d-4b2d978c951b,ebe48628-5e44-4562-97b7-b4950b216247,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:50.539509+00
9c4cf796-3768-4182-b1e0-1a38f8187c87,00c742d9-e5f7-4666-9597-5a8ca54d5478,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,3,525,100,Nacom,0.00,395,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:26:50.539509+00,2025-11-29 13:26:52.120683+00
207b92d0-39d0-4f81-b00d-9119d7a20626,188fa4e3-985c-4048-8913-754cb0560875,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
e0ece833-4e73-4ada-b7d2-25197cf9097d,caa05325-b8e7-4b1c-9d95-03d4e0c7372d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
e58e13b1-cc53-40da-8ecf-3fa4c2c97672,128ac756-bdb8-49d7-8fdb-cdb8fd241d06,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
719b10c0-2de5-43a3-b9e4-d38730a92ad2,7f3bb769-4d7e-4ca9-8527-708da0368be5,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
66570bed-28ce-407d-a5df-43236bba500a,6a565d40-9012-4c89-878c-05bb8b6e2d81,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
762397ff-699f-4bb8-bef6-2e03959fe4c1,3f255f44-40d9-4dc9-970c-d50ddec197b3,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
e8a5e302-93c4-4f6a-8da6-b81ed01dde7a,f1870075-a6e0-47e7-88c6-793320ab3c8f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
bc3dda37-e131-45c1-8595-e047eb751a2f,ab2425d9-e2da-49ac-b8db-2db605e7283f,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
7e0781fc-ab59-4ea4-a57a-3b95b45c151f,802f4d68-bbd0-4220-8218-634975c3774a,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
5b11ed88-05e5-4edb-94a1-13a9b7a93ec2,142af777-fce1-4067-b84b-f684e2fa1170,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
f5b9530d-0587-44d5-9bd9-890a1ff8ed26,b5c2d5dc-e753-40ff-8e01-95c4c497710c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
82e45270-b5a0-478e-a81f-8330e638921c,d29345bb-fd48-4f69-ac81-eeedd4b41e6d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
94ad1072-16af-401b-b32f-3c33fb07c22b,813055ff-e5b7-4538-825c-eb721360e189,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
a51cd72a-1d76-4367-84ee-5fd448eec673,6c9bbb36-0b2d-49ea-9c1b-63209f009773,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
9ac32e07-bde6-4d8d-b172-2cf8c28b3cb6,8daf8ed9-d15f-407f-b827-3a9c01907e62,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
6a89fb69-f4f9-409e-8687-1927a9c9931a,bd028538-520d-45cf-a6f7-27c9f675d663,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
e08417c1-a015-4820-bab2-0e3bafda8c81,de1511df-f963-4ff6-8e3f-2225ba493879,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
27b913c1-b6c1-41a8-ac80-b8aec18dfdcb,26168044-3b5c-43f6-a757-833ba1485d41,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
d3a33394-f4dc-4e3e-b817-eb6309b17b59,e742724a-0ff6-4760-884b-866835460045,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
3e6f2e70-0113-42ae-beaf-f2fed10d70f2,3ce354c8-bcac-44c6-9a94-5274e5f9b389,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
28dac481-b80a-47c3-9de4-693f2774c470,c0aecfcc-3b2f-4117-9f20-e0920df97dc0,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
6732ab00-bca6-4a4b-b9ac-34adfb108299,3dfcdc9d-de8a-45b3-a05f-b83b51097ef5,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
ef81f3a4-9995-4c4c-b2b0-927235077174,bb74b280-db90-4240-ab09-b8c6cf63d553,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
f9cb12f8-523f-47c9-b3f3-ac55aac11502,7ede7b67-42d2-44cd-a530-66f62a68cd54,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
026b8072-f628-4bda-aeda-ce76d2fbccce,2df90a89-455e-4637-8b96-ad01c45f5701,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
713232b8-54d8-49b8-bcc5-9fabb3bd5c76,43560c6b-fda2-4b45-bc0b-7dbbbffff05c,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
4223a8af-8011-4234-b71d-520c3f7b23b0,ff4760c8-5359-43e9-9b42-95a0bf3e3d36,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
b54503c1-f3fd-411d-9830-882aa2c54dc2,a4c43698-c276-4430-b15e-8373b7bbb662,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
a657e586-ce3a-4c5c-b244-f704c13fff5e,30462f07-1c6b-4706-b4fb-288845b3631e,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
ce3898e2-403d-4fc1-8bfd-eb78be76b86a,4f5170f2-1d35-4130-a535-1d93383e406b,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-11-29 13:33:04.23263+00,2025-11-29 13:33:04.23263+00
1bec7e38-0109-4e25-bbad-8e28cdc211a2,0ae1bf21-39e3-4168-9632-457418c7a07d,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,4,1180,100,Ah K'in,0.00,710,360,0,40,2025-11-29 19:41:58.551+00,0,0,,0,9,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,2025-11-29 13:41:42.417785+00,,{},2025-11-29 13:37:09.278078+00,2025-11-29 13:41:59.942645+00
5035c591-f320-4182-981a-9a1416030d75,69681b09-5077-4f77-84cc-67606abd9755,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-12-08 19:24:06.272257+00,2025-12-08 19:24:06.272257+00
5bc3c779-e7f4-4c4a-9bca-c0854ea1e288,f929d6df-8c29-461f-88f5-264facd879e9,a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11,1,0,100,Ajaw,0.00,100,100,0,0,,0,0,,0,0,0,0,,0,0,0,00:00:00,00:00:00,0,0,0,0,,,,,,{},2025-12-17 17:51:43.536295+00,2025-12-17 17:51:43.536295+00
1 id user_id tenant_id level total_xp xp_to_next_level current_rank rank_progress ml_coins ml_coins_earned_total ml_coins_spent_total ml_coins_earned_today last_ml_coins_reset current_streak max_streak streak_started_at days_active_total exercises_completed modules_completed total_score average_score perfect_scores achievements_earned certificates_earned total_time_spent weekly_time_spent sessions_count weekly_xp monthly_xp weekly_exercises global_rank_position class_rank_position school_rank_position last_activity_at last_login_at metadata created_at updated_at
2 7446ef44-11a1-451d-9624-abd95f0eb2ec aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 6 2525 100 Halach Uinic 0.00 1960 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.458823+00 2025-11-29 13:26:52.120683+00
3 06fd9e66-cefc-4c64-a446-37cef9668b36 bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 2 375 100 Ajaw 0.00 260 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.458823+00 2025-11-29 13:26:52.120683+00
4 b3830215-9623-46a6-9624-2c7183f13737 cccccccc-cccc-cccc-cccc-cccccccccccc a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 5 1825 100 Halach Uinic 0.00 1625 180 0 0 0 0 0 8 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 2025-12-02 10:55:24.674923+00 {} 2025-11-29 13:26:50.458823+00 2025-12-02 10:55:24.674923+00
5 1f6076c1-7b54-43f7-9fca-519407e65c4f 2f5a9846-3393-40b2-9e87-0f29238c383f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 2 150 100 Ajaw 0.00 140 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:52.120683+00
6 524efcd5-9c89-4a79-ac4c-f58f92f9fd28 7a6a973e-83f7-4374-a9fc-54258138115f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 25 100 Ajaw 0.00 110 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:52.120683+00
7 88b149bb-5f3b-41bb-885f-e226eb9cac22 b017b792-b327-40dd-aefb-a80312776952 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
8 fe110986-762c-459f-acde-b2c865c237bb 33306a65-a3b1-41d5-a49d-47989957b822 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 75 100 Ajaw 0.00 120 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:52.120683+00
9 f0734a0b-1d9c-4999-bcba-8e3b8f229c80 9951ad75-e9cb-47b3-b478-6bb860ee2530 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 2 375 100 Ajaw 0.00 260 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:52.120683+00
10 0145f432-c383-45d1-9d0f-0c7783a48612 735235f5-260a-4c9b-913c-14a1efd083ea a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 75 100 Ajaw 0.00 135 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:52.120683+00
11 c29ffaef-0392-4fe1-ac41-b502a4052111 5e738038-1743-4aa9-b222-30171300ea9d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 25 100 Ajaw 0.00 110 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:52.120683+00
12 1cb60bdb-800a-4ebc-a9c3-16ecf78d3535 06a24962-e83d-4e94-aad7-ff69f20a9119 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
13 5cba623a-015f-41e9-9de0-da67bdd6b5fb 24e8c563-8854-43d1-b3c9-2f83e91f5a1e a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
14 ee39d06d-d9c5-492a-9855-2210c74b74fd ccd7135c-0fea-4488-9094-9da52df1c98c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
15 c6a7e9dd-ade4-4860-a4e0-882fd5aa0ed1 bf0d3e34-e077-43d1-9626-292f7fae2bd6 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
16 e6be8348-29af-49c4-b49d-4b2d978c951b ebe48628-5e44-4562-97b7-b4950b216247 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:50.539509+00
17 9c4cf796-3768-4182-b1e0-1a38f8187c87 00c742d9-e5f7-4666-9597-5a8ca54d5478 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 3 525 100 Nacom 0.00 395 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:26:50.539509+00 2025-11-29 13:26:52.120683+00
18 207b92d0-39d0-4f81-b00d-9119d7a20626 188fa4e3-985c-4048-8913-754cb0560875 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
19 e0ece833-4e73-4ada-b7d2-25197cf9097d caa05325-b8e7-4b1c-9d95-03d4e0c7372d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
20 e58e13b1-cc53-40da-8ecf-3fa4c2c97672 128ac756-bdb8-49d7-8fdb-cdb8fd241d06 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
21 719b10c0-2de5-43a3-b9e4-d38730a92ad2 7f3bb769-4d7e-4ca9-8527-708da0368be5 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
22 66570bed-28ce-407d-a5df-43236bba500a 6a565d40-9012-4c89-878c-05bb8b6e2d81 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
23 762397ff-699f-4bb8-bef6-2e03959fe4c1 3f255f44-40d9-4dc9-970c-d50ddec197b3 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
24 e8a5e302-93c4-4f6a-8da6-b81ed01dde7a f1870075-a6e0-47e7-88c6-793320ab3c8f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
25 bc3dda37-e131-45c1-8595-e047eb751a2f ab2425d9-e2da-49ac-b8db-2db605e7283f a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
26 7e0781fc-ab59-4ea4-a57a-3b95b45c151f 802f4d68-bbd0-4220-8218-634975c3774a a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
27 5b11ed88-05e5-4edb-94a1-13a9b7a93ec2 142af777-fce1-4067-b84b-f684e2fa1170 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
28 f5b9530d-0587-44d5-9bd9-890a1ff8ed26 b5c2d5dc-e753-40ff-8e01-95c4c497710c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
29 82e45270-b5a0-478e-a81f-8330e638921c d29345bb-fd48-4f69-ac81-eeedd4b41e6d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
30 94ad1072-16af-401b-b32f-3c33fb07c22b 813055ff-e5b7-4538-825c-eb721360e189 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
31 a51cd72a-1d76-4367-84ee-5fd448eec673 6c9bbb36-0b2d-49ea-9c1b-63209f009773 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
32 9ac32e07-bde6-4d8d-b172-2cf8c28b3cb6 8daf8ed9-d15f-407f-b827-3a9c01907e62 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
33 6a89fb69-f4f9-409e-8687-1927a9c9931a bd028538-520d-45cf-a6f7-27c9f675d663 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
34 e08417c1-a015-4820-bab2-0e3bafda8c81 de1511df-f963-4ff6-8e3f-2225ba493879 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
35 27b913c1-b6c1-41a8-ac80-b8aec18dfdcb 26168044-3b5c-43f6-a757-833ba1485d41 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
36 d3a33394-f4dc-4e3e-b817-eb6309b17b59 e742724a-0ff6-4760-884b-866835460045 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
37 3e6f2e70-0113-42ae-beaf-f2fed10d70f2 3ce354c8-bcac-44c6-9a94-5274e5f9b389 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
38 28dac481-b80a-47c3-9de4-693f2774c470 c0aecfcc-3b2f-4117-9f20-e0920df97dc0 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
39 6732ab00-bca6-4a4b-b9ac-34adfb108299 3dfcdc9d-de8a-45b3-a05f-b83b51097ef5 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
40 ef81f3a4-9995-4c4c-b2b0-927235077174 bb74b280-db90-4240-ab09-b8c6cf63d553 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
41 f9cb12f8-523f-47c9-b3f3-ac55aac11502 7ede7b67-42d2-44cd-a530-66f62a68cd54 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
42 026b8072-f628-4bda-aeda-ce76d2fbccce 2df90a89-455e-4637-8b96-ad01c45f5701 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
43 713232b8-54d8-49b8-bcc5-9fabb3bd5c76 43560c6b-fda2-4b45-bc0b-7dbbbffff05c a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
44 4223a8af-8011-4234-b71d-520c3f7b23b0 ff4760c8-5359-43e9-9b42-95a0bf3e3d36 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
45 b54503c1-f3fd-411d-9830-882aa2c54dc2 a4c43698-c276-4430-b15e-8373b7bbb662 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
46 a657e586-ce3a-4c5c-b244-f704c13fff5e 30462f07-1c6b-4706-b4fb-288845b3631e a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
47 ce3898e2-403d-4fc1-8bfd-eb78be76b86a 4f5170f2-1d35-4130-a535-1d93383e406b a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-11-29 13:33:04.23263+00 2025-11-29 13:33:04.23263+00
48 1bec7e38-0109-4e25-bbad-8e28cdc211a2 0ae1bf21-39e3-4168-9632-457418c7a07d a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 4 1180 100 Ah K'in 0.00 710 360 0 40 2025-11-29 19:41:58.551+00 0 0 0 9 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 2025-11-29 13:41:42.417785+00 {} 2025-11-29 13:37:09.278078+00 2025-11-29 13:41:59.942645+00
49 5035c591-f320-4182-981a-9a1416030d75 69681b09-5077-4f77-84cc-67606abd9755 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-12-08 19:24:06.272257+00 2025-12-08 19:24:06.272257+00
50 5bc3c779-e7f4-4c4a-9bca-c0854ea1e288 f929d6df-8c29-461f-88f5-264facd879e9 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 1 0 100 Ajaw 0.00 100 100 0 0 0 0 0 0 0 0 0 0 0 00:00:00 00:00:00 0 0 0 0 {} 2025-12-17 17:51:43.536295+00 2025-12-17 17:51:43.536295+00

View File

@ -0,0 +1,246 @@
--
-- PostgreSQL database dump
--
\restrict kteh5aijQdsTMjnzB1xbEvkDPawhbikecDwbwClvcxgOHhbchFJp4xxlp3L10vn
-- Dumped from database version 16.11 (Ubuntu 16.11-0ubuntu0.24.04.1)
-- Dumped by pg_dump version 16.11 (Ubuntu 16.11-0ubuntu0.24.04.1)
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- Data for Name: users; Type: TABLE DATA; Schema: auth; Owner: -
--
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'authenticated', NULL, 'teacher@gamilit.com', '$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga', '2025-11-29 13:26:50.289631+00', NULL, '', NULL, '', NULL, '', '', NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"name": "Profesor Testing", "role": "admin_teacher", "description": "Usuario profesor de testing"}', false, '2025-11-29 13:26:50.289631+00', '2025-11-29 13:26:50.289631+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'admin_teacher', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'b017b792-b327-40dd-aefb-a80312776952', 'authenticated', NULL, 'joseal.guirre34@gmail.com', '$2b$10$kb9yCB4Y2WBr2.Gth.wC9e8q8bnkZJ6O2X6kFSn.O4VK8d76Cr/xO', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Aguirre", "first_name": "Jose"}', false, '2025-11-18 07:29:05.226874+00', '2025-11-18 07:29:05.226874+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '06a24962-e83d-4e94-aad7-ff69f20a9119', 'authenticated', NULL, 'sergiojimenezesteban63@gmail.com', '$2b$10$8oPdKN15ndCqCOIt12SEO.2yx4D29kQEQGPCC5rtUYWu8Qp5L7/zW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Jimenez", "first_name": "Sergio"}', false, '2025-11-18 08:17:40.925857+00', '2025-11-18 08:17:40.925857+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '24e8c563-8854-43d1-b3c9-2f83e91f5a1e', 'authenticated', NULL, 'Gomezfornite92@gmail.com', '$2b$10$FuEfoSA0jxvBI2f6odMJqux9Gpgvt7Zjk.plRhRatvK0ykkIXxbI.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Gomez", "first_name": "Hugo"}', false, '2025-11-18 08:18:04.240276+00', '2025-11-18 08:18:04.240276+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'bf0d3e34-e077-43d1-9626-292f7fae2bd6', 'authenticated', NULL, 'Aragon494gt54@icloud.com', '$2b$10$lE8M8qWUIsgYLwcHyRGvTOjxdykLVchRVifsMVqCRCZq3bEeXR.xG', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Aragón", "first_name": "Hugo"}', false, '2025-11-18 08:20:17.228812+00', '2025-11-18 08:20:17.228812+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '2f5a9846-3393-40b2-9e87-0f29238c383f', 'authenticated', NULL, 'blu3wt7@gmail.com', '$2b$10$gKRXQ.rmOePqsNKWdxABQuyIZike2oSsYpdfWpQdi5HHDWDUk.3u2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Valentina", "first_name": "Azul"}', false, '2025-11-18 08:32:17.314233+00', '2025-11-18 08:32:17.314233+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5e738038-1743-4aa9-b222-30171300ea9d', 'authenticated', NULL, 'ricardolugo786@icloud.com', '$2b$10$YV1StKIdCPPED/Ft84zR2ONxj/VzzV7zOxjgwMSbDpd2hzvYOGtby', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Lugo", "first_name": "Ricardo"}', false, '2025-11-18 10:15:06.479774+00', '2025-11-18 10:15:06.479774+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '00c742d9-e5f7-4666-9597-5a8ca54d5478', 'authenticated', NULL, 'marbancarlos916@gmail.com', '$2b$10$PfsKOsEEXpGA6YB6eXNBPePo6OV6Am1glUN6Mkunl64bK/ji6uttW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Marban", "first_name": "Carlos"}', false, '2025-11-18 10:29:05.23842+00', '2025-11-18 10:29:05.23842+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '33306a65-a3b1-41d5-a49d-47989957b822', 'authenticated', NULL, 'diego.colores09@gmail.com', '$2b$10$rFlH9alBbgPGVEZMYIV8p.AkeZ30yRCVd5acasFjIt7fpCZhE6RuO', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Colores", "first_name": "Diego"}', false, '2025-11-18 10:29:20.530359+00', '2025-11-18 10:29:20.530359+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '7a6a973e-83f7-4374-a9fc-54258138115f', 'authenticated', NULL, 'hernandezfonsecabenjamin7@gmail.com', '$2b$10$1E6gLqfMojNLYrSKIbatqOh0pHblZ3jWZwbcxTY/DCx7MGADToCVm', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Hernandez", "first_name": "Benjamin"}', false, '2025-11-18 10:37:06.919813+00', '2025-11-18 10:37:06.919813+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'ccd7135c-0fea-4488-9094-9da52df1c98c', 'authenticated', NULL, 'jr7794315@gmail.com', '$2b$10$Ej/Gwx8mGCWg4TnQSjh1r.QZLw/GkUANqXmz4bEfVaNF9E527L02C', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Reyes", "first_name": "Josue"}', false, '2025-11-18 17:53:39.67958+00', '2025-11-18 17:53:39.67958+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '9951ad75-e9cb-47b3-b478-6bb860ee2530', 'authenticated', NULL, 'barraganfer03@gmail.com', '$2b$10$VJ8bS.ksyKpa7oG575r5YOWQYcq8vwmwTa8jMBkCv0dwskF04SHn2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Barragan", "first_name": "Fernando"}', false, '2025-11-18 20:39:27.408624+00', '2025-11-18 20:39:27.408624+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '735235f5-260a-4c9b-913c-14a1efd083ea', 'authenticated', NULL, 'roman.rebollar.marcoantonio1008@gmail.com', '$2b$10$l4eF8UoOB7D8LKDEzTigXOUO7EABhVdYCqknJ/lD6R4p8uF1R4I.W', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Roman", "first_name": "Marco Antonio"}', false, '2025-11-18 21:03:17.326679+00', '2025-11-18 21:03:17.326679+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'ebe48628-5e44-4562-97b7-b4950b216247', 'authenticated', NULL, 'rodrigoguerrero0914@gmail.com', '$2b$10$ihoy7HbOdlqU38zAddpTOuDO7Nqa8.Cr1dEQjCgMpdb30UwCIMhGW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "Guerrero", "first_name": "Rodrigo"}', false, '2025-11-18 21:20:52.303128+00', '2025-11-18 21:20:52.303128+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'd089b1af-462f-4d2c-b0f5-d2528cec8506', 'authenticated', NULL, 'santiagoferrara78@gmail.com', '$2b$10$Wjo3EENjiuddS9BwPMAW1OORZrZpU8ECP9zEXmd4Gvn7orwgjo8O2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 09:21:04.898591+00', '2025-11-24 09:21:04.898591+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'b1cadf36-1f07-46b2-b63d-da72d9b54dc6', 'authenticated', NULL, 'alexanserrv917@gmail.com', '$2b$10$8sT/ObLZUNmiu6CpbceHhenfc7E8zZml8AvB1HUiyOddSLqchggZ2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:26:51.934739+00', '2025-11-24 10:26:51.934739+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'af4d8788-f8a8-4971-bb0d-2f48c150dfc2', 'authenticated', NULL, 'aarizmendi434@gmail.com', '$2b$10$2BAG4EskBG0feGOIva6XyOCBtBJbKJE9h27GU6DmuBH3f.2iK6FoS', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:30:54.728262+00', '2025-11-24 10:30:54.728262+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '26fbc469-10af-4fa3-bd65-e5498188cc4f', 'authenticated', NULL, 'ashernarcisobenitezpalomino@gmail.com', '$2b$10$Bv5vo0GDeseWUWTt.5xV0O9nN93TRVN.vHRigs4vF/ww7Hbnjylam', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:37:35.325342+00', '2025-11-24 10:37:35.325342+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '74ed8c97-ec36-43aa-a1cc-b0c99e4be4e8', 'authenticated', NULL, 'ra.alejandrobm@gmail.com', '$2b$10$QZId3lZBIzBulD7AZCeEKOiL0LBJRekGlQTGiacC70IDwDo2wx7py', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:42:33.424367+00', '2025-11-24 10:42:33.424367+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'f4c46f46-3fb9-40bf-a52b-a8ad2e6a92e1', 'authenticated', NULL, 'abdallahxelhaneriavega@gmail.com', '$2b$10$jQ4SquNUxIO70e7IBYqqLeUw1d.gSCleJ/cwinuWMVlW25a8.pRGG', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:45:19.984994+00', '2025-11-24 10:45:19.984994+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '012adac4-8ffd-47bd-9248-f0c5851e981f', 'authenticated', NULL, '09enriquecampos@gmail.com', '$2b$10$95c9hOplonbo/46O5UlPqummq.AIaGVIZ7YgBstSuOWPbgGersKxy', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:51:54.731982+00', '2025-11-24 10:51:54.731982+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '126b9257-7b0a-4bd6-9ab3-c505ee00e10a', 'authenticated', NULL, 'johhkk22@gmail.com', '$2b$10$Bt6IZ19zuBkly.6QmmPWBeF0kfyVN/O/c3/9bqyUGup3gPZu14DGa', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:53:47.029991+00', '2025-11-24 10:53:47.029991+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '9ac1746e-94a6-4efc-a961-951c015d416e', 'authenticated', NULL, 'edangiel4532@gmail.com', '$2b$10$eZap9LmAws7VtY9sHnS17.RJkhIte5SUobIWaWpuTxTPKjbKgzK.6', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 10:58:12.790316+00', '2025-11-24 10:58:12.790316+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'authenticated', NULL, 'student@gamilit.com', '$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga', '2025-11-29 13:26:50.289631+00', NULL, '', NULL, '', NULL, '', '', NULL, '2025-12-07 03:42:02.528+00', '{"provider": "email", "providers": ["email"]}', '{"name": "Estudiante Testing", "role": "student", "description": "Usuario estudiante de testing"}', false, '2025-11-29 13:26:50.289631+00', '2025-12-07 03:42:02.529507+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '2d9f05d4-44dd-42cd-97aa-d57bd06fecd0', 'authenticated', NULL, 'erickfranco462@gmail.com', '$2b$10$lNzkSO7zbBHQcJJui0O76.a2artcsZHari4Mgkjo4btGww.Wy9/iC', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:00:11.800551+00', '2025-11-24 11:00:11.800551+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'aff5dcc6-32de-4769-9aaf-eda751fa0866', 'authenticated', NULL, 'gallinainsana@gmail.com', '$2b$10$6y/FVa4LqyliI4PXuBxKpepTRwIIRWybFN0NhcAqRM.Kl/cnvXDMq', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:03:17.536383+00', '2025-11-24 11:03:17.536383+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '0cda1645-83c5-445b-80b7-d0e4d436c00c', 'authenticated', NULL, 'leile5257@gmail.com', '$2b$10$ZZX0.z30VPm7BsLF8bNVweQpRZ2ca/1EPlxdIZy0xNaCFugoKL0ci', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:05:17.75852+00', '2025-11-24 11:05:17.75852+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '1364c463-88de-479b-a883-c0b7b362bcf8', 'authenticated', NULL, 'maximiliano.mejia367@gmail.com', '$2b$10$iTfIWKh2ISvPys2bkK2LOOPI24ua7I47oT8dFxHHYW7AuztoZreQa', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:08:58.232003+00', '2025-11-24 11:08:58.232003+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '547eb778-4782-4681-b198-c731bba36147', 'authenticated', NULL, 'fl432025@gmail.com', '$2b$10$aGKv6yhAWwHb07m3N2DxJOXIn5omkP3t2QeSYblhcDo52pB2ZiFQi', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:12:13.692614+00', '2025-11-24 11:12:13.692614+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5fc06693-e408-4eab-a9a3-fcd5f4e01296', 'authenticated', NULL, '7341023901m@gmail.com', '$2b$10$Z/HUBov20g..LZ6RDYax4.NcDuiFD/gn9Nrt7/OPCPBqCoTJUgr3C', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:15:18.276345+00', '2025-11-24 11:15:18.276345+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5d1839f6-b03f-4e12-b236-eca43f4674f2', 'authenticated', NULL, 'segurauriel235@gmail.com', '$2b$10$IfdhPuUOModgrJT7bMfYkODZkXeTcaAReuCQf9BGpK1cT6GiP9UGu', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:17:46.846963+00', '2025-11-24 11:17:46.846963+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '1b310708-6f24-4c6a-88c9-a11f7a7f9763', 'authenticated', NULL, 'angelrabano11@gmail.com', '$2b$10$Sg6q4kErMvxRlZgWM9lCj.PfRg5sCQrwm763d7sfc3iaAUID7y436', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:47:53.790673+00', '2025-11-24 11:47:53.790673+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '3c613b0e-66f9-4640-a599-c9426d8edffb', 'authenticated', NULL, 'daliaayalareyes35@gmail.com', '$2b$10$dd2SQeBqNIZpZWCGMIDu1O8U6MLpWnKF05w641MNOMzHDZ/U5glCe', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:55:08.708961+00', '2025-11-24 11:55:08.708961+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '7ded133e-9b13-4467-9803-edb813f6a9a1', 'authenticated', NULL, 'alexeimongam@gmail.com', '$2b$10$jyQrHAIj6SsnReQ45FrFlOnDgpZtabskpxPuOYgB/h.YPLyZhuld.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 11:55:11.906996+00', '2025-11-24 11:55:11.906996+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '4cc04f54-7771-462d-98aa-a94448bb6ff5', 'authenticated', NULL, 'davidocampovenegas@gmail.com', '$2b$10$8COk10WE5.bXFJnAucEA0efcGQKU6KUXKV9N7n32ZX6aNKORs4McW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 14:52:46.468737+00', '2025-11-24 14:52:46.468737+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'fbbe7d19-048c-45e4-8a9c-cf86d2098c35', 'authenticated', NULL, 'zaid080809@gmail.com', '$2b$10$kdaUWR1BUqPRY7H8YkR.xuuDbqtLcvP5yKW.B0ooPlb.I6b/UU192', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 16:25:03.689847+00', '2025-11-24 16:25:03.689847+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5b3d74e8-fd1a-4c80-96d2-24c54bfe90c4', 'authenticated', NULL, 'ruizcruzabrahamfrancisco@gmail.com', '$2b$10$DXHr682C4/VpesiHa7fRrOjKceiWSDUSx.1LZTbsvuxpqCdMNh/Ii', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 19:46:06.311558+00', '2025-11-24 19:46:06.311558+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '615adf6e-dbf3-480f-a907-3cfb3a64c6d2', 'authenticated', NULL, 'vituschinchilla@gmail.com', '$2b$10$dA8adTYlfhgqhZfACcQkFOCYjXdsmggXnIUluNDoh1zRFgQ6pq5O2', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-24 21:07:26.037867+00', '2025-11-24 21:07:26.037867+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'bf445960-4c1f-4e29-8fb7-31667b183d7e', 'authenticated', NULL, 'bryan@betanzos.com', '$2b$10$Xdfuf4Tfog9QKd1FRLL.7eAaD6tr2cXgPx1/L8xqT1kLLzNHzSM26', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 06:13:30.263795+00', '2025-11-25 06:13:30.263795+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'd5fa4905-a78a-4040-8ad8-23220881c6a6', 'authenticated', NULL, 'loganalexander816@gmail.com', '$2b$10$8zLduh/9L/priag.nujz5utuloO9RnNFFDGdKgI2UniFCOwocEPLq', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 07:37:04.953164+00', '2025-11-25 07:37:04.953164+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '71734c15-cdaa-431b-90f5-97a57e0316a8', 'authenticated', NULL, 'carlois1974@gmail.com', '$2b$10$IfLfJ.q59DZgicR07ckSVOcrkkBJe42m1FECXxaoaodKYSo6uj5wW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 07:41:38.025764+00', '2025-11-25 07:41:38.025764+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '1efe491d-98ef-4c02-acd1-3135f7289072', 'authenticated', NULL, 'enriquecuevascbtis136@gmail.com', '$2b$10$9BX3OQMZmHruffBtN.3WPOFoyea6zgPd8i72DvhJ7vRAdqWKax6GS', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 08:16:33.977647+00', '2025-11-25 08:16:33.977647+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '5ae21325-7450-4c37-82f1-3f9bcd7b6f45', 'authenticated', NULL, 'omarcitogonzalezzavaleta@gmail.com', '$2b$10$RRk3DAgQdiikxVImFIMqquqB.TNpKs3E.RNFtt1rwwTzO24uShri.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 08:17:07.610076+00', '2025-11-25 08:17:07.610076+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'a4d27774-8a51-4660-ad2f-81d0dfd3a5a7', 'authenticated', NULL, 'gustavobm2024cbtis@gmail.com', '$2b$10$lg7KRUTPofcx4Rtyey8J7.XO0gmdBLCFIfK5uP08mqT0qUIl1aTJq', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 08:20:49.649184+00', '2025-11-25 08:20:49.649184+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', '6e30164a-78b0-49b0-bd21-23d7c6c03349', 'authenticated', NULL, 'marianaxsotoxt22@gmail.com', '$2b$10$GQC9yTWiP2vP9GUp0gnhUeLjmw70EI4JQhfJBZbMOlCNXGXb/bt5O', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{"last_name": "", "first_name": ""}', false, '2025-11-25 08:33:18.150784+00', '2025-11-25 08:33:18.150784+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES (NULL, '0ae1bf21-39e3-4168-9632-457418c7a07d', 'authenticated', NULL, 'rckrdmrd@gmail.com', '$2b$10$LiDdaJLA.ZvdFleamkMuvOcIrW0PQMEh5aVZ5Wg5pzhm7gwc5s.1C', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-09 01:22:42.784+00', NULL, '{}', false, '2025-11-29 13:37:09.271457+00', '2025-12-09 01:22:42.785367+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES ('00000000-0000-0000-0000-000000000000', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'authenticated', NULL, 'admin@gamilit.com', '$2b$10$pkqX0/v7H3F5TBTuDTaoYeBjH581pXpjlcNcYmMtXofd/2HjfTuga', '2025-11-29 13:26:50.289631+00', NULL, '', NULL, '', NULL, '', '', NULL, '2025-12-01 00:54:19.615+00', '{"provider": "email", "providers": ["email"]}', '{"name": "Admin GAMILIT", "role": "super_admin", "description": "Usuario administrador de testing"}', false, '2025-11-29 13:26:50.289631+00', '2025-12-01 00:54:19.617766+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'super_admin', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES (NULL, '69681b09-5077-4f77-84cc-67606abd9755', 'authenticated', NULL, 'javiermar06@hotmail.com', '$2b$10$3RHyXnR4BG3NaxP8Ez82FuiGDMNCG7GhNaOsMFigy3BpIVOzCqHMW', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-14 03:51:04.122+00', NULL, '{}', false, '2025-12-08 19:24:06.266895+00', '2025-12-14 03:51:04.123886+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
INSERT INTO auth.users (instance_id, id, aud, role, email, encrypted_password, email_confirmed_at, invited_at, confirmation_token, confirmation_sent_at, recovery_token, recovery_sent_at, email_change_token_new, email_change, email_change_sent_at, last_sign_in_at, raw_app_meta_data, raw_user_meta_data, is_super_admin, created_at, updated_at, phone, phone_confirmed_at, phone_change, phone_change_token, phone_change_sent_at, confirmed_at, email_change_token_current, email_change_confirm_status, banned_until, reauthentication_token, reauthentication_sent_at, is_sso_user, deleted_at, gamilit_role, status) VALUES (NULL, 'f929d6df-8c29-461f-88f5-264facd879e9', 'authenticated', NULL, 'ju188an@gmail.com', '$2b$10$9vUERFnXApdfXuAI7DFve.aa8uDjI5bfm4CI75/EZ2cUre83RytKe', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-17 23:51:43.553+00', NULL, '{}', false, '2025-12-17 17:51:43.530434+00', '2025-12-17 23:51:43.55475+00', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, false, NULL, 'student', 'active');
--
-- Data for Name: profiles; Type: TABLE DATA; Schema: auth_management; Owner: -
--
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Admin GAMILIT', 'Administrador GAMILIT', 'Administrador', 'GAMILIT', 'admin@gamilit.com', '/avatars/admin-testing.png', 'Usuario administrador para testing y desarrollo.', '55-0000-0001', '1985-01-01', NULL, NULL, NULL, 'super_admin', 'active', true, true, '{"theme": "professional", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{"description": "Usuario de testing principal", "testing_user": true}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:50.458823+00', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Profesor Testing', 'Profesor de Testing GAMILIT', 'Profesor', 'Testing', 'teacher@gamilit.com', '/avatars/teacher-testing.png', 'Usuario profesor para testing y desarrollo.', '55-0000-0002', '1980-05-15', NULL, NULL, NULL, 'admin_teacher', 'active', true, true, '{"theme": "teacher", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{"subjects": ["Lengua Española", "Comprensión Lectora"], "testing_user": true}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:50.458823+00', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('cccccccc-cccc-cccc-cccc-cccccccccccc', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Estudiante Testing', 'Estudiante de Testing GAMILIT', 'Estudiante', 'Testing', 'student@gamilit.com', '/avatars/student-testing.png', 'Usuario estudiante para testing y desarrollo.', '55-0000-0003', '2013-09-01', '5', 'EST-TEST-001', NULL, 'student', 'active', true, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "gamification": {"show_rank": true, "show_leaderboard": true, "show_achievements": true}, "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{"interests": ["lectura", "ciencia"], "testing_user": true, "learning_style": "visual"}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:50.458823+00', 'cccccccc-cccc-cccc-cccc-cccccccccccc', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('b017b792-b327-40dd-aefb-a80312776952', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Jose Aguirre', 'Jose Aguirre', 'Jose', 'Aguirre', 'joseal.guirre34@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 07:29:05.229254+00', '2025-11-18 07:29:05.229254+00', 'b017b792-b327-40dd-aefb-a80312776952', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('06a24962-e83d-4e94-aad7-ff69f20a9119', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Sergio Jimenez', 'Sergio Jimenez', 'Sergio', 'Jimenez', 'sergiojimenezesteban63@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 08:17:40.928077+00', '2025-11-18 08:17:40.928077+00', '06a24962-e83d-4e94-aad7-ff69f20a9119', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('24e8c563-8854-43d1-b3c9-2f83e91f5a1e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Hugo Gomez', 'Hugo Gomez', 'Hugo', 'Gomez', 'Gomezfornite92@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 08:18:04.242047+00', '2025-11-18 08:18:04.242047+00', '24e8c563-8854-43d1-b3c9-2f83e91f5a1e', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('bf0d3e34-e077-43d1-9626-292f7fae2bd6', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Hugo Aragón', 'Hugo Aragón', 'Hugo', 'Aragón', 'Aragon494gt54@icloud.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 08:20:17.230714+00', '2025-11-18 08:20:17.230714+00', 'bf0d3e34-e077-43d1-9626-292f7fae2bd6', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('2f5a9846-3393-40b2-9e87-0f29238c383f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Azul Valentina', 'Azul Valentina', 'Azul', 'Valentina', 'blu3wt7@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 08:32:17.315932+00', '2025-11-18 08:32:17.315932+00', '2f5a9846-3393-40b2-9e87-0f29238c383f', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('5e738038-1743-4aa9-b222-30171300ea9d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ricardo Lugo', 'Ricardo Lugo', 'Ricardo', 'Lugo', 'ricardolugo786@icloud.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 10:15:06.481498+00', '2025-11-18 10:15:06.481498+00', '5e738038-1743-4aa9-b222-30171300ea9d', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('00c742d9-e5f7-4666-9597-5a8ca54d5478', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Carlos Marban', 'Carlos Marban', 'Carlos', 'Marban', 'marbancarlos916@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 10:29:05.240413+00', '2025-11-18 10:29:05.240413+00', '00c742d9-e5f7-4666-9597-5a8ca54d5478', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('33306a65-a3b1-41d5-a49d-47989957b822', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Diego Colores', 'Diego Colores', 'Diego', 'Colores', 'diego.colores09@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 10:29:20.531883+00', '2025-11-18 10:29:20.531883+00', '33306a65-a3b1-41d5-a49d-47989957b822', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('7a6a973e-83f7-4374-a9fc-54258138115f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Benjamin Hernandez', 'Benjamin Hernandez', 'Benjamin', 'Hernandez', 'hernandezfonsecabenjamin7@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 10:37:06.9215+00', '2025-11-18 10:37:06.9215+00', '7a6a973e-83f7-4374-a9fc-54258138115f', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('ccd7135c-0fea-4488-9094-9da52df1c98c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Josue Reyes', 'Josue Reyes', 'Josue', 'Reyes', 'jr7794315@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 17:53:39.681271+00', '2025-11-18 17:53:39.681271+00', 'ccd7135c-0fea-4488-9094-9da52df1c98c', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('9951ad75-e9cb-47b3-b478-6bb860ee2530', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Fernando Barragan', 'Fernando Barragan', 'Fernando', 'Barragan', 'barraganfer03@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 20:39:27.410436+00', '2025-11-18 20:39:27.410436+00', '9951ad75-e9cb-47b3-b478-6bb860ee2530', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('735235f5-260a-4c9b-913c-14a1efd083ea', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Marco Antonio Roman', 'Marco Antonio Roman', 'Marco Antonio', 'Roman', 'roman.rebollar.marcoantonio1008@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 21:03:17.328254+00', '2025-11-18 21:03:17.328254+00', '735235f5-260a-4c9b-913c-14a1efd083ea', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('ebe48628-5e44-4562-97b7-b4950b216247', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Rodrigo Guerrero', 'Rodrigo Guerrero', 'Rodrigo', 'Guerrero', 'rodrigoguerrero0914@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-18 21:20:52.304488+00', '2025-11-18 21:20:52.304488+00', 'ebe48628-5e44-4562-97b7-b4950b216247', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('3f255f44-40d9-4dc9-970c-d50ddec197b3', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'alexanserrv917@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'b1cadf36-1f07-46b2-b63d-da72d9b54dc6', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('f1870075-a6e0-47e7-88c6-793320ab3c8f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'carlois1974@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '71734c15-cdaa-431b-90f5-97a57e0316a8', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('ab2425d9-e2da-49ac-b8db-2db605e7283f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'gustavobm2024cbtis@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'a4d27774-8a51-4660-ad2f-81d0dfd3a5a7', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('802f4d68-bbd0-4220-8218-634975c3774a', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'gallinainsana@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'aff5dcc6-32de-4769-9aaf-eda751fa0866', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('142af777-fce1-4067-b84b-f684e2fa1170', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'zaid080809@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'fbbe7d19-048c-45e4-8a9c-cf86d2098c35', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('b5c2d5dc-e753-40ff-8e01-95c4c497710c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'davidocampovenegas@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '4cc04f54-7771-462d-98aa-a94448bb6ff5', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('d29345bb-fd48-4f69-ac81-eeedd4b41e6d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'marianaxsotoxt22@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '6e30164a-78b0-49b0-bd21-23d7c6c03349', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('813055ff-e5b7-4538-825c-eb721360e189', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'leile5257@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '0cda1645-83c5-445b-80b7-d0e4d436c00c', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('6c9bbb36-0b2d-49ea-9c1b-63209f009773', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'ashernarcisobenitezpalomino@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '26fbc469-10af-4fa3-bd65-e5498188cc4f', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('8daf8ed9-d15f-407f-b827-3a9c01907e62', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'ruizcruzabrahamfrancisco@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '5b3d74e8-fd1a-4c80-96d2-24c54bfe90c4', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('bd028538-520d-45cf-a6f7-27c9f675d663', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'daliaayalareyes35@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '3c613b0e-66f9-4640-a599-c9426d8edffb', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('de1511df-f963-4ff6-8e3f-2225ba493879', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'ra.alejandrobm@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '74ed8c97-ec36-43aa-a1cc-b0c99e4be4e8', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('26168044-3b5c-43f6-a757-833ba1485d41', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'enriquecuevascbtis136@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '1efe491d-98ef-4c02-acd1-3135f7289072', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('e742724a-0ff6-4760-884b-866835460045', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'fl432025@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '547eb778-4782-4681-b198-c731bba36147', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('3ce354c8-bcac-44c6-9a94-5274e5f9b389', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'abdallahxelhaneriavega@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'f4c46f46-3fb9-40bf-a52b-a8ad2e6a92e1', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('188fa4e3-985c-4048-8913-754cb0560875', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', '7341023901m@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '5fc06693-e408-4eab-a9a3-fcd5f4e01296', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('caa05325-b8e7-4b1c-9d95-03d4e0c7372d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'vituschinchilla@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '615adf6e-dbf3-480f-a907-3cfb3a64c6d2', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('128ac756-bdb8-49d7-8fdb-cdb8fd241d06', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'alexeimongam@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '7ded133e-9b13-4467-9803-edb813f6a9a1', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('7f3bb769-4d7e-4ca9-8527-708da0368be5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'angelrabano11@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '1b310708-6f24-4c6a-88c9-a11f7a7f9763', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('6a565d40-9012-4c89-878c-05bb8b6e2d81', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'loganalexander816@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'd5fa4905-a78a-4040-8ad8-23220881c6a6', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('7ede7b67-42d2-44cd-a530-66f62a68cd54', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'bryan@betanzos.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'bf445960-4c1f-4e29-8fb7-31667b183d7e', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('2df90a89-455e-4637-8b96-ad01c45f5701', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'johhkk22@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '126b9257-7b0a-4bd6-9ab3-c505ee00e10a', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('43560c6b-fda2-4b45-bc0b-7dbbbffff05c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'edangiel4532@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '9ac1746e-94a6-4efc-a961-951c015d416e', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('ff4760c8-5359-43e9-9b42-95a0bf3e3d36', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'aarizmendi434@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'af4d8788-f8a8-4971-bb0d-2f48c150dfc2', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('a4c43698-c276-4430-b15e-8373b7bbb662', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'santiagoferrara78@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', 'd089b1af-462f-4d2c-b0f5-d2528cec8506', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('30462f07-1c6b-4706-b4fb-288845b3631e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', '09enriquecampos@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '012adac4-8ffd-47bd-9248-f0c5851e981f', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('4f5170f2-1d35-4130-a535-1d93383e406b', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'maximiliano.mejia367@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '1364c463-88de-479b-a883-c0b7b362bcf8', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('c0aecfcc-3b2f-4117-9f20-e0920df97dc0', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'segurauriel235@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '5d1839f6-b03f-4e12-b236-eca43f4674f2', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('3dfcdc9d-de8a-45b3-a05f-b83b51097ef5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'omarcitogonzalezzavaleta@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '5ae21325-7450-4c37-82f1-3f9bcd7b6f45', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('bb74b280-db90-4240-ab09-b8c6cf63d553', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, '', '', 'erickfranco462@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:30:54.277737+00', '2025-11-29 13:30:54.277737+00', '2d9f05d4-44dd-42cd-97aa-d57bd06fecd0', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('0ae1bf21-39e3-4168-9632-457418c7a07d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, 'rckrdmrd@gmail.com', NULL, 'rckrdmrd@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-11-29 13:37:09.278078+00', '2025-11-29 13:37:09.278078+00', '0ae1bf21-39e3-4168-9632-457418c7a07d', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('69681b09-5077-4f77-84cc-67606abd9755', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, 'Javier', ' Mar', 'javiermar06@hotmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-12-08 19:24:06.272257+00', '2025-12-08 19:24:06.272257+00', '69681b09-5077-4f77-84cc-67606abd9755', NULL);
INSERT INTO auth_management.profiles (id, tenant_id, display_name, full_name, first_name, last_name, email, avatar_url, bio, phone, date_of_birth, grade_level, student_id, school_id, role, status, email_verified, phone_verified, preferences, last_sign_in_at, last_activity_at, metadata, created_at, updated_at, user_id, deleted_at) VALUES ('f929d6df-8c29-461f-88f5-264facd879e9', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', NULL, NULL, 'Juan', 'pa', 'ju188an@gmail.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'student', 'active', false, false, '{"theme": "detective", "language": "es", "timezone": "America/Mexico_City", "sound_enabled": true, "notifications_enabled": true}', NULL, NULL, '{}', '2025-12-17 17:51:43.536295+00', '2025-12-17 17:51:43.536295+00', 'f929d6df-8c29-461f-88f5-264facd879e9', NULL);
--
-- Data for Name: user_ranks; Type: TABLE DATA; Schema: gamification_system; Owner: -
--
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('aef81f6b-b9c4-4f80-b27f-8f9bf8c2cd97', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.458823+00', NULL, true, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:50.458823+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('4cadc6a3-c15e-410a-88f5-c0254463ca8a', 'b017b792-b327-40dd-aefb-a80312776952', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('8c1d72aa-fead-4bff-bf47-b34ceab62a40', '06a24962-e83d-4e94-aad7-ff69f20a9119', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('840cabba-4a80-40fa-a3e0-0e218e09463e', '24e8c563-8854-43d1-b3c9-2f83e91f5a1e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('913ae601-8ab4-4056-864c-517e100bef5b', 'bf0d3e34-e077-43d1-9626-292f7fae2bd6', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('eb382620-70b8-4842-b8cf-ad51eb1c7266', '2f5a9846-3393-40b2-9e87-0f29238c383f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('207ff6ef-a56d-4fc1-942f-5a50e0c842da', '5e738038-1743-4aa9-b222-30171300ea9d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('64946395-a46c-4e93-abf7-5b827e4dcf12', '33306a65-a3b1-41d5-a49d-47989957b822', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('66cb0dd1-2c47-4572-99ec-c97ccee95e53', '7a6a973e-83f7-4374-a9fc-54258138115f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('241b6cea-03d0-4f9c-97b6-7d49d9175cfb', 'ccd7135c-0fea-4488-9094-9da52df1c98c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b14b22be-bd9d-485c-9477-b4122c63cbfb', '9951ad75-e9cb-47b3-b478-6bb860ee2530', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('4e7cf7a1-8ef4-4d20-902b-ba1c57faad51', '735235f5-260a-4c9b-913c-14a1efd083ea', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('d0500d4e-17ec-46be-94a1-4e2500e4b9a8', 'ebe48628-5e44-4562-97b7-b4950b216247', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:26:50.539509+00', NULL, true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('9a4e06cc-0a50-4ff9-b781-d29edff7bbd6', '00c742d9-e5f7-4666-9597-5a8ca54d5478', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Nacom', 'Ajaw', 0, NULL, 0, NULL, 0, 100, NULL, NULL, '2025-11-29 13:26:52.138221+00', '2025-11-29 13:26:50.539509+00', true, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.138221+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('33b12003-65b0-4f50-8bda-6eeebedc3413', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Halach Uinic', 'Ah K''in', 0, NULL, 0, NULL, 0, 500, NULL, NULL, '2025-11-29 13:26:52.158657+00', '2025-11-29 13:26:52.158657+00', true, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:52.138221+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('7c3b01ab-b75b-4464-8858-91c1ff805c32', '3dfcdc9d-de8a-45b3-a05f-b83b51097ef5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('53ec34ee-bd3c-462f-b5b0-317705c0399d', '3f255f44-40d9-4dc9-970c-d50ddec197b3', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b2461bb7-7107-48dd-923f-de4ff8e86a67', 'e742724a-0ff6-4760-884b-866835460045', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('890ba444-c64f-4680-894d-56bf30cbcf5c', 'f1870075-a6e0-47e7-88c6-793320ab3c8f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('a7b16bb9-efa6-4f10-8fe0-992adbd8c482', 'b5c2d5dc-e753-40ff-8e01-95c4c497710c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('c6eb5dd4-a987-4560-b22d-645ca31791e6', '142af777-fce1-4067-b84b-f684e2fa1170', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('520cd26c-5222-4579-8f1d-72f4be8e98d3', 'c0aecfcc-3b2f-4117-9f20-e0920df97dc0', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('2971dbbf-33de-4f12-9e47-48c9a3b145df', '7ede7b67-42d2-44cd-a530-66f62a68cd54', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('cb9feef2-0f2d-4949-b212-3b6d7dbfe2fa', 'caa05325-b8e7-4b1c-9d95-03d4e0c7372d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('89181d4a-a47b-4449-81fa-09a7e1d67534', 'a4c43698-c276-4430-b15e-8373b7bbb662', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('998f3c88-8932-4d91-af11-7bca6c03bbc3', 'bb74b280-db90-4240-ab09-b8c6cf63d553', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('e22e4620-57fc-47ad-ae53-f45ecc17932f', '4f5170f2-1d35-4130-a535-1d93383e406b', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b9e35a4b-ade2-4fa0-bd58-38ffcf5ca614', '802f4d68-bbd0-4220-8218-634975c3774a', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('365f3ac3-2880-42a8-8799-0c465b0a4ed9', 'de1511df-f963-4ff6-8e3f-2225ba493879', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('21152c4c-b082-40a7-938b-e7486730e2bb', '188fa4e3-985c-4048-8913-754cb0560875', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b1c76243-62c4-4e73-8e7b-152b82e41c93', '128ac756-bdb8-49d7-8fdb-cdb8fd241d06', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('e521b5a1-250b-4e96-a2cd-e8736f1f3fbe', '6c9bbb36-0b2d-49ea-9c1b-63209f009773', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('a106676f-8723-492b-b4f1-1b9256da8a4d', '813055ff-e5b7-4538-825c-eb721360e189', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('8cf5754b-7af4-429f-8e57-b0f2e4f740d6', '3ce354c8-bcac-44c6-9a94-5274e5f9b389', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('89526d39-7d29-4d97-a65b-94a42dfb45e2', 'ab2425d9-e2da-49ac-b8db-2db605e7283f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('fa25a282-3568-481a-878d-c424f6eaee95', 'ff4760c8-5359-43e9-9b42-95a0bf3e3d36', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('aee1d9bf-b4fe-4512-9cf0-4cc90413692e', '8daf8ed9-d15f-407f-b827-3a9c01907e62', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('69621cdf-cc64-4f2b-85f3-d1f09b54cbf0', '7f3bb769-4d7e-4ca9-8527-708da0368be5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b4c93d8d-fb84-4ba2-91d7-78abd5a780de', '26168044-3b5c-43f6-a757-833ba1485d41', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('3444f9aa-7c1b-452c-bfbb-af58dc70e70b', 'bd028538-520d-45cf-a6f7-27c9f675d663', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('c8aec5d3-4a66-40b6-a8e7-9b2edd4225b1', '2df90a89-455e-4637-8b96-ad01c45f5701', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('e284ffd8-9d58-4564-95c4-075721724643', '6a565d40-9012-4c89-878c-05bb8b6e2d81', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('abfa66bf-dc3d-426a-b4ec-538677b39cd5', '43560c6b-fda2-4b45-bc0b-7dbbbffff05c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('b26939b5-2dc1-4643-b46c-c4a3d6a5203f', 'd29345bb-fd48-4f69-ac81-eeedd4b41e6d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('564433a1-e5f1-48ce-8807-06f5b9ea1418', '30462f07-1c6b-4706-b4fb-288845b3631e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-11-29 13:33:25.124715+00', NULL, true, '{}', '2025-11-29 13:33:25.124715+00', '2025-11-29 13:33:25.124715+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('3c88a791-ad9b-4988-9351-b5e9df60c9a4', '0ae1bf21-39e3-4168-9632-457418c7a07d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ah K''in', 'Nacom', 0, NULL, 0, NULL, 0, 250, NULL, NULL, '2025-11-29 13:41:42.417785+00', '2025-11-29 13:40:27.516619+00', true, '{}', '2025-11-29 13:37:09.278078+00', '2025-11-29 13:41:42.417785+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('cb04ef70-2738-4c9e-b32a-a92643b8a3f9', 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Halach Uinic', 'Ah K''in', 0, NULL, 0, NULL, 0, 500, NULL, NULL, '2025-11-30 20:12:46.263821+00', '2025-11-29 13:26:52.146305+00', true, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-30 20:12:46.263821+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('1de77cef-003a-4d08-8ccc-8bd4001fa62c', '69681b09-5077-4f77-84cc-67606abd9755', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-12-08 19:24:06.272257+00', NULL, true, '{}', '2025-12-08 19:24:06.272257+00', '2025-12-08 19:24:06.272257+00');
INSERT INTO gamification_system.user_ranks (id, user_id, tenant_id, current_rank, previous_rank, rank_progress_percentage, modules_required_for_next, modules_completed_for_rank, xp_required_for_next, xp_earned_for_rank, ml_coins_bonus, certificate_url, badge_url, achieved_at, previous_rank_achieved_at, is_current, rank_metadata, created_at, updated_at) VALUES ('63b40546-38a8-4c80-bf11-3504c73150bb', 'f929d6df-8c29-461f-88f5-264facd879e9', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'Ajaw', NULL, 0, NULL, 0, NULL, 0, 0, NULL, NULL, '2025-12-17 17:51:43.536295+00', NULL, true, '{}', '2025-12-17 17:51:43.536295+00', '2025-12-17 17:51:43.536295+00');
--
-- Data for Name: user_stats; Type: TABLE DATA; Schema: gamification_system; Owner: -
--
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('88b149bb-5f3b-41bb-885f-e226eb9cac22', 'b017b792-b327-40dd-aefb-a80312776952', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('1cb60bdb-800a-4ebc-a9c3-16ecf78d3535', '06a24962-e83d-4e94-aad7-ff69f20a9119', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('5cba623a-015f-41e9-9de0-da67bdd6b5fb', '24e8c563-8854-43d1-b3c9-2f83e91f5a1e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('c6a7e9dd-ade4-4860-a4e0-882fd5aa0ed1', 'bf0d3e34-e077-43d1-9626-292f7fae2bd6', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('ee39d06d-d9c5-492a-9855-2210c74b74fd', 'ccd7135c-0fea-4488-9094-9da52df1c98c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e6be8348-29af-49c4-b49d-4b2d978c951b', 'ebe48628-5e44-4562-97b7-b4950b216247', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:50.539509+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('9c4cf796-3768-4182-b1e0-1a38f8187c87', '00c742d9-e5f7-4666-9597-5a8ca54d5478', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 3, 525, 100, 'Nacom', 0.00, 395, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('1f6076c1-7b54-43f7-9fca-519407e65c4f', '2f5a9846-3393-40b2-9e87-0f29238c383f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 2, 150, 100, 'Ajaw', 0.00, 140, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('1bec7e38-0109-4e25-bbad-8e28cdc211a2', '0ae1bf21-39e3-4168-9632-457418c7a07d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 4, 1180, 100, 'Ah K''in', 0.00, 710, 360, 0, 40, '2025-11-29 19:41:58.551+00', 0, 0, NULL, 0, 9, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, '2025-11-29 13:41:42.417785+00', NULL, '{}', '2025-11-29 13:37:09.278078+00', '2025-11-29 13:41:59.942645+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('524efcd5-9c89-4a79-ac4c-f58f92f9fd28', '7a6a973e-83f7-4374-a9fc-54258138115f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 25, 100, 'Ajaw', 0.00, 110, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('5035c591-f320-4182-981a-9a1416030d75', '69681b09-5077-4f77-84cc-67606abd9755', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-12-08 19:24:06.272257+00', '2025-12-08 19:24:06.272257+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('fe110986-762c-459f-acde-b2c865c237bb', '33306a65-a3b1-41d5-a49d-47989957b822', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 75, 100, 'Ajaw', 0.00, 120, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('06fd9e66-cefc-4c64-a446-37cef9668b36', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 2, 375, 100, 'Ajaw', 0.00, 260, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('f0734a0b-1d9c-4999-bcba-8e3b8f229c80', '9951ad75-e9cb-47b3-b478-6bb860ee2530', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 2, 375, 100, 'Ajaw', 0.00, 260, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('7446ef44-11a1-451d-9624-abd95f0eb2ec', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 6, 2525, 100, 'Halach Uinic', 0.00, 1960, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.458823+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('0145f432-c383-45d1-9d0f-0c7783a48612', '735235f5-260a-4c9b-913c-14a1efd083ea', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 75, 100, 'Ajaw', 0.00, 135, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('c29ffaef-0392-4fe1-ac41-b502a4052111', '5e738038-1743-4aa9-b222-30171300ea9d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 25, 100, 'Ajaw', 0.00, 110, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:26:50.539509+00', '2025-11-29 13:26:52.120683+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('762397ff-699f-4bb8-bef6-2e03959fe4c1', '3f255f44-40d9-4dc9-970c-d50ddec197b3', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e8a5e302-93c4-4f6a-8da6-b81ed01dde7a', 'f1870075-a6e0-47e7-88c6-793320ab3c8f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('bc3dda37-e131-45c1-8595-e047eb751a2f', 'ab2425d9-e2da-49ac-b8db-2db605e7283f', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('7e0781fc-ab59-4ea4-a57a-3b95b45c151f', '802f4d68-bbd0-4220-8218-634975c3774a', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('5b11ed88-05e5-4edb-94a1-13a9b7a93ec2', '142af777-fce1-4067-b84b-f684e2fa1170', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('f5b9530d-0587-44d5-9bd9-890a1ff8ed26', 'b5c2d5dc-e753-40ff-8e01-95c4c497710c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('82e45270-b5a0-478e-a81f-8330e638921c', 'd29345bb-fd48-4f69-ac81-eeedd4b41e6d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('94ad1072-16af-401b-b32f-3c33fb07c22b', '813055ff-e5b7-4538-825c-eb721360e189', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('a51cd72a-1d76-4367-84ee-5fd448eec673', '6c9bbb36-0b2d-49ea-9c1b-63209f009773', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('9ac32e07-bde6-4d8d-b172-2cf8c28b3cb6', '8daf8ed9-d15f-407f-b827-3a9c01907e62', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('6a89fb69-f4f9-409e-8687-1927a9c9931a', 'bd028538-520d-45cf-a6f7-27c9f675d663', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e08417c1-a015-4820-bab2-0e3bafda8c81', 'de1511df-f963-4ff6-8e3f-2225ba493879', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('27b913c1-b6c1-41a8-ac80-b8aec18dfdcb', '26168044-3b5c-43f6-a757-833ba1485d41', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('d3a33394-f4dc-4e3e-b817-eb6309b17b59', 'e742724a-0ff6-4760-884b-866835460045', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('3e6f2e70-0113-42ae-beaf-f2fed10d70f2', '3ce354c8-bcac-44c6-9a94-5274e5f9b389', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('207b92d0-39d0-4f81-b00d-9119d7a20626', '188fa4e3-985c-4048-8913-754cb0560875', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e0ece833-4e73-4ada-b7d2-25197cf9097d', 'caa05325-b8e7-4b1c-9d95-03d4e0c7372d', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('e58e13b1-cc53-40da-8ecf-3fa4c2c97672', '128ac756-bdb8-49d7-8fdb-cdb8fd241d06', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('719b10c0-2de5-43a3-b9e4-d38730a92ad2', '7f3bb769-4d7e-4ca9-8527-708da0368be5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('66570bed-28ce-407d-a5df-43236bba500a', '6a565d40-9012-4c89-878c-05bb8b6e2d81', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('f9cb12f8-523f-47c9-b3f3-ac55aac11502', '7ede7b67-42d2-44cd-a530-66f62a68cd54', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('026b8072-f628-4bda-aeda-ce76d2fbccce', '2df90a89-455e-4637-8b96-ad01c45f5701', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('713232b8-54d8-49b8-bcc5-9fabb3bd5c76', '43560c6b-fda2-4b45-bc0b-7dbbbffff05c', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('4223a8af-8011-4234-b71d-520c3f7b23b0', 'ff4760c8-5359-43e9-9b42-95a0bf3e3d36', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('b54503c1-f3fd-411d-9830-882aa2c54dc2', 'a4c43698-c276-4430-b15e-8373b7bbb662', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('a657e586-ce3a-4c5c-b244-f704c13fff5e', '30462f07-1c6b-4706-b4fb-288845b3631e', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('ce3898e2-403d-4fc1-8bfd-eb78be76b86a', '4f5170f2-1d35-4130-a535-1d93383e406b', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('28dac481-b80a-47c3-9de4-693f2774c470', 'c0aecfcc-3b2f-4117-9f20-e0920df97dc0', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('6732ab00-bca6-4a4b-b9ac-34adfb108299', '3dfcdc9d-de8a-45b3-a05f-b83b51097ef5', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('ef81f3a4-9995-4c4c-b2b0-927235077174', 'bb74b280-db90-4240-ab09-b8c6cf63d553', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-11-29 13:33:04.23263+00', '2025-11-29 13:33:04.23263+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('b3830215-9623-46a6-9624-2c7183f13737', 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 5, 1825, 100, 'Halach Uinic', 0.00, 1625, 180, 0, 0, NULL, 0, 0, NULL, 0, 8, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, '2025-12-02 10:55:24.674923+00', NULL, '{}', '2025-11-29 13:26:50.458823+00', '2025-12-02 10:55:24.674923+00');
INSERT INTO gamification_system.user_stats (id, user_id, tenant_id, level, total_xp, xp_to_next_level, current_rank, rank_progress, ml_coins, ml_coins_earned_total, ml_coins_spent_total, ml_coins_earned_today, last_ml_coins_reset, current_streak, max_streak, streak_started_at, days_active_total, exercises_completed, modules_completed, total_score, average_score, perfect_scores, achievements_earned, certificates_earned, total_time_spent, weekly_time_spent, sessions_count, weekly_xp, monthly_xp, weekly_exercises, global_rank_position, class_rank_position, school_rank_position, last_activity_at, last_login_at, metadata, created_at, updated_at) VALUES ('5bc3c779-e7f4-4c4a-9bca-c0854ea1e288', 'f929d6df-8c29-461f-88f5-264facd879e9', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 1, 0, 100, 'Ajaw', 0.00, 100, 100, 0, 0, NULL, 0, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, '00:00:00', '00:00:00', 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, '{}', '2025-12-17 17:51:43.536295+00', '2025-12-17 17:51:43.536295+00');
--
-- PostgreSQL database dump complete
--
\unrestrict kteh5aijQdsTMjnzB1xbEvkDPawhbikecDwbwClvcxgOHhbchFJp4xxlp3L10vn

View File

@ -410,6 +410,7 @@ execute_sql_files "$DDL_DIR/schemas/communication/functions" "*.sql" "Funciones
execute_sql_files "$DDL_DIR/schemas/communication/triggers" "*.sql" "Triggers de comunicación (si existen)"
execute_sql_files "$DDL_DIR/schemas/communication/indexes" "*.sql" "Índices de comunicación (si existen)"
execute_sql_files "$DDL_DIR/schemas/communication/views" "*.sql" "Vistas de comunicación (si existen)"
execute_sql_files "$DDL_DIR/schemas/communication/rls-policies" "*.sql" "RLS Policies de comunicación (P0-002 AUDIT-DB-001)"
log_success "FASE 10.5 completada - Communication schema creado (DB-122)"
log ""
@ -531,6 +532,7 @@ execute_sql "$SEEDS_DIR/notifications/01-notification_templates.sql" "Seeds: not
# 16.2: Auth Management (tenants y auth_providers)
execute_sql "$SEEDS_DIR/auth_management/01-tenants.sql" "Seeds: tenants"
execute_sql "$SEEDS_DIR/auth_management/02-tenants-production.sql" "Seeds: tenants-production (13 tenants usuarios reales)"
execute_sql "$SEEDS_DIR/auth_management/02-auth_providers.sql" "Seeds: auth_providers"
# 16.3: Auth (usuarios de testing y demo)
@ -541,18 +543,36 @@ execute_sql "$SEEDS_DIR/auth/02-production-users.sql" "Seeds: users (production
# REASON: initialize_user_stats() trigger needs modules to exist when creating module_progress
execute_sql "$SEEDS_DIR/educational_content/01-modules.sql" "Seeds: modules (5)"
# 16.4.1: Educational Content (dependencias y taxonomías) - P0-SEEDS AUDIT-DB-001
execute_sql "$SEEDS_DIR/educational_content/11-module_dependencies.sql" "Seeds: module_dependencies (6 dependencias - P0 AUDIT-DB-001)"
execute_sql "$SEEDS_DIR/educational_content/12-taxonomies.sql" "Seeds: taxonomies (4 taxonomías - P0 AUDIT-DB-001)"
# 16.5: Auth Management (profiles para usuarios)
# NOTE: Trigger initialize_user_stats() fires here and creates module_progress automatically
execute_sql "$SEEDS_DIR/auth_management/04-profiles-complete.sql" "Seeds: profiles (testing + demo - 22)"
# DEPRECATED: 05-profiles-demo.sql movido a _deprecated/ - requiere auth.users que no existen
execute_sql "$SEEDS_DIR/auth_management/06-profiles-production.sql" "Seeds: profiles (production - 13 usuarios)"
# 16.5.0.1: Auth Management (roles de usuarios) - P0-SEEDS AUDIT-DB-001
# MUST BE AFTER profiles (FK user_id references profiles)
execute_sql "$SEEDS_DIR/auth_management/07-user_roles.sql" "Seeds: user_roles (8 roles - P0 AUDIT-DB-001)"
# 16.5.1: Content Management (templates de contenido)
execute_sql "$SEEDS_DIR/content_management/01-default-templates.sql" "Seeds: content_templates"
# 16.5.1.1: Content Management (contenido Marie Curie) - P0-SEEDS AUDIT-DB-001
execute_sql "$SEEDS_DIR/content_management/02-marie_curie_content.sql" "Seeds: marie_curie_content (6 artículos - P0 AUDIT-DB-001)"
# 16.5.2: Social Features (escuelas, aulas y miembros)
execute_sql "$SEEDS_DIR/social_features/00-schools-default.sql" "Seeds: schools (sistema - default)"
execute_sql "$SEEDS_DIR/social_features/01-schools.sql" "Seeds: schools (demo)"
execute_sql "$SEEDS_DIR/social_features/02-classrooms.sql" "Seeds: classrooms (demo)"
execute_sql "$SEEDS_DIR/social_features/03-classroom-members.sql" "Seeds: classroom_members (demo)"
execute_sql "$SEEDS_DIR/social_features/04-friendships.sql" "Seeds: friendships (10 amistades + 3 pending)"
# 16.5.3: Auth Management (asignación de escuela a admins) - 2025-12-15
# MUST BE AFTER profiles AND schools
execute_sql "$SEEDS_DIR/auth_management/08-assign-admin-schools.sql" "Seeds: assign admin schools (2025-12-15)"
# 16.6: Educational Content (ejercicios)
execute_sql "$SEEDS_DIR/educational_content/02-exercises-module1.sql" "Seeds: Module 1 - Literal (5 exercises)"
@ -583,6 +603,10 @@ execute_sql "$SEEDS_DIR/gamification_system/01-achievement_categories.sql" "Seed
execute_sql "$SEEDS_DIR/gamification_system/02-leaderboard_metadata.sql" "Seeds: leaderboard_metadata"
execute_sql "$SEEDS_DIR/gamification_system/03-maya_ranks.sql" "Seeds: maya_ranks"
execute_sql "$SEEDS_DIR/gamification_system/04-achievements.sql" "Seeds: achievements (30 logros demo - 2025-11-29 updated)"
# 16.6.0.1: Mission Templates - P0-SEEDS AUDIT-DB-001
execute_sql "$SEEDS_DIR/gamification_system/10-mission_templates.sql" "Seeds: mission_templates (11 templates - P0 AUDIT-DB-001)"
execute_sql "$SEEDS_DIR/gamification_system/11-missions-production-users.sql" "Seeds: missions-production (8 misiones por usuario prod)"
execute_sql "$SEEDS_DIR/gamification_system/12-shop_categories.sql" "Seeds: shop_categories (5 categorías - 2025-11-29 NEW)"
execute_sql "$SEEDS_DIR/gamification_system/13-shop_items.sql" "Seeds: shop_items (20 items - 2025-11-29 NEW)"
execute_sql "$SEEDS_DIR/gamification_system/05-user_stats.sql" "Seeds: user_stats"

View File

@ -2,34 +2,33 @@
-- GLIT Platform - Prerequisites (ENUMs y Funciones Base)
-- Descripción: Todos los tipos y funciones que deben existir ANTES de crear tablas
-- Creado: 2025-11-02
-- Actualizado: 2025-11-11 (DB-111 - Agregados roles Supabase)
-- Actualizado: 2025-11-11 (DB-111 - Agregados roles estándar RLS)
-- ============================================================================
-- ============================================================================
-- ROLES DE SUPABASE (para compatibilidad local)
-- ROLES ESTÁNDAR PARA RLS (Row Level Security)
-- ============================================================================
-- Nota: Estos roles existen por defecto en Supabase Cloud pero no en PostgreSQL local.
-- Se crean condicionalmente para que RLS policies funcionen en ambos ambientes.
-- Refs: https://supabase.com/docs/guides/database/postgres/roles
-- Nota: Estos roles son patrón estándar de la industria para RLS en PostgreSQL.
-- Se crean condicionalmente para que RLS policies funcionen correctamente.
DO $$ BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'authenticated') THEN
CREATE ROLE authenticated;
COMMENT ON ROLE authenticated IS 'Supabase role: usuarios autenticados (cualquier rol GAMILIT)';
COMMENT ON ROLE authenticated IS 'Rol RLS: usuarios autenticados (cualquier rol GAMILIT)';
END IF;
END $$;
DO $$ BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'anon') THEN
CREATE ROLE anon;
COMMENT ON ROLE anon IS 'Supabase role: usuarios anónimos (sin autenticar)';
COMMENT ON ROLE anon IS 'Rol RLS: usuarios anónimos (sin autenticar)';
END IF;
END $$;
DO $$ BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'service_role') THEN
CREATE ROLE service_role;
COMMENT ON ROLE service_role IS 'Supabase role: servicio backend con privilegios elevados';
COMMENT ON ROLE service_role IS 'Rol RLS: servicio backend con privilegios elevados';
END IF;
END $$;
@ -111,8 +110,19 @@ EXCEPTION WHEN duplicate_object THEN null; END $$;
-- 📚 Documentación: gamification_system.achievement_category
-- Requerimiento: docs/01-requerimientos/02-gamificacion/RF-GAM-001-achievements.md
-- Especificación: docs/02-especificaciones-tecnicas/02-gamificacion/ET-GAM-001-achievements.md
-- VERSIÓN: 1.1 (2025-12-15) - Agregados 'collection' y 'hidden' para alineación con Frontend
DO $$ BEGIN
CREATE TYPE gamification_system.achievement_category AS ENUM ('progress', 'streak', 'completion', 'social', 'special', 'mastery', 'exploration');
CREATE TYPE gamification_system.achievement_category AS ENUM (
'progress', -- Logros de progreso general
'streak', -- Logros de rachas consecutivas
'completion', -- Logros de completar contenido
'social', -- Logros sociales (amigos, grupos)
'special', -- Logros especiales/eventos
'mastery', -- Logros de maestría/dominio
'exploration', -- Logros de exploración
'collection', -- Logros de colección (V1.1)
'hidden' -- Logros ocultos/secretos (V1.1)
);
EXCEPTION WHEN duplicate_object THEN null; END $$;
-- 📚 Documentación: gamification_system.achievement_type
@ -182,18 +192,19 @@ DO $$ BEGIN
-- Roadmap: docs/04-fase-backlog/
-- Fecha: Movido a backlog 2025-11-19 (DB-126)
-- Module 4: Lectura Digital (5 mecánicas) ⚠️ BACKLOG
-- Module 4: Lectura Digital (9 mecánicas) ⚠️ BACKLOG
-- Requieren: Validación de fuentes, análisis de imágenes, IA multimodal
'analisis_memes', 'infografia_interactiva', 'navegacion_hipertextual', 'quiz_tiktok', 'verificador_fake_news',
-- Module 4: Producción Textual Digital (4 mecánicas adicionales) - AGREGADO 2025-12-18
'chat_literario', 'email_formal', 'ensayo_argumentativo', 'resena_critica',
-- Module 5: Producción Lectora (3 mecánicas) ⚠️ BACKLOG
-- Requieren: Rúbricas de evaluación creativa, revisión humana/IA
'comic_digital', 'diario_multimedia', 'video_carta'
-- ====================================================================
-- REMOVIDO 2025-11-17: Mecánicas no implementadas movidas a comentarios
-- ACTUALIZADO 2025-12-18: Agregados 4 tipos M4 previamente comentados
-- ====================================================================
-- Futuros Módulo 4: 'resena_critica', 'chat_literario', 'email_formal', 'ensayo_argumentativo'
-- Auxiliares potenciales: 'comprension_auditiva', 'collage_prensa', 'texto_movimiento', 'call_to_action'
);
EXCEPTION WHEN duplicate_object THEN null; END $$;

View File

@ -1,6 +1,6 @@
# Schema: auth
Extensión del sistema de autenticación de Supabase
Schema base de autenticación (patrón estándar de la industria)
## Estructura

View File

@ -15,7 +15,7 @@ SET search_path TO auth, public;
DROP TABLE IF EXISTS auth.users CASCADE;
CREATE TABLE auth.users (
-- Core Supabase-compatible columns
-- Core authentication columns (patrón estándar de la industria)
instance_id uuid,
id uuid DEFAULT gen_random_uuid() NOT NULL,
aud varchar(255) DEFAULT 'authenticated',

View File

@ -0,0 +1,117 @@
-- =====================================================
-- Enable RLS for auth_management schema
-- Description: Habilita Row Level Security en tablas críticas
-- Created: 2025-12-14
-- Priority: P0 - CRÍTICO (Auditoría AUDIT-DB-001)
-- =====================================================
--
-- IMPORTANTE: Las políticas están definidas en 01-policies.sql
-- Este archivo SOLO habilita RLS en las tablas.
--
-- Sin RLS habilitado, las políticas NO se aplican y cualquier
-- usuario puede acceder a todos los datos.
-- =====================================================
-- =====================================================
-- TABLE: auth_management.profiles
-- Description: Perfiles de usuario (109 FKs dependen de esta tabla)
-- Risk: CRÍTICO - Datos personales expuestos
-- =====================================================
ALTER TABLE auth_management.profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.profiles FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.user_sessions
-- Description: Sesiones activas de usuario
-- Risk: ALTO - Información de sesiones expuesta
-- =====================================================
ALTER TABLE auth_management.user_sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.user_sessions FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.email_verification_tokens
-- Description: Tokens de verificación de email
-- Risk: ALTO - Tokens sensibles expuestos
-- =====================================================
ALTER TABLE auth_management.email_verification_tokens ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.email_verification_tokens FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.password_reset_tokens
-- Description: Tokens de reset de contraseña
-- Risk: CRÍTICO - Tokens de reset expuestos
-- =====================================================
ALTER TABLE auth_management.password_reset_tokens ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.password_reset_tokens FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.user_preferences
-- Description: Preferencias de usuario
-- Risk: MEDIO - Preferencias personales expuestas
-- =====================================================
ALTER TABLE auth_management.user_preferences ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.user_preferences FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.memberships
-- Description: Membresías de usuario en tenants
-- Risk: MEDIO - Información de membresía expuesta
-- =====================================================
ALTER TABLE auth_management.memberships ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.memberships FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.user_suspensions
-- Description: Suspensiones de usuario
-- Risk: ALTO - Información de suspensiones expuesta
-- =====================================================
ALTER TABLE auth_management.user_suspensions ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.user_suspensions FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.security_events
-- Description: Eventos de seguridad
-- Risk: ALTO - Log de eventos de seguridad expuesto
-- =====================================================
ALTER TABLE auth_management.security_events ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.security_events FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.tenants
-- Description: Información de tenants
-- Risk: MEDIO - Datos de organización expuestos
-- =====================================================
ALTER TABLE auth_management.tenants ENABLE ROW LEVEL SECURITY;
ALTER TABLE auth_management.tenants FORCE ROW LEVEL SECURITY;
-- =====================================================
-- TABLE: auth_management.user_roles (si existe tabla física)
-- NOTE: Verificar si user_roles existe como tabla o es derivada
-- =====================================================
-- ALTER TABLE auth_management.user_roles ENABLE ROW LEVEL SECURITY;
-- ALTER TABLE auth_management.user_roles FORCE ROW LEVEL SECURITY;
-- =====================================================
-- SUMMARY
-- =====================================================
-- Tablas con RLS habilitado: 9
-- - profiles (CRÍTICO)
-- - user_sessions (ALTO)
-- - email_verification_tokens (ALTO)
-- - password_reset_tokens (CRÍTICO)
-- - user_preferences (MEDIO)
-- - memberships (MEDIO)
-- - user_suspensions (ALTO)
-- - security_events (ALTO)
-- - tenants (MEDIO)
--
-- Tablas sin RLS (por diseño):
-- - auth_attempts (sistema-only, SECURITY DEFINER)
-- - roles (catálogo estático)
-- - auth_providers (catálogo estático)
-- =====================================================
-- Verificación (ejecutar después)
-- SELECT schemaname, tablename, rowsecurity
-- FROM pg_tables
-- WHERE schemaname = 'auth_management';

View File

@ -0,0 +1,82 @@
-- =====================================================
-- Trigger: trg_ensure_profile_name
-- Table: auth_management.profiles
-- Function: ensure_profile_name
-- Event: BEFORE INSERT OR UPDATE
-- Level: FOR EACH ROW
-- Description: Asegura que first_name, last_name y full_name tengan valores,
-- extrayendo del email si es necesario
-- Created: 2025-12-18
-- =====================================================
-- Función que extrae nombre del email si no se proporciona
CREATE OR REPLACE FUNCTION auth_management.ensure_profile_name()
RETURNS TRIGGER AS $$
DECLARE
email_prefix TEXT;
extracted_name TEXT;
BEGIN
-- Si first_name está vacío o es NULL, extraer del email
IF NEW.first_name IS NULL OR TRIM(NEW.first_name) = '' THEN
-- Obtener parte antes del @
email_prefix := SPLIT_PART(NEW.email, '@', 1);
-- Limpiar: quitar números, reemplazar puntos/guiones por espacios, capitalizar
extracted_name := INITCAP(
TRIM(
REGEXP_REPLACE(
REGEXP_REPLACE(
email_prefix,
'[0-9]+', '', 'g' -- Quitar números
),
'[._-]+', ' ', 'g' -- Puntos/guiones a espacios
)
)
);
-- Si después de limpiar queda vacío, usar 'Usuario'
IF extracted_name = '' THEN
extracted_name := 'Usuario';
END IF;
NEW.first_name := extracted_name;
END IF;
-- Si last_name está vacío o es NULL, poner valor por defecto
IF NEW.last_name IS NULL OR TRIM(NEW.last_name) = '' THEN
NEW.last_name := 'Usuario';
END IF;
-- Siempre computar full_name como concatenación de first_name + last_name
NEW.full_name := TRIM(COALESCE(NEW.first_name, '') || ' ' || COALESCE(NEW.last_name, ''));
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Comentario de la función
COMMENT ON FUNCTION auth_management.ensure_profile_name() IS
'Asegura first_name/last_name/full_name tengan valores. Extrae del email si es necesario. Previene "Unknown Student" en la UI.';
-- Eliminar trigger si existe
DROP TRIGGER IF EXISTS trg_ensure_profile_name ON auth_management.profiles CASCADE;
-- Crear trigger BEFORE INSERT para asegurar nombres
CREATE TRIGGER trg_ensure_profile_name
BEFORE INSERT ON auth_management.profiles
FOR EACH ROW
EXECUTE FUNCTION auth_management.ensure_profile_name();
-- También aplicar en UPDATE para correcciones
DROP TRIGGER IF EXISTS trg_ensure_profile_name_update ON auth_management.profiles CASCADE;
CREATE TRIGGER trg_ensure_profile_name_update
BEFORE UPDATE ON auth_management.profiles
FOR EACH ROW
WHEN (NEW.first_name IS DISTINCT FROM OLD.first_name
OR NEW.last_name IS DISTINCT FROM OLD.last_name
OR NEW.full_name IS DISTINCT FROM OLD.full_name)
EXECUTE FUNCTION auth_management.ensure_profile_name();
-- Mensaje de confirmación
DO $$ BEGIN RAISE NOTICE 'Trigger trg_ensure_profile_name created successfully'; END $$;

View File

@ -0,0 +1,158 @@
-- =====================================================
-- RLS Policies for communication.messages
-- Description: Políticas de seguridad para mensajes privados
-- Created: 2025-12-14
-- Priority: P0 - CRÍTICO (Auditoría AUDIT-DB-001)
-- =====================================================
--
-- Security Strategy:
-- - Users can only see messages where they are sender or recipient
-- - Users can only see classroom messages if they are members
-- - Moderation access for admins
-- - Soft-delete respects ownership
-- =====================================================
-- =====================================================
-- Enable RLS
-- =====================================================
ALTER TABLE communication.messages ENABLE ROW LEVEL SECURITY;
ALTER TABLE communication.messages FORCE ROW LEVEL SECURITY;
-- =====================================================
-- Drop existing policies (if any)
-- =====================================================
DROP POLICY IF EXISTS messages_select_own ON communication.messages;
DROP POLICY IF EXISTS messages_select_classroom ON communication.messages;
DROP POLICY IF EXISTS messages_select_admin ON communication.messages;
DROP POLICY IF EXISTS messages_insert_own ON communication.messages;
DROP POLICY IF EXISTS messages_update_own ON communication.messages;
DROP POLICY IF EXISTS messages_delete_own ON communication.messages;
-- =====================================================
-- SELECT Policies
-- =====================================================
-- Policy: messages_select_own
-- Purpose: Users can read messages where they are sender or recipient
CREATE POLICY messages_select_own
ON communication.messages
AS PERMISSIVE
FOR SELECT
TO public
USING (
sender_id = current_setting('app.current_user_id', true)::uuid
OR recipient_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY messages_select_own ON communication.messages IS
'Permite a los usuarios ver mensajes donde son remitente o destinatario';
-- Policy: messages_select_classroom
-- Purpose: Users can read classroom messages if they are members
CREATE POLICY messages_select_classroom
ON communication.messages
AS PERMISSIVE
FOR SELECT
TO public
USING (
classroom_id IS NOT NULL
AND EXISTS (
SELECT 1 FROM social_features.classroom_members cm
WHERE cm.classroom_id = communication.messages.classroom_id
AND cm.student_id = current_setting('app.current_user_id', true)::uuid
)
);
COMMENT ON POLICY messages_select_classroom ON communication.messages IS
'Permite a los miembros del aula ver mensajes del aula';
-- Policy: messages_select_admin
-- Purpose: Admins can read all messages for moderation
CREATE POLICY messages_select_admin
ON communication.messages
AS PERMISSIVE
FOR SELECT
TO public
USING (
EXISTS (
SELECT 1 FROM auth_management.profiles p
WHERE p.id = current_setting('app.current_user_id', true)::uuid
AND p.role IN ('super_admin', 'admin_teacher')
)
);
COMMENT ON POLICY messages_select_admin ON communication.messages IS
'Permite a los administradores ver todos los mensajes (moderación)';
-- =====================================================
-- INSERT Policies
-- =====================================================
-- Policy: messages_insert_own
-- Purpose: Users can send messages as themselves
CREATE POLICY messages_insert_own
ON communication.messages
AS PERMISSIVE
FOR INSERT
TO public
WITH CHECK (
sender_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY messages_insert_own ON communication.messages IS
'Los usuarios solo pueden enviar mensajes como ellos mismos';
-- =====================================================
-- UPDATE Policies
-- =====================================================
-- Policy: messages_update_own
-- Purpose: Users can update/edit their own messages
CREATE POLICY messages_update_own
ON communication.messages
AS PERMISSIVE
FOR UPDATE
TO public
USING (
sender_id = current_setting('app.current_user_id', true)::uuid
)
WITH CHECK (
sender_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY messages_update_own ON communication.messages IS
'Los usuarios solo pueden editar sus propios mensajes';
-- =====================================================
-- DELETE Policies
-- =====================================================
-- Policy: messages_delete_own
-- Purpose: Users can soft-delete their own messages
CREATE POLICY messages_delete_own
ON communication.messages
AS PERMISSIVE
FOR DELETE
TO public
USING (
sender_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY messages_delete_own ON communication.messages IS
'Los usuarios solo pueden eliminar sus propios mensajes';
-- =====================================================
-- SUMMARY
-- =====================================================
-- Total policies: 6
-- - SELECT: 3 (own, classroom members, admin)
-- - INSERT: 1 (only as self)
-- - UPDATE: 1 (only own messages)
-- - DELETE: 1 (only own messages)
--
-- Security enforced:
-- - Users cannot read other users' direct messages
-- - Users cannot read classroom messages unless members
-- - Users cannot impersonate others (sender_id check)
-- - Admins have moderation access (audit trail preserved)
-- =====================================================

View File

@ -176,6 +176,7 @@ COMMENT ON FUNCTION educational_content.validate_rueda_inferencias_text IS
-- ============================================================================
-- FUNCIÓN: validate_rueda_inferencias (WRAPPER ESTÁNDAR)
-- Descripción: Wrapper con firma estándar para integración con el sistema
-- FIX 2025-12-15: Soporte para estructura categoryExpectations del seed
-- ============================================================================
CREATE OR REPLACE FUNCTION educational_content.validate_rueda_inferencias(
@ -200,11 +201,14 @@ DECLARE
v_max_length INTEGER;
v_fragments_solution JSONB;
v_fragments_submitted JSONB;
v_fragment_states JSONB;
v_fragment_id TEXT;
v_user_text TEXT;
v_fragment_solution JSONB;
v_keywords JSONB;
v_fragment_points INTEGER;
v_category_id TEXT;
v_fragment_state JSONB;
v_validation_result JSONB;
v_total_fragments INTEGER := 0;
v_valid_fragments INTEGER := 0;
@ -219,6 +223,7 @@ BEGIN
END IF;
v_fragments_submitted := p_submitted_answer->'fragments';
v_fragment_states := p_submitted_answer->'fragmentStates';
IF v_fragments_submitted IS NULL THEN
RAISE EXCEPTION 'Invalid submitted_answer format: missing "fragments" object';
@ -259,11 +264,66 @@ BEGIN
CONTINUE;
END IF;
-- Extraer keywords y puntos del fragmento
v_keywords := v_fragment_solution->'keywords';
v_fragment_points := COALESCE((v_fragment_solution->>'points')::INTEGER, 20);
-- ====================================================================
-- FIX 2025-12-15: Soporte para estructura categoryExpectations
-- El seed tiene: { categoryExpectations: { "cat-literal": { keywords, points }, ... } }
-- En lugar de: { keywords, points } directamente en el fragment
-- ====================================================================
IF v_fragment_solution ? 'categoryExpectations' THEN
-- Nueva estructura con categorías
-- Buscar categoryId en fragmentStates para este fragment
v_category_id := 'cat-literal'; -- default fallback
IF v_fragment_states IS NOT NULL THEN
SELECT state INTO v_fragment_state
FROM jsonb_array_elements(v_fragment_states) AS state
WHERE state->>'fragmentId' = v_fragment_id;
IF v_fragment_state IS NOT NULL THEN
v_category_id := COALESCE(v_fragment_state->>'categoryId', 'cat-literal');
END IF;
END IF;
-- Extraer keywords y points de categoryExpectations[categoryId]
v_keywords := v_fragment_solution->'categoryExpectations'->v_category_id->'keywords';
v_fragment_points := COALESCE(
(v_fragment_solution->'categoryExpectations'->v_category_id->>'points')::INTEGER,
20
);
-- Si la categoría no existe, usar fallback a cat-literal
IF v_keywords IS NULL THEN
v_keywords := v_fragment_solution->'categoryExpectations'->'cat-literal'->'keywords';
v_fragment_points := COALESCE(
(v_fragment_solution->'categoryExpectations'->'cat-literal'->>'points')::INTEGER,
20
);
v_category_id := 'cat-literal (fallback)';
END IF;
ELSE
-- Estructura flat legacy
v_keywords := v_fragment_solution->'keywords';
v_fragment_points := COALESCE((v_fragment_solution->>'points')::INTEGER, 20);
v_category_id := 'flat';
END IF;
-- ====================================================================
-- END FIX 2025-12-15
-- ====================================================================
v_total_points := v_total_points + v_fragment_points;
-- Validar que v_keywords no sea NULL
IF v_keywords IS NULL THEN
v_results := v_results || jsonb_build_object(
'fragment_id', v_fragment_id,
'is_valid', false,
'error', format('Keywords not found for fragment %s (category: %s)', v_fragment_id, v_category_id),
'points', 0,
'category_used', v_category_id
);
CONTINUE;
END IF;
-- Validar el fragmento usando la función auxiliar
v_validation_result := educational_content._validate_single_fragment(
v_keywords,
@ -284,10 +344,12 @@ BEGIN
-- Agregar resultado del fragmento al detalle
v_results := v_results || jsonb_build_object(
'fragment_id', v_fragment_id,
'category_used', v_category_id,
'is_valid', v_validation_result->'is_valid',
'matched_keywords', v_validation_result->'matched_keywords',
'keyword_count', v_validation_result->'keyword_count',
'points', v_validation_result->'points',
'max_points', v_fragment_points,
'feedback', v_validation_result->'feedback'
);
END LOOP;
@ -307,16 +369,16 @@ BEGIN
END;
END IF;
-- 5. Determinar si es correcto
is_correct := (v_valid_fragments = v_total_fragments);
-- 5. Determinar si es correcto (al menos passing_score, normalmente 70%)
is_correct := (score >= 70);
-- 6. Generar feedback
IF is_correct THEN
IF v_valid_fragments = v_total_fragments THEN
feedback := format('¡Excelente! Todas las %s inferencias son válidas. Has demostrado comprensión profunda del texto.',
v_total_fragments);
ELSIF v_valid_fragments > 0 THEN
feedback := format('%s de %s inferencias válidas. Revisa los fragmentos marcados para mejorar tu respuesta.',
v_valid_fragments, v_total_fragments);
feedback := format('%s de %s inferencias válidas (Puntuación: %s%%). Revisa los fragmentos marcados para mejorar tu respuesta.',
v_valid_fragments, v_total_fragments, score);
ELSE
feedback := format('Ninguna inferencia válida. Asegúrate de incluir conceptos clave del texto y cumplir con la longitud requerida (%s-%s caracteres).',
v_min_length, v_max_length);
@ -328,11 +390,7 @@ BEGIN
'valid_fragments', v_valid_fragments,
'total_points_possible', v_total_points,
'points_earned', v_accumulated_score,
'percentage', CASE
WHEN v_total_fragments > 0
THEN ROUND((v_valid_fragments::NUMERIC / v_total_fragments) * 100)
ELSE 0
END,
'percentage', score,
'validation_criteria', jsonb_build_object(
'min_keywords', v_min_keywords,
'min_length', v_min_length,
@ -344,4 +402,9 @@ END;
$$;
COMMENT ON FUNCTION educational_content.validate_rueda_inferencias IS
'Wrapper estándar para validación de rueda de inferencias. Recibe formato { fragments: { "frag-1": "texto...", ... } } y valida cada fragmento acumulando puntos.';
'Wrapper estándar para validación de rueda de inferencias.
Soporta DOS estructuras de solución:
1. NUEVA (categoryExpectations): { fragments: [{ id, categoryExpectations: { cat-xxx: { keywords, points } } }] }
2. LEGACY (flat): { fragments: [{ id, keywords, points }] }
El frontend envía fragmentStates con categoryId para indicar qué categoría usó el usuario.
FIX 2025-12-15: Corregido para manejar estructura categoryExpectations del seed.';

View File

@ -1,9 +1,17 @@
-- =====================================================
-- Function: gamification_system.update_missions_updated_at
-- Description: No description available
-- Description: DEPRECATED - Usar gamilit.update_updated_at_column()
-- Parameters: None
-- Returns: trigger
-- Created: 2025-10-27
-- Modified: 2025-12-14 (P0-DUP Auditoría AUDIT-DB-001)
-- =====================================================
--
-- DEPRECATED: Esta función es redundante.
-- Todos los triggers deben usar gamilit.update_updated_at_column()
-- para garantizar consistencia de timezone (gamilit.now_mexico())
--
-- Cambio: NOW() → gamilit.now_mexico() para consistencia de timezone
-- =====================================================
CREATE OR REPLACE FUNCTION gamification_system.update_missions_updated_at()
@ -11,7 +19,11 @@ CREATE OR REPLACE FUNCTION gamification_system.update_missions_updated_at()
LANGUAGE plpgsql
AS $function$
BEGIN
NEW.updated_at = NOW();
-- P0-DUP: Corregido para usar timezone México (antes usaba NOW())
NEW.updated_at = gamilit.now_mexico();
RETURN NEW;
END;
$function$;
COMMENT ON FUNCTION gamification_system.update_missions_updated_at() IS
'DEPRECATED: Usar gamilit.update_updated_at_column(). Corregido 2025-12-14 para usar gamilit.now_mexico()';

View File

@ -1,9 +1,17 @@
-- =====================================================
-- Function: gamification_system.update_notifications_updated_at
-- Description: No description available
-- Description: DEPRECATED - Usar gamilit.update_updated_at_column()
-- Parameters: None
-- Returns: trigger
-- Created: 2025-10-27
-- Modified: 2025-12-14 (P0-DUP Auditoría AUDIT-DB-001)
-- =====================================================
--
-- DEPRECATED: Esta función es redundante.
-- Todos los triggers deben usar gamilit.update_updated_at_column()
-- para garantizar consistencia de timezone (gamilit.now_mexico())
--
-- Cambio: NOW() → gamilit.now_mexico() para consistencia de timezone
-- =====================================================
CREATE OR REPLACE FUNCTION gamification_system.update_notifications_updated_at()
@ -11,7 +19,11 @@ CREATE OR REPLACE FUNCTION gamification_system.update_notifications_updated_at()
LANGUAGE plpgsql
AS $function$
BEGIN
NEW.updated_at = NOW();
-- P0-DUP: Corregido para usar timezone México (antes usaba NOW())
NEW.updated_at = gamilit.now_mexico();
RETURN NEW;
END;
$function$;
COMMENT ON FUNCTION gamification_system.update_notifications_updated_at() IS
'DEPRECATED: Usar gamilit.update_updated_at_column(). Corregido 2025-12-14 para usar gamilit.now_mexico()';

View File

@ -5,6 +5,7 @@
-- Schema: gamification_system
-- Type: FUNCTION (IMMUTABLE - can be inlined and optimized)
-- Created: 2025-11-29
-- Updated: 2025-12-14 (v2.1 - Sync with 03-maya_ranks.sql seeds)
-- Origin: Integrated from P0-001-migrate-maya-rank-values.sql
-- =============================================================================
@ -16,24 +17,25 @@
-- Returns: TEXT - The Maya rank name
-- Note: This is a pure function with no database dependencies
--
-- Rank Thresholds:
-- - Ajaw: 0-999 XP (Level 1)
-- - Nacom: 1,000-2,999 XP (Level 2)
-- - Ah K'in: 3,000-5,999 XP (Level 3)
-- - Halach Uinic: 6,000-9,999 XP (Level 4)
-- - K'uk'ulkan: 10,000+ XP (Level 5, Maximum)
-- Rank Thresholds v2.1 (synced with 03-maya_ranks.sql):
-- - Ajaw: 0-499 XP (Level 1)
-- - Nacom: 500-999 XP (Level 2)
-- - Ah K'in: 1,000-1,499 XP (Level 3)
-- - Halach Uinic: 1,500-1,899 XP (Level 4)
-- - K'uk'ulkan: 1,900+ XP (Level 5, Maximum)
-- =============================================================================
CREATE OR REPLACE FUNCTION gamification_system.calculate_maya_rank_from_xp(xp INTEGER)
RETURNS TEXT AS $$
BEGIN
IF xp < 1000 THEN
-- v2.1 thresholds (synced with 03-maya_ranks.sql seeds)
IF xp < 500 THEN
RETURN 'Ajaw';
ELSIF xp < 3000 THEN
ELSIF xp < 1000 THEN
RETURN 'Nacom';
ELSIF xp < 6000 THEN
ELSIF xp < 1500 THEN
RETURN 'Ah K''in';
ELSIF xp < 10000 THEN
ELSIF xp < 1900 THEN
RETURN 'Halach Uinic';
ELSE
RETURN 'K''uk''ulkan';
@ -43,8 +45,8 @@ $$ LANGUAGE plpgsql IMMUTABLE;
COMMENT ON FUNCTION gamification_system.calculate_maya_rank_from_xp(INTEGER) IS
'Pure function: Calculates Maya rank from XP value without database queries.
IMMUTABLE for query optimization. Thresholds: Ajaw(0), Nacom(1000), Ah K''in(3000),
Halach Uinic(6000), K''uk''ulkan(10000+).';
IMMUTABLE for query optimization. v2.1 Thresholds: Ajaw(0-499), Nacom(500-999),
Ah K''in(1000-1499), Halach Uinic(1500-1899), K''uk''ulkan(1900+).';
-- =============================================================================
@ -56,6 +58,7 @@ COMMENT ON FUNCTION gamification_system.calculate_maya_rank_from_xp(INTEGER) IS
-- rank TEXT - Current rank name
-- Returns: NUMERIC(5,2) - Progress percentage (0.00 to 100.00)
-- Note: This is a pure function with no database dependencies
-- Updated: 2025-12-14 (v2.1 - Sync with 03-maya_ranks.sql seeds)
-- =============================================================================
CREATE OR REPLACE FUNCTION gamification_system.calculate_rank_progress_percentage(
@ -67,20 +70,20 @@ DECLARE
xp_in_rank INTEGER;
rank_size INTEGER;
BEGIN
-- Calculate XP earned within the current rank
-- Calculate XP earned within the current rank (v2.1 thresholds)
CASE rank
WHEN 'Ajaw' THEN
xp_in_rank := xp;
rank_size := 1000;
xp_in_rank := xp; -- 0-499 XP
rank_size := 500;
WHEN 'Nacom' THEN
xp_in_rank := xp - 1000;
rank_size := 2000;
xp_in_rank := xp - 500; -- 500-999 XP
rank_size := 500;
WHEN 'Ah K''in' THEN
xp_in_rank := xp - 3000;
rank_size := 3000;
xp_in_rank := xp - 1000; -- 1000-1499 XP
rank_size := 500;
WHEN 'Halach Uinic' THEN
xp_in_rank := xp - 6000;
rank_size := 4000;
xp_in_rank := xp - 1500; -- 1500-1899 XP
rank_size := 400;
WHEN 'K''uk''ulkan' THEN
-- Maximum rank always shows 100%
RETURN 100.00;
@ -101,6 +104,7 @@ $$ LANGUAGE plpgsql IMMUTABLE;
COMMENT ON FUNCTION gamification_system.calculate_rank_progress_percentage(INTEGER, TEXT) IS
'Pure function: Calculates percentage progress within a Maya rank.
Returns 0-100 based on XP earned within the rank. Maximum rank returns 100%.
v2.1 thresholds: Ajaw(500), Nacom(500), Ah K''in(500), Halach Uinic(400).
IMMUTABLE for query optimization.';

View File

@ -1,7 +1,11 @@
-- Nombre: calculate_user_rank
-- Descripción: Calcula el rango actual del usuario basado en XP total y misiones completadas
-- Descripción: Calcula el rango actual del usuario basado en XP total y módulos completados
-- Schema: gamification_system
-- Tipo: FUNCTION
--
-- CHANGELOG:
-- 2025-12-15: CORR-P0-001 - Cambiar missions_completed → modules_completed
-- (missions_completed no existe en tabla user_stats)
CREATE OR REPLACE FUNCTION gamification_system.calculate_user_rank(p_user_id UUID)
RETURNS TABLE (
@ -9,37 +13,41 @@ RETURNS TABLE (
current_rank VARCHAR,
next_rank VARCHAR,
xp_to_next_rank BIGINT,
missions_to_next_rank INTEGER,
modules_to_next_rank INTEGER, -- Renombrado: missions → modules
rank_percentage NUMERIC(5,2)
) AS $$
DECLARE
v_total_xp BIGINT;
v_missions_completed INTEGER;
v_modules_completed INTEGER; -- Renombrado: missions → modules
v_current_rank VARCHAR;
v_next_rank VARCHAR;
v_next_rank_xp BIGINT;
v_next_rank_missions INTEGER;
v_next_rank_modules INTEGER; -- Renombrado: missions → modules
BEGIN
-- Obtener estadísticas del usuario
SELECT total_xp, missions_completed INTO v_total_xp, v_missions_completed
FROM gamification_system.user_stats
WHERE user_id = p_user_id;
-- CORR-P0-001: Usar modules_completed en lugar de missions_completed (columna no existe)
-- FIX: Usar alias 'us' para evitar ambigüedad con output column 'user_id'
SELECT us.total_xp, us.modules_completed INTO v_total_xp, v_modules_completed
FROM gamification_system.user_stats us
WHERE us.user_id = p_user_id;
IF NOT FOUND THEN
RETURN;
END IF;
-- Determinar rango actual basado en XP
SELECT current_rank INTO v_current_rank
FROM gamification_system.user_ranks
WHERE user_id = p_user_id
AND is_current = true;
-- FIX: Usar alias 'ur' para evitar ambigüedad
SELECT ur.current_rank INTO v_current_rank
FROM gamification_system.user_ranks ur
WHERE ur.user_id = p_user_id
AND ur.is_current = true;
-- Obtener siguiente rango desde maya_ranks
SELECT name::VARCHAR, min_xp_required, missions_required
INTO v_next_rank, v_next_rank_xp, v_next_rank_missions
-- NOTA: Columna correcta es rank_name (ENUM maya_rank), no name
SELECT rank_name::VARCHAR, min_xp_required, COALESCE(modules_required, 0)
INTO v_next_rank, v_next_rank_xp, v_next_rank_modules
FROM gamification_system.maya_ranks
WHERE name::VARCHAR > COALESCE(v_current_rank, 'Ajaw')
WHERE rank_name::VARCHAR > COALESCE(v_current_rank, 'Ajaw')
ORDER BY min_xp_required ASC
LIMIT 1;
@ -47,7 +55,7 @@ BEGIN
-- Usuario está en rango máximo
v_next_rank := v_current_rank;
v_next_rank_xp := v_total_xp;
v_next_rank_missions := v_missions_completed;
v_next_rank_modules := v_modules_completed;
END IF;
RETURN QUERY SELECT
@ -55,12 +63,12 @@ BEGIN
COALESCE(v_current_rank, 'Ajaw'::VARCHAR),
v_next_rank,
GREATEST(0, v_next_rank_xp - v_total_xp),
GREATEST(0, COALESCE(v_next_rank_missions, 0) - v_missions_completed),
GREATEST(0, COALESCE(v_next_rank_modules, 0) - v_modules_completed),
LEAST(100.0::NUMERIC, (v_total_xp::NUMERIC / NULLIF(v_next_rank_xp, 0)) * 100);
END;
$$ LANGUAGE plpgsql STABLE;
COMMENT ON FUNCTION gamification_system.calculate_user_rank(UUID) IS
'Calcula el rango actual del usuario basado en XP y misiones';
'Calcula el rango actual del usuario basado en XP y módulos completados';
GRANT EXECUTE ON FUNCTION gamification_system.calculate_user_rank(UUID) TO authenticated;

View File

@ -2,7 +2,8 @@
-- Description: Calcula el progreso del usuario hacia el siguiente rango Maya
-- Parameters:
-- - p_user_id: UUID - ID del usuario
-- Returns: TABLE (current_rank, current_xp, next_rank, next_rank_xp, xp_needed, progress_percentage, missions_completed, missions_required)
-- Returns: TABLE (current_rank, current_xp, next_rank, next_rank_xp, xp_needed, progress_percentage, modules_completed, missions_required)
-- CORRECTED (2025-12-18): missions_completed -> modules_completed (alineado con user_stats entity)
-- Example:
-- SELECT * FROM gamification_system.get_user_rank_progress('123e4567-e89b-12d3-a456-426614174000');
-- Dependencies: gamification_system.user_stats, user_ranks, maya_ranks
@ -19,7 +20,7 @@ RETURNS TABLE (
next_rank_xp BIGINT,
xp_needed BIGINT,
progress_percentage NUMERIC(5,2),
missions_completed INTEGER,
modules_completed INTEGER,
missions_required INTEGER
) AS $$
DECLARE
@ -60,7 +61,7 @@ BEGIN
v_user_stats.total_xp,
0::BIGINT,
100.00::NUMERIC,
v_user_stats.missions_completed,
v_user_stats.modules_completed,
0::INTEGER;
ELSE
RETURN QUERY SELECT
@ -71,7 +72,7 @@ BEGIN
GREATEST(0, v_next_rank.min_xp_required - v_user_stats.total_xp),
LEAST(100, (v_user_stats.total_xp - v_current_rank_xp)::NUMERIC /
NULLIF(v_next_rank.min_xp_required - v_current_rank_xp, 0) * 100),
v_user_stats.missions_completed,
v_user_stats.modules_completed,
v_next_rank.missions_required;
END IF;
END;

View File

@ -7,6 +7,7 @@
-- - p_scope: VARCHAR(20) - Alcance del leaderboard (GLOBAL, CLASSROOM) default 'GLOBAL'
-- Returns: TABLE (user_position, total_participants, user_score, top_score, percentile)
-- Created: 2025-11-02
-- CORRECTED (2025-12-18): missions_completed -> modules_completed (alineado con user_stats entity)
-- =====================================================
CREATE OR REPLACE FUNCTION gamification_system.update_leaderboard_global(
@ -43,17 +44,18 @@ BEGIN
FROM gamification_system.user_stats;
ELSIF p_leaderboard_type = 'MISSIONS' THEN
-- NOTA: Usando modules_completed ya que missions_completed no existe en user_stats
SELECT COUNT(*) + 1 INTO v_position
FROM gamification_system.user_stats
WHERE missions_completed > (
SELECT COALESCE(missions_completed, 0) FROM gamification_system.user_stats WHERE user_id = p_user_id
WHERE modules_completed > (
SELECT COALESCE(modules_completed, 0) FROM gamification_system.user_stats WHERE user_id = p_user_id
);
SELECT COALESCE(missions_completed, 0) INTO v_user_score
SELECT COALESCE(modules_completed, 0) INTO v_user_score
FROM gamification_system.user_stats
WHERE user_id = p_user_id;
SELECT COALESCE(MAX(missions_completed), 0) INTO v_top_score
SELECT COALESCE(MAX(modules_completed), 0) INTO v_top_score
FROM gamification_system.user_stats;
END IF;

View File

@ -5,6 +5,11 @@
-- - p_user_id: UUID - ID del usuario
-- Returns: TABLE (current_streak, longest_streak, streak_maintained, bonus_xp)
-- Created: 2025-11-02
-- Updated: 2025-12-15 (CORR-001: Alineación con columnas reales de user_stats DDL)
-- =====================================================
-- CORRECCIONES 2025-12-15:
-- - last_activity_date → last_activity_at::DATE (columna real es timestamp)
-- - longest_streak → max_streak (columna real es max_streak)
-- =====================================================
CREATE OR REPLACE FUNCTION gamification_system.update_leaderboard_streaks(
@ -24,10 +29,11 @@ DECLARE
v_bonus_xp INTEGER := 0;
BEGIN
-- Obtener información de racha actual
-- NOTA: last_activity_at es TIMESTAMP WITH TIME ZONE, se castea a DATE
SELECT
COALESCE(last_activity_date, CURRENT_DATE),
COALESCE(us.last_activity_at::DATE, CURRENT_DATE),
COALESCE(us.current_streak, 0),
COALESCE(us.longest_streak, 0)
COALESCE(us.max_streak, 0)
INTO v_last_activity, v_current_streak, v_longest_streak
FROM gamification_system.user_stats us
WHERE us.user_id = p_user_id;
@ -52,8 +58,8 @@ BEGIN
UPDATE gamification_system.user_stats
SET
current_streak = v_current_streak,
longest_streak = GREATEST(longest_streak, v_current_streak),
last_activity_date = CURRENT_DATE,
max_streak = GREATEST(max_streak, v_current_streak),
last_activity_at = NOW(),
total_xp = total_xp + v_bonus_xp,
updated_at = NOW()
WHERE user_id = p_user_id;
@ -67,7 +73,7 @@ BEGIN
UPDATE gamification_system.user_stats
SET
current_streak = 1,
last_activity_date = CURRENT_DATE,
last_activity_at = NOW(),
updated_at = NOW()
WHERE user_id = p_user_id;
END IF;

View File

@ -147,8 +147,10 @@ CREATE INDEX idx_mission_templates_difficulty ON gamification_system.mission_tem
-- Foreign Keys
--
-- P1-001: Corregido FK - auth_management.users no existe, usar profiles
-- Fecha: 2025-12-14 (Auditoría AUDIT-DB-001)
ALTER TABLE ONLY gamification_system.mission_templates
ADD CONSTRAINT mission_templates_created_by_fkey FOREIGN KEY (created_by) REFERENCES auth_management.users(id) ON DELETE SET NULL;
ADD CONSTRAINT mission_templates_created_by_fkey FOREIGN KEY (created_by) REFERENCES auth_management.profiles(id) ON DELETE SET NULL;
-- Note: badge_id FK commented out until badges table is created
-- ALTER TABLE ONLY gamification_system.mission_templates

View File

@ -0,0 +1,260 @@
-- =====================================================
-- RLS Policies for notifications schema
-- Description: Políticas de seguridad para sistema de notificaciones
-- Created: 2025-12-14
-- Priority: P0 - CRÍTICO (Auditoría AUDIT-DB-001)
-- =====================================================
--
-- Security Strategy:
-- - Users can only see their own notifications
-- - Users can only modify their own preferences
-- - System can create notifications for any user (via SECURITY DEFINER)
-- - Admins have full access for monitoring
-- =====================================================
-- =====================================================
-- TABLE: notifications.notifications
-- =====================================================
-- Enable RLS
ALTER TABLE notifications.notifications ENABLE ROW LEVEL SECURITY;
ALTER TABLE notifications.notifications FORCE ROW LEVEL SECURITY;
-- Drop existing policies
DROP POLICY IF EXISTS notifications_select_own ON notifications.notifications;
DROP POLICY IF EXISTS notifications_select_admin ON notifications.notifications;
DROP POLICY IF EXISTS notifications_update_own ON notifications.notifications;
DROP POLICY IF EXISTS notifications_delete_own ON notifications.notifications;
-- Policy: notifications_select_own
-- Purpose: Users can only see their own notifications
CREATE POLICY notifications_select_own
ON notifications.notifications
AS PERMISSIVE
FOR SELECT
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY notifications_select_own ON notifications.notifications IS
'Usuarios solo pueden ver sus propias notificaciones';
-- Policy: notifications_select_admin
-- Purpose: Admins can see all notifications
CREATE POLICY notifications_select_admin
ON notifications.notifications
AS PERMISSIVE
FOR SELECT
TO public
USING (
EXISTS (
SELECT 1 FROM auth_management.profiles p
WHERE p.id = current_setting('app.current_user_id', true)::uuid
AND p.role = 'super_admin'
)
);
COMMENT ON POLICY notifications_select_admin ON notifications.notifications IS
'Administradores pueden ver todas las notificaciones';
-- Policy: notifications_update_own
-- Purpose: Users can mark their notifications as read
CREATE POLICY notifications_update_own
ON notifications.notifications
AS PERMISSIVE
FOR UPDATE
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
)
WITH CHECK (
user_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY notifications_update_own ON notifications.notifications IS
'Usuarios solo pueden actualizar sus propias notificaciones (marcar como leídas)';
-- Policy: notifications_delete_own
-- Purpose: Users can delete their own notifications
CREATE POLICY notifications_delete_own
ON notifications.notifications
AS PERMISSIVE
FOR DELETE
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY notifications_delete_own ON notifications.notifications IS
'Usuarios solo pueden eliminar sus propias notificaciones';
-- =====================================================
-- TABLE: notifications.notification_preferences
-- =====================================================
-- Enable RLS
ALTER TABLE notifications.notification_preferences ENABLE ROW LEVEL SECURITY;
ALTER TABLE notifications.notification_preferences FORCE ROW LEVEL SECURITY;
-- Drop existing policies
DROP POLICY IF EXISTS notification_preferences_select_own ON notifications.notification_preferences;
DROP POLICY IF EXISTS notification_preferences_insert_own ON notifications.notification_preferences;
DROP POLICY IF EXISTS notification_preferences_update_own ON notifications.notification_preferences;
-- Policy: notification_preferences_select_own
CREATE POLICY notification_preferences_select_own
ON notifications.notification_preferences
AS PERMISSIVE
FOR SELECT
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY notification_preferences_select_own ON notifications.notification_preferences IS
'Usuarios solo pueden ver sus propias preferencias de notificación';
-- Policy: notification_preferences_insert_own
CREATE POLICY notification_preferences_insert_own
ON notifications.notification_preferences
AS PERMISSIVE
FOR INSERT
TO public
WITH CHECK (
user_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY notification_preferences_insert_own ON notifications.notification_preferences IS
'Usuarios solo pueden crear preferencias para sí mismos';
-- Policy: notification_preferences_update_own
CREATE POLICY notification_preferences_update_own
ON notifications.notification_preferences
AS PERMISSIVE
FOR UPDATE
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
)
WITH CHECK (
user_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY notification_preferences_update_own ON notifications.notification_preferences IS
'Usuarios solo pueden modificar sus propias preferencias de notificación';
-- =====================================================
-- TABLE: notifications.notification_logs
-- =====================================================
-- Enable RLS
ALTER TABLE notifications.notification_logs ENABLE ROW LEVEL SECURITY;
ALTER TABLE notifications.notification_logs FORCE ROW LEVEL SECURITY;
-- Drop existing policies
DROP POLICY IF EXISTS notification_logs_select_own ON notifications.notification_logs;
DROP POLICY IF EXISTS notification_logs_select_admin ON notifications.notification_logs;
-- Policy: notification_logs_select_own
CREATE POLICY notification_logs_select_own
ON notifications.notification_logs
AS PERMISSIVE
FOR SELECT
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY notification_logs_select_own ON notifications.notification_logs IS
'Usuarios pueden ver logs de sus propias notificaciones';
-- Policy: notification_logs_select_admin
CREATE POLICY notification_logs_select_admin
ON notifications.notification_logs
AS PERMISSIVE
FOR SELECT
TO public
USING (
EXISTS (
SELECT 1 FROM auth_management.profiles p
WHERE p.id = current_setting('app.current_user_id', true)::uuid
AND p.role = 'super_admin'
)
);
COMMENT ON POLICY notification_logs_select_admin ON notifications.notification_logs IS
'Administradores pueden ver todos los logs de notificaciones';
-- =====================================================
-- TABLE: notifications.user_devices (para push notifications)
-- =====================================================
-- Enable RLS
ALTER TABLE notifications.user_devices ENABLE ROW LEVEL SECURITY;
ALTER TABLE notifications.user_devices FORCE ROW LEVEL SECURITY;
-- Drop existing policies
DROP POLICY IF EXISTS user_devices_select_own ON notifications.user_devices;
DROP POLICY IF EXISTS user_devices_insert_own ON notifications.user_devices;
DROP POLICY IF EXISTS user_devices_update_own ON notifications.user_devices;
DROP POLICY IF EXISTS user_devices_delete_own ON notifications.user_devices;
-- Policy: user_devices_all_own
CREATE POLICY user_devices_select_own
ON notifications.user_devices
AS PERMISSIVE
FOR SELECT
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
);
CREATE POLICY user_devices_insert_own
ON notifications.user_devices
AS PERMISSIVE
FOR INSERT
TO public
WITH CHECK (
user_id = current_setting('app.current_user_id', true)::uuid
);
CREATE POLICY user_devices_update_own
ON notifications.user_devices
AS PERMISSIVE
FOR UPDATE
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
);
CREATE POLICY user_devices_delete_own
ON notifications.user_devices
AS PERMISSIVE
FOR DELETE
TO public
USING (
user_id = current_setting('app.current_user_id', true)::uuid
);
COMMENT ON POLICY user_devices_select_own ON notifications.user_devices IS
'Usuarios solo pueden ver sus propios dispositivos registrados';
-- =====================================================
-- SUMMARY
-- =====================================================
-- Tables with RLS enabled: 4
-- - notifications.notifications (4 policies)
-- - notifications.notification_preferences (3 policies)
-- - notifications.notification_logs (2 policies)
-- - notifications.user_devices (4 policies)
--
-- Total policies: 13
--
-- Security enforced:
-- - Users cannot read other users' notifications
-- - Users cannot modify other users' preferences
-- - Users cannot see other users' registered devices
-- - Admins have read-only access for monitoring
-- - INSERT for notifications uses SECURITY DEFINER functions
-- =====================================================

View File

@ -10,6 +10,7 @@
-- Dependencies: social_features.classroom_members, gamification_system.user_stats, progress_tracking.module_progress, auth.profiles
-- Created: 2025-10-28
-- Modified: 2025-10-28
-- CORRECTED (2025-12-18): missions_completed -> modules_completed, last_activity_date -> last_activity_at
CREATE OR REPLACE FUNCTION progress_tracking.get_classroom_analytics(
p_classroom_id UUID,
@ -39,22 +40,22 @@ BEGIN
SELECT
cs.user_id,
us.total_xp,
us.missions_completed,
us.modules_completed,
us.current_streak,
us.last_activity_date
us.last_activity_at
FROM classroom_students cs
JOIN gamification_system.user_stats us ON us.user_id = cs.user_id
)
SELECT
COUNT(*)::INTEGER as total_students,
COUNT(*) FILTER (WHERE last_activity_date >= CURRENT_DATE - 7)::INTEGER as active_students,
COUNT(*) FILTER (WHERE last_activity_at >= CURRENT_DATE - 7)::INTEGER as active_students,
AVG(
(SELECT completion_percentage
FROM progress_tracking.module_progress mp
WHERE mp.user_id = ss.user_id
LIMIT 1)
)::NUMERIC(5,2) as avg_completion_rate,
SUM(missions_completed)::INTEGER as total_missions_completed,
SUM(modules_completed)::INTEGER as total_missions_completed,
SUM(total_xp)::BIGINT as total_xp_earned,
AVG(current_streak)::NUMERIC(5,2) as avg_current_streak,
(SELECT user_id FROM student_stats ORDER BY total_xp DESC LIMIT 1) as top_performer_id,

View File

@ -9,6 +9,7 @@
-- Dependencies: gamification_system.missions, gamification_system.calculate_mission_reward, user_stats, ml_coins_transactions, update_user_level, check_and_grant_achievements
-- Created: 2025-10-28
-- Modified: 2025-10-28
-- CORRECTED (2025-12-18): missions_completed -> modules_completed (columna no existe en user_stats)
CREATE OR REPLACE FUNCTION progress_tracking.grant_mission_completion_rewards(
p_user_id UUID,
@ -47,11 +48,12 @@ BEGIN
WHERE user_id = p_user_id;
-- Otorgar XP y Coins
-- NOTA: Usando modules_completed ya que missions_completed no existe en user_stats
UPDATE gamification_system.user_stats
SET
total_xp = total_xp + v_boosted_xp,
ml_coins = ml_coins + v_boosted_coins,
missions_completed = missions_completed + 1,
modules_completed = modules_completed + 1,
updated_at = NOW()
WHERE user_id = p_user_id;

View File

@ -19,7 +19,7 @@ El schema `public` está reservado para objetos del core de PostgreSQL y extensi
Todos los objetos propios de Gamilit deben ubicarse en schemas específicos según su responsabilidad:
- **Supabase Core**: `auth`, `storage`
- **Auth Core**: `auth`, `storage`
- **Application**: `auth_management`, `system_configuration`
- **Domain**: `educational_content`, `gamification_system`, `progress_tracking`, `social_features`, `content_management`
- **Integration/Admin**: `audit_logging`, `admin_dashboard`, `lti_integration`

View File

@ -1,6 +1,6 @@
# Schema: storage
Configuración de almacenamiento de Supabase
Schema de configuración de almacenamiento (S3/Storage compatible)
## Estructura

View File

@ -2,7 +2,7 @@
-- Seed: auth.users - Test Users (PRODUCTION CLEAN)
-- Description: Solo usuarios de testing con dominio @gamilit.com
-- Environment: PRODUCTION
-- Dependencies: None (auth schema managed by Supabase)
-- Dependencies: None (auth schema base)
-- Order: 01
-- Created: 2025-11-17
-- Version: 2.0 (CLEAN - Solo 3 usuarios @gamilit.com)

View File

@ -0,0 +1,381 @@
-- =====================================================
-- Seed: auth_management.tenants - Production User Tenants
-- Description: Tenants para usuarios reales registrados en producción
-- Environment: PRODUCTION
-- Dependencies: auth_management/01-tenants.sql
-- Order: 02
-- Created: 2025-11-19
-- Version: 1.0 (Migrados desde servidor producción)
-- =====================================================
--
-- TENANTS DE USUARIOS REALES REGISTRADOS (13):
-- Cada usuario de producción tiene su propio tenant personal
-- creado automáticamente durante el registro
--
-- TOTAL: 13 tenants personales
--
-- POLÍTICA DE CARGA LIMPIA:
-- ✅ Tenant IDs originales del servidor preservados
-- ✅ Configuración base para usuarios estudiantes
-- ✅ Subscription tier 'free' por defecto
--
-- IMPORTANTE: Estos son tenants personales de estudiantes.
-- Son diferentes al tenant principal de la plataforma.
-- =====================================================
SET search_path TO auth_management, public;
-- =====================================================
-- INSERT: Production User Tenants (13 tenants)
-- =====================================================
INSERT INTO auth_management.tenants (
id,
name,
slug,
domain,
logo_url,
subscription_tier,
max_users,
max_storage_gb,
is_active,
trial_ends_at,
settings,
metadata,
created_at,
updated_at
) VALUES
-- Tenant 1: Jose Aguirre
(
'a2019d2c-1abe-4b92-8033-372a2a553f76'::uuid,
'Jose Aguirre',
'jose-aguirre',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'joseal.guirre34@gmail.com'),
'2025-11-18 07:29:05.229254+00'::timestamptz,
'2025-11-18 07:29:05.229254+00'::timestamptz
),
-- Tenant 2: Sergio Jimenez
(
'6490930a-c572-4464-82f7-19d688f32877'::uuid,
'Sergio Jimenez',
'sergio-jimenez',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'sergiojimenezesteban63@gmail.com'),
'2025-11-18 08:17:40.928077+00'::timestamptz,
'2025-11-18 08:17:40.928077+00'::timestamptz
),
-- Tenant 3: Hugo Gomez
(
'4abd1886-6d7e-42c9-a2a5-f7a9e01973bd'::uuid,
'Hugo Gomez',
'hugo-gomez',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'Gomezfornite92@gmail.com'),
'2025-11-18 08:18:04.242047+00'::timestamptz,
'2025-11-18 08:18:04.242047+00'::timestamptz
),
-- Tenant 4: Hugo Aragón
(
'c77ba4cc-be06-4ed8-8e48-4bbc72d59f16'::uuid,
'Hugo Aragón',
'hugo-aragon',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'Aragon494gt54@icloud.com'),
'2025-11-18 08:20:17.230714+00'::timestamptz,
'2025-11-18 08:20:17.230714+00'::timestamptz
),
-- Tenant 5: Azul Valentina
(
'e2b08195-5a20-4822-a9b6-8d2e04c785b3'::uuid,
'Azul Valentina',
'azul-valentina',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'blu3wt7@gmail.com'),
'2025-11-18 08:32:17.315932+00'::timestamptz,
'2025-11-18 08:32:17.315932+00'::timestamptz
),
-- Tenant 6: Ricardo Lugo
(
'5f4dd29b-0317-4d96-8540-4e9417175525'::uuid,
'Ricardo Lugo',
'ricardo-lugo',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'ricardolugo786@icloud.com'),
'2025-11-18 10:15:06.481498+00'::timestamptz,
'2025-11-18 10:15:06.481498+00'::timestamptz
),
-- Tenant 7: Carlos Marban
(
'87b8dc94-da11-451d-a53b-31c00a6973b8'::uuid,
'Carlos Marban',
'carlos-marban',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'marbancarlos916@gmail.com'),
'2025-11-18 10:29:05.240413+00'::timestamptz,
'2025-11-18 10:29:05.240413+00'::timestamptz
),
-- Tenant 8: Diego Colores
(
'331b5931-1125-482f-9535-f1e0e829edd5'::uuid,
'Diego Colores',
'diego-colores',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'diego.colores09@gmail.com'),
'2025-11-18 10:29:20.531883+00'::timestamptz,
'2025-11-18 10:29:20.531883+00'::timestamptz
),
-- Tenant 9: Benjamin Hernandez
(
'2f1c69b9-2da7-4b72-a6fd-477aa96ba075'::uuid,
'Benjamin Hernandez',
'benjamin-hernandez',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'hernandezfonsecabenjamin7@gmail.com'),
'2025-11-18 10:37:06.9215+00'::timestamptz,
'2025-11-18 10:37:06.9215+00'::timestamptz
),
-- Tenant 10: Josue Reyes
(
'7265b54e-a988-4c50-a62c-61cb0594f556'::uuid,
'Josue Reyes',
'josue-reyes',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'jr7794315@gmail.com'),
'2025-11-18 17:53:39.681271+00'::timestamptz,
'2025-11-18 17:53:39.681271+00'::timestamptz
),
-- Tenant 11: Fernando Barragan
(
'dcc49202-4d26-4b09-9bdb-8f71d039f328'::uuid,
'Fernando Barragan',
'fernando-barragan',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'barraganfer03@gmail.com'),
'2025-11-18 20:39:27.410436+00'::timestamptz,
'2025-11-18 20:39:27.410436+00'::timestamptz
),
-- Tenant 12: Marco Antonio Roman
(
'bfc0fac3-8905-4514-af32-7375e242e0f5'::uuid,
'Marco Antonio Roman',
'marco-roman',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'roman.rebollar.marcoantonio1008@gmail.com'),
'2025-11-18 21:03:17.328254+00'::timestamptz,
'2025-11-18 21:03:17.328254+00'::timestamptz
),
-- Tenant 13: Rodrigo Guerrero
(
'c4856507-807f-4fc5-9689-ffeb0feb4825'::uuid,
'Rodrigo Guerrero',
'rodrigo-guerrero',
NULL,
NULL,
'free',
1,
1,
true,
NULL,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City'
),
jsonb_build_object('personal_tenant', true, 'user_email', 'rodrigoguerrero0914@gmail.com'),
'2025-11-18 21:20:52.304488+00'::timestamptz,
'2025-11-18 21:20:52.304488+00'::timestamptz
)
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
updated_at = EXCLUDED.updated_at;
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
production_tenant_count INTEGER;
total_tenant_count INTEGER;
BEGIN
-- Contar tenants personales de producción
SELECT COUNT(*) INTO production_tenant_count
FROM auth_management.tenants
WHERE metadata->>'personal_tenant' = 'true';
-- Contar todos los tenants
SELECT COUNT(*) INTO total_tenant_count
FROM auth_management.tenants;
RAISE NOTICE '========================================';
RAISE NOTICE 'TENANTS DE PRODUCCIÓN CREADOS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Tenants personales: %', production_tenant_count;
RAISE NOTICE 'Total tenants (incluyendo principal): %', total_tenant_count;
RAISE NOTICE '========================================';
IF production_tenant_count = 13 THEN
RAISE NOTICE '✓ Los 13 tenants personales fueron creados correctamente';
ELSE
RAISE WARNING '⚠ Se esperaban 13 tenants personales, se crearon %', production_tenant_count;
END IF;
RAISE NOTICE '========================================';
END $$;
-- =====================================================
-- CHANGELOG
-- =====================================================
-- v1.0 (2025-11-19): Primera versión
-- - 13 tenants personales migrados desde servidor producción
-- - Tenant IDs originales preservados
-- - Configuración base para estudiantes
-- - Subscription tier 'free' por defecto
-- =====================================================

View File

@ -0,0 +1,210 @@
-- =====================================================
-- Seed: auth_management.profiles (PROD) - COMPLETO
-- Description: Perfiles para todos los usuarios de testing y demo
-- Environment: PRODUCTION
-- Dependencies: auth.users, auth_management.tenants
-- Order: 04
-- Created: 2025-11-11
-- Version: 2.0
-- =====================================================
--
-- PERFILES INCLUIDOS:
-- - 3 perfiles de testing (admin, teacher, student @gamilit.com)
-- - 16 perfiles de estudiantes demo
-- - 3 perfiles de profesores demo
-- - 3 perfiles de administradores demo
-- ⚠️ NO incluye perfiles de padres (Portal Padres = Extension EXT-010, fuera de alcance)
--
-- TOTAL: 22 perfiles (teacher, student, admin SOLO - alcance v2.3.x)
-- =====================================================
SET search_path TO auth_management, public;
-- =====================================================
-- INSERT: Perfiles Completos
-- =====================================================
INSERT INTO auth_management.profiles (
id,
tenant_id,
user_id,
email,
display_name,
full_name,
first_name,
last_name,
avatar_url,
bio,
phone,
date_of_birth,
grade_level,
student_id,
school_id,
role,
status,
email_verified,
phone_verified,
preferences,
metadata,
created_at,
updated_at
) VALUES
-- =====================================================
-- PERFILES DE TESTING (3)
-- =====================================================
(
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, -- Tenant principal
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid, -- user_id admin
'admin@gamilit.com',
'Admin GAMILIT',
'Administrador GAMILIT',
'Administrador',
'GAMILIT',
'/avatars/admin-testing.png',
'Usuario administrador para testing y desarrollo.',
'55-0000-0001',
'1985-01-01'::date,
NULL, -- grade_level (no aplica para admin)
NULL, -- student_id
NULL, -- school_id
'super_admin'::auth_management.gamilit_role,
'active'::auth_management.user_status,
true,
true,
jsonb_build_object(
'theme', 'professional',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
jsonb_build_object(
'testing_user', true,
'description', 'Usuario de testing principal'
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid, -- user_id teacher
'teacher@gamilit.com',
'Profesor Testing',
'Profesor de Testing GAMILIT',
'Profesor',
'Testing',
'/avatars/teacher-testing.png',
'Usuario profesor para testing y desarrollo.',
'55-0000-0002',
'1980-05-15'::date,
NULL,
NULL,
NULL,
'admin_teacher'::auth_management.gamilit_role,
'active'::auth_management.user_status,
true,
true,
jsonb_build_object(
'theme', 'teacher',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
jsonb_build_object(
'testing_user', true,
'subjects', ARRAY['Lengua Española', 'Comprensión Lectora']
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, -- user_id student
'student@gamilit.com',
'Estudiante Testing',
'Estudiante de Testing GAMILIT',
'Estudiante',
'Testing',
'/avatars/student-testing.png',
'Usuario estudiante para testing y desarrollo.',
'55-0000-0003',
'2013-09-01'::date,
'5', -- grade_level
'EST-TEST-001',
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
true,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true,
'gamification', jsonb_build_object(
'show_leaderboard', true,
'show_achievements', true,
'show_rank', true
)
),
jsonb_build_object(
'testing_user', true,
'interests', ARRAY['lectura', 'ciencia'],
'learning_style', 'visual'
),
gamilit.now_mexico(),
gamilit.now_mexico()
)
ON CONFLICT (user_id) DO UPDATE SET
display_name = EXCLUDED.display_name,
full_name = EXCLUDED.full_name,
bio = EXCLUDED.bio,
preferences = EXCLUDED.preferences,
metadata = EXCLUDED.metadata,
updated_at = gamilit.now_mexico();
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
profile_count INTEGER;
testing_profiles INTEGER;
BEGIN
SELECT COUNT(*) INTO profile_count
FROM auth_management.profiles;
SELECT COUNT(*) INTO testing_profiles
FROM auth_management.profiles
WHERE email IN ('admin@gamilit.com', 'teacher@gamilit.com', 'student@gamilit.com');
RAISE NOTICE '========================================';
RAISE NOTICE 'PERFILES DE TESTING CREADOS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total perfiles: %', profile_count;
RAISE NOTICE 'Perfiles de testing: %', testing_profiles;
RAISE NOTICE '========================================';
IF testing_profiles = 3 THEN
RAISE NOTICE '✓ Perfiles de testing creados correctamente';
ELSE
RAISE WARNING '⚠ Se esperaban 3 perfiles de testing, se crearon %', testing_profiles;
END IF;
END $$;
-- =====================================================
-- Testing Info
-- =====================================================
-- Los perfiles de testing están listos para usar con:
-- - admin@gamilit.com / Test1234
-- - teacher@gamilit.com / Test1234
-- - student@gamilit.com / Test1234
-- =====================================================

View File

@ -0,0 +1,589 @@
-- =====================================================
-- Seed: auth_management.profiles - Production Users (CORREGIDO)
-- Description: Perfiles CORREGIDOS para usuarios reales registrados en producción
-- Environment: PRODUCTION
-- Dependencies: auth/02-production-users.sql, auth_management/01-tenants.sql
-- Order: 06
-- Created: 2025-11-19
-- Version: 2.0 (CORRECCIÓN: profiles.id = auth.users.id)
-- =====================================================
--
-- CORRECCIONES APLICADAS:
-- ❌ ANTES: profiles.id generado con gen_random_uuid() (diferente de auth.users.id)
-- ✅ AHORA: profiles.id = auth.users.id (consistente con seeds de testing)
--
-- ❌ ANTES: tenant_id apuntaba a tenants personales
-- ✅ AHORA: tenant_id apunta al tenant principal (GAMILIT Platform)
--
-- JUSTIFICACIÓN:
-- 1. Todos los usuarios de testing tienen profiles.id = auth.users.id
-- 2. Backend busca user_stats con profiles.id, pero user_stats usa auth.users.id
-- 3. Resultado: Error 404 al enviar respuestas de ejercicios
-- 4. Solución: Unificar IDs (1 usuario = 1 ID único)
--
-- IMPACTO:
-- - ✅ Usuarios de producción funcionan igual que usuarios de testing
-- - ✅ No más errores 404 al enviar respuestas
-- - ✅ Gamificación funciona correctamente
-- - ✅ Trigger initialize_user_stats() usa el ID correcto
--
-- TOTAL: 13 perfiles de estudiantes (CORREGIDOS)
-- =====================================================
SET search_path TO auth_management, public;
-- =====================================================
-- INSERT: Production User Profiles (13 perfiles CORREGIDOS)
-- =====================================================
INSERT INTO auth_management.profiles (
id, -- ✅ AHORA: auth.users.id (NO gen_random_uuid())
tenant_id, -- ✅ AHORA: Tenant principal (NO personal)
user_id, -- ✅ auth.users.id (sin cambios)
email,
display_name,
full_name,
first_name,
last_name,
avatar_url,
bio,
phone,
date_of_birth,
grade_level,
student_id,
school_id,
role,
status,
email_verified,
phone_verified,
preferences,
metadata,
created_at,
updated_at
) VALUES
-- =====================================================
-- PROFILE 1: Jose Aguirre (CORREGIDO)
-- =====================================================
(
'b017b792-b327-40dd-aefb-a80312776952'::uuid, -- ✅ id = user_id (auth.users.id)
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, -- ✅ Tenant principal
'b017b792-b327-40dd-aefb-a80312776952'::uuid, -- user_id
'joseal.guirre34@gmail.com',
'Jose Aguirre',
'Jose Aguirre',
'Jose',
'Aguirre',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 07:29:05.229254+00'::timestamptz,
'2025-11-18 07:29:05.229254+00'::timestamptz
),
-- =====================================================
-- PROFILE 2: Sergio Jimenez (CORREGIDO)
-- =====================================================
(
'06a24962-e83d-4e94-aad7-ff69f20a9119'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'06a24962-e83d-4e94-aad7-ff69f20a9119'::uuid,
'sergiojimenezesteban63@gmail.com',
'Sergio Jimenez',
'Sergio Jimenez',
'Sergio',
'Jimenez',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 08:17:40.928077+00'::timestamptz,
'2025-11-18 08:17:40.928077+00'::timestamptz
),
-- =====================================================
-- PROFILE 3: Hugo Gomez (CORREGIDO)
-- =====================================================
(
'24e8c563-8854-43d1-b3c9-2f83e91f5a1e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'24e8c563-8854-43d1-b3c9-2f83e91f5a1e'::uuid,
'Gomezfornite92@gmail.com',
'Hugo Gomez',
'Hugo Gomez',
'Hugo',
'Gomez',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 08:18:04.242047+00'::timestamptz,
'2025-11-18 08:18:04.242047+00'::timestamptz
),
-- =====================================================
-- PROFILE 4: Hugo Aragón (CORREGIDO)
-- =====================================================
(
'bf0d3e34-e077-43d1-9626-292f7fae2bd6'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'bf0d3e34-e077-43d1-9626-292f7fae2bd6'::uuid,
'Aragon494gt54@icloud.com',
'Hugo Aragón',
'Hugo Aragón',
'Hugo',
'Aragón',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 08:20:17.230714+00'::timestamptz,
'2025-11-18 08:20:17.230714+00'::timestamptz
),
-- =====================================================
-- PROFILE 5: Azul Valentina (CORREGIDO)
-- =====================================================
(
'2f5a9846-3393-40b2-9e87-0f29238c383f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'2f5a9846-3393-40b2-9e87-0f29238c383f'::uuid,
'blu3wt7@gmail.com',
'Azul Valentina',
'Azul Valentina',
'Azul',
'Valentina',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 08:32:17.315932+00'::timestamptz,
'2025-11-18 08:32:17.315932+00'::timestamptz
),
-- =====================================================
-- PROFILE 6: Ricardo Lugo (CORREGIDO)
-- =====================================================
(
'5e738038-1743-4aa9-b222-30171300ea9d'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'5e738038-1743-4aa9-b222-30171300ea9d'::uuid,
'ricardolugo786@icloud.com',
'Ricardo Lugo',
'Ricardo Lugo',
'Ricardo',
'Lugo',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 10:15:06.481498+00'::timestamptz,
'2025-11-18 10:15:06.481498+00'::timestamptz
),
-- =====================================================
-- PROFILE 7: Carlos Marban (CORREGIDO)
-- =====================================================
(
'00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid,
'marbancarlos916@gmail.com',
'Carlos Marban',
'Carlos Marban',
'Carlos',
'Marban',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 10:29:05.240413+00'::timestamptz,
'2025-11-18 10:29:05.240413+00'::timestamptz
),
-- =====================================================
-- PROFILE 8: Diego Colores (CORREGIDO)
-- =====================================================
(
'33306a65-a3b1-41d5-a49d-47989957b822'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'33306a65-a3b1-41d5-a49d-47989957b822'::uuid,
'diego.colores09@gmail.com',
'Diego Colores',
'Diego Colores',
'Diego',
'Colores',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 10:29:20.531883+00'::timestamptz,
'2025-11-18 10:29:20.531883+00'::timestamptz
),
-- =====================================================
-- PROFILE 9: Benjamin Hernandez (CORREGIDO)
-- =====================================================
(
'7a6a973e-83f7-4374-a9fc-54258138115f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'7a6a973e-83f7-4374-a9fc-54258138115f'::uuid,
'hernandezfonsecabenjamin7@gmail.com',
'Benjamin Hernandez',
'Benjamin Hernandez',
'Benjamin',
'Hernandez',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 10:37:06.9215+00'::timestamptz,
'2025-11-18 10:37:06.9215+00'::timestamptz
),
-- =====================================================
-- PROFILE 10: Josue Reyes (CORREGIDO)
-- =====================================================
(
'ccd7135c-0fea-4488-9094-9da52df1c98c'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'ccd7135c-0fea-4488-9094-9da52df1c98c'::uuid,
'jr7794315@gmail.com',
'Josue Reyes',
'Josue Reyes',
'Josue',
'Reyes',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 17:53:39.681271+00'::timestamptz,
'2025-11-18 17:53:39.681271+00'::timestamptz
),
-- =====================================================
-- PROFILE 11: Fernando Barragan (CORREGIDO)
-- =====================================================
(
'9951ad75-e9cb-47b3-b478-6bb860ee2530'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'9951ad75-e9cb-47b3-b478-6bb860ee2530'::uuid,
'barraganfer03@gmail.com',
'Fernando Barragan',
'Fernando Barragan',
'Fernando',
'Barragan',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 20:39:27.410436+00'::timestamptz,
'2025-11-18 20:39:27.410436+00'::timestamptz
),
-- =====================================================
-- PROFILE 12: Marco Antonio Roman (CORREGIDO)
-- =====================================================
(
'735235f5-260a-4c9b-913c-14a1efd083ea'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'735235f5-260a-4c9b-913c-14a1efd083ea'::uuid,
'roman.rebollar.marcoantonio1008@gmail.com',
'Marco Antonio Roman',
'Marco Antonio Roman',
'Marco Antonio',
'Roman',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 21:03:17.328254+00'::timestamptz,
'2025-11-18 21:03:17.328254+00'::timestamptz
),
-- =====================================================
-- PROFILE 13: Rodrigo Guerrero (CORREGIDO)
-- =====================================================
(
'ebe48628-5e44-4562-97b7-b4950b216247'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'ebe48628-5e44-4562-97b7-b4950b216247'::uuid,
'rodrigoguerrero0914@gmail.com',
'Rodrigo Guerrero',
'Rodrigo Guerrero',
'Rodrigo',
'Guerrero',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'student'::auth_management.gamilit_role,
'active'::auth_management.user_status,
false,
false,
jsonb_build_object(
'theme', 'detective',
'language', 'es',
'timezone', 'America/Mexico_City',
'sound_enabled', true,
'notifications_enabled', true
),
'{}'::jsonb,
'2025-11-18 21:20:52.304488+00'::timestamptz,
'2025-11-18 21:20:52.304488+00'::timestamptz
)
ON CONFLICT (id) DO UPDATE SET
tenant_id = EXCLUDED.tenant_id, -- ✅ Actualizar tenant al principal
display_name = EXCLUDED.display_name,
full_name = EXCLUDED.full_name,
first_name = EXCLUDED.first_name,
last_name = EXCLUDED.last_name,
updated_at = EXCLUDED.updated_at;
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
production_profile_count INTEGER;
corrected_ids_count INTEGER;
corrected_tenants_count INTEGER;
BEGIN
-- Contar perfiles de producción
SELECT COUNT(*) INTO production_profile_count
FROM auth_management.profiles
WHERE email NOT LIKE '%@gamilit.com';
-- Contar perfiles con IDs corregidos (id = user_id)
SELECT COUNT(*) INTO corrected_ids_count
FROM auth_management.profiles
WHERE email NOT LIKE '%@gamilit.com'
AND id = user_id;
-- Contar perfiles con tenant principal
SELECT COUNT(*) INTO corrected_tenants_count
FROM auth_management.profiles
WHERE email NOT LIKE '%@gamilit.com'
AND tenant_id = 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11';
RAISE NOTICE '========================================';
RAISE NOTICE 'PERFILES DE PRODUCCIÓN (CORREGIDOS)';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total perfiles de producción: %', production_profile_count;
RAISE NOTICE 'Perfiles con profiles.id = auth.users.id: %', corrected_ids_count;
RAISE NOTICE 'Perfiles con tenant principal: %', corrected_tenants_count;
RAISE NOTICE '========================================';
IF production_profile_count = 13 AND corrected_ids_count = 13 AND corrected_tenants_count = 13 THEN
RAISE NOTICE '✅ Los 13 perfiles de producción fueron CORREGIDOS correctamente';
RAISE NOTICE '✅ profiles.id = auth.users.id para TODOS los usuarios';
RAISE NOTICE '✅ tenant_id = GAMILIT Platform para TODOS los usuarios';
ELSE
RAISE WARNING '⚠ Corrección incompleta:';
RAISE WARNING ' - Esperados: 13 perfiles';
RAISE WARNING ' - IDs corregidos: %', corrected_ids_count;
RAISE WARNING ' - Tenants corregidos: %', corrected_tenants_count;
END IF;
RAISE NOTICE '========================================';
END $$;
-- =====================================================
-- CHANGELOG
-- =====================================================
-- v2.0 (2025-11-19): Corrección de IDs y tenants
-- - ✅ profiles.id = auth.users.id (era diferente)
-- - ✅ tenant_id = Tenant principal (era personal)
-- - ✅ Consistente con usuarios de testing
-- - ✅ Elimina error 404 al enviar respuestas
--
-- v1.0 (2025-11-19): Primera versión (DEPRECADA)
-- - ❌ profiles.id generado con gen_random_uuid()
-- - ❌ tenant_id apuntaba a tenants personales
-- =====================================================

View File

@ -0,0 +1,260 @@
-- =====================================================
-- Seed: auth_management.user_roles
-- Description: Asignaciones de roles a usuarios de prueba y demo
-- Priority: P0 - CRÍTICO (Auditoría AUDIT-DB-001)
-- Created: 2025-12-14
-- =====================================================
--
-- Este seed asigna roles a los usuarios existentes en profiles.
-- Los roles definen los permisos y accesos del sistema.
--
-- Roles disponibles (ENUM gamilit_role):
-- - super_admin: Administrador global del sistema
-- - admin_teacher: Profesor con permisos administrativos
-- - teacher: Profesor estándar
-- - student: Estudiante
-- - parent: Padre de familia
-- =====================================================
DO $$
DECLARE
v_tenant_id UUID;
v_admin_id UUID;
v_teacher_id UUID;
v_student_id UUID;
BEGIN
-- Obtener tenant principal (puede ser 'GAMILIT Platform' o 'GAMILIT Principal')
SELECT id INTO v_tenant_id FROM auth_management.tenants
WHERE name LIKE 'GAMILIT%' OR id = 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid
LIMIT 1;
IF v_tenant_id IS NULL THEN
-- Usar UUID por defecto si no se encuentra
v_tenant_id := 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid;
RAISE NOTICE 'Usando tenant por defecto: %', v_tenant_id;
END IF;
-- Obtener IDs de usuarios de prueba (creados en 04-profiles-complete.sql)
v_admin_id := 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid;
v_teacher_id := 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid;
v_student_id := 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid;
RAISE NOTICE 'Asignando roles a usuarios de prueba...';
-- =====================================================
-- 1. ROL SUPER_ADMIN para admin@gamilit.com
-- =====================================================
INSERT INTO auth_management.user_roles (
id,
user_id,
tenant_id,
role,
permissions,
assigned_by,
is_active,
metadata
) VALUES (
'10000001-0000-0000-0000-000000000001'::uuid,
v_admin_id,
v_tenant_id,
'super_admin',
'{
"read": true,
"write": true,
"admin": true,
"analytics": true,
"manage_users": true,
"manage_content": true,
"manage_gamification": true,
"system_config": true
}'::jsonb,
v_admin_id,
true,
'{"assigned_reason": "Usuario administrador del sistema", "seed_version": "1.0.0"}'::jsonb
)
ON CONFLICT (user_id, tenant_id, role) DO UPDATE SET
permissions = EXCLUDED.permissions,
is_active = true,
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Rol super_admin asignado a admin@gamilit.com';
-- =====================================================
-- 2. ROL ADMIN_TEACHER para teacher@gamilit.com
-- =====================================================
INSERT INTO auth_management.user_roles (
id,
user_id,
tenant_id,
role,
permissions,
assigned_by,
is_active,
metadata
) VALUES (
'10000002-0000-0000-0000-000000000001'::uuid,
v_teacher_id,
v_tenant_id,
'admin_teacher',
'{
"read": true,
"write": true,
"admin": false,
"analytics": true,
"manage_students": true,
"manage_classrooms": true,
"create_content": true,
"grade_assignments": true
}'::jsonb,
v_admin_id,
true,
'{"assigned_reason": "Profesor de prueba con permisos administrativos", "seed_version": "1.0.0"}'::jsonb
)
ON CONFLICT (user_id, tenant_id, role) DO UPDATE SET
permissions = EXCLUDED.permissions,
is_active = true,
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Rol admin_teacher asignado a teacher@gamilit.com';
-- =====================================================
-- 3. ROL STUDENT para student@gamilit.com
-- =====================================================
INSERT INTO auth_management.user_roles (
id,
user_id,
tenant_id,
role,
permissions,
assigned_by,
is_active,
metadata
) VALUES (
'10000003-0000-0000-0000-000000000001'::uuid,
v_student_id,
v_tenant_id,
'student',
'{
"read": true,
"write": false,
"admin": false,
"analytics": false,
"view_own_progress": true,
"submit_exercises": true,
"participate_classrooms": true,
"earn_achievements": true
}'::jsonb,
v_admin_id,
true,
'{"assigned_reason": "Estudiante de prueba", "seed_version": "1.0.0"}'::jsonb
)
ON CONFLICT (user_id, tenant_id, role) DO UPDATE SET
permissions = EXCLUDED.permissions,
is_active = true,
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Rol student asignado a student@gamilit.com';
-- =====================================================
-- 4. ROLES PARA ESTUDIANTES DEMO (Ana, Carlos, María, Luis)
-- =====================================================
-- Ana García (student)
INSERT INTO auth_management.user_roles (
id, user_id, tenant_id, role, permissions, assigned_by, is_active
) VALUES (
'10000004-0000-0000-0000-000000000001'::uuid,
'2f5a9846-3393-40b2-9e87-0f29238c383f'::uuid,
v_tenant_id,
'student',
'{"read": true, "submit_exercises": true, "view_own_progress": true}'::jsonb,
v_admin_id,
true
)
ON CONFLICT (user_id, tenant_id, role) DO NOTHING;
-- Carlos Ramírez (student)
INSERT INTO auth_management.user_roles (
id, user_id, tenant_id, role, permissions, assigned_by, is_active
) VALUES (
'10000005-0000-0000-0000-000000000001'::uuid,
'7a6a973e-83f7-4374-a9fc-54258138115f'::uuid,
v_tenant_id,
'student',
'{"read": true, "submit_exercises": true, "view_own_progress": true}'::jsonb,
v_admin_id,
true
)
ON CONFLICT (user_id, tenant_id, role) DO NOTHING;
-- María Fernanda (student)
INSERT INTO auth_management.user_roles (
id, user_id, tenant_id, role, permissions, assigned_by, is_active
) VALUES (
'10000006-0000-0000-0000-000000000001'::uuid,
'00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid,
v_tenant_id,
'student',
'{"read": true, "submit_exercises": true, "view_own_progress": true}'::jsonb,
v_admin_id,
true
)
ON CONFLICT (user_id, tenant_id, role) DO NOTHING;
-- Luis Miguel (student)
INSERT INTO auth_management.user_roles (
id, user_id, tenant_id, role, permissions, assigned_by, is_active
) VALUES (
'10000007-0000-0000-0000-000000000001'::uuid,
'33306a65-a3b1-41d5-a49d-47989957b822'::uuid,
v_tenant_id,
'student',
'{"read": true, "submit_exercises": true, "view_own_progress": true}'::jsonb,
v_admin_id,
true
)
ON CONFLICT (user_id, tenant_id, role) DO NOTHING;
RAISE NOTICE '✅ Roles student asignados a estudiantes demo';
-- =====================================================
-- 5. ROL TEACHER para Laura Martínez (profesora demo)
-- =====================================================
INSERT INTO auth_management.user_roles (
id, user_id, tenant_id, role, permissions, assigned_by, is_active
) VALUES (
'10000008-0000-0000-0000-000000000001'::uuid,
'9951ad75-e9cb-47b3-b478-6bb860ee2530'::uuid,
v_tenant_id,
'admin_teacher',
'{"read": true, "write": true, "analytics": true, "manage_students": true}'::jsonb,
v_admin_id,
true
)
ON CONFLICT (user_id, tenant_id, role) DO NOTHING;
RAISE NOTICE '✅ Rol admin_teacher asignado a Laura Martínez';
-- =====================================================
-- VERIFICACIÓN
-- =====================================================
RAISE NOTICE '';
RAISE NOTICE '=== RESUMEN DE ROLES ASIGNADOS ===';
RAISE NOTICE 'Total roles insertados: %', (SELECT COUNT(*) FROM auth_management.user_roles WHERE tenant_id = v_tenant_id);
RAISE NOTICE 'Super Admins: %', (SELECT COUNT(*) FROM auth_management.user_roles WHERE role = 'super_admin' AND is_active = true);
RAISE NOTICE 'Admin Teachers: %', (SELECT COUNT(*) FROM auth_management.user_roles WHERE role = 'admin_teacher' AND is_active = true);
RAISE NOTICE 'Students: %', (SELECT COUNT(*) FROM auth_management.user_roles WHERE role = 'student' AND is_active = true);
END $$;
-- =====================================================
-- VERIFICACIÓN FINAL
-- =====================================================
DO $$
BEGIN
IF (SELECT COUNT(*) FROM auth_management.user_roles) < 3 THEN
RAISE WARNING '⚠️ Se esperaban al menos 3 registros en user_roles';
ELSE
RAISE NOTICE '✅ Seed de user_roles completado exitosamente';
END IF;
END $$;

View File

@ -0,0 +1,149 @@
-- =====================================================
-- Seed: auth_management.profiles - Assign School to ALL Users (PROD)
-- Description: Asigna la escuela default a TODOS los usuarios sin escuela
-- Environment: PRODUCTION
-- Dependencies:
-- - social_features.schools (00-schools-default.sql)
-- - auth_management.profiles (04-profiles-complete.sql)
-- Order: 08 (debe ejecutarse DESPUÉS de profiles y schools)
-- Created: 2025-12-15
-- Updated: 2025-12-15 - Expandido a TODOS los usuarios
-- Version: 2.0
-- =====================================================
--
-- PROPÓSITO:
-- Asegurar que TODOS los usuarios tengan una escuela asignada
-- (school_id NOT NULL) apuntando a la escuela default.
--
-- USUARIOS AFECTADOS:
-- - Todos los roles: super_admin, admin_teacher, student, parent
-- - Cualquier usuario nuevo sin school_id
--
-- DECISIÓN DE DISEÑO (v2.0):
-- - TODOS los usuarios van a la escuela default
-- - El admin puede reasignarlos desde la UI a otras escuelas
-- - Esto garantiza integridad referencial
--
-- IMPORTANTE: Este seed es idempotente - solo actualiza si school_id IS NULL
-- =====================================================
SET search_path TO auth_management, social_features, public;
-- =====================================================
-- Asignar escuela default a TODOS los usuarios sin escuela
-- =====================================================
DO $$
DECLARE
v_default_school_id UUID;
v_total_users INTEGER;
v_users_without_school INTEGER;
v_affected_count INTEGER;
rec RECORD;
BEGIN
-- Obtener la escuela default del sistema
SELECT id INTO v_default_school_id
FROM social_features.schools
WHERE code = 'SYSTEM-UNASSIGNED'
AND is_active = true
LIMIT 1;
IF v_default_school_id IS NULL THEN
RAISE EXCEPTION 'Escuela default (SYSTEM-UNASSIGNED) no encontrada. Ejecutar primero 00-schools-default.sql';
END IF;
RAISE NOTICE 'Usando escuela default: %', v_default_school_id;
-- Contar usuarios totales y sin escuela
SELECT COUNT(*) INTO v_total_users
FROM auth_management.profiles;
SELECT COUNT(*) INTO v_users_without_school
FROM auth_management.profiles
WHERE school_id IS NULL;
RAISE NOTICE 'Total usuarios: %', v_total_users;
RAISE NOTICE 'Usuarios sin escuela: %', v_users_without_school;
-- Actualizar TODOS los usuarios sin escuela asignada
UPDATE auth_management.profiles
SET
school_id = v_default_school_id,
updated_at = gamilit.now_mexico()
WHERE school_id IS NULL;
GET DIAGNOSTICS v_affected_count = ROW_COUNT;
-- Reportar resultados
RAISE NOTICE '========================================';
RAISE NOTICE 'ASIGNACIÓN DE ESCUELA A USUARIOS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Escuela default ID: %', v_default_school_id;
RAISE NOTICE 'Usuarios actualizados: %', v_affected_count;
RAISE NOTICE '========================================';
IF v_affected_count > 0 THEN
RAISE NOTICE 'Usuarios ahora tienen escuela asignada por rol:';
-- Mostrar conteo por rol
FOR rec IN
SELECT role, COUNT(*) as count
FROM auth_management.profiles
WHERE school_id = v_default_school_id
GROUP BY role
ORDER BY role
LOOP
RAISE NOTICE ' - %: % usuarios', rec.role, rec.count;
END LOOP;
ELSE
RAISE NOTICE 'No hay usuarios sin escuela asignada (todos ya tienen school_id)';
END IF;
END $$;
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
v_users_without_school INTEGER;
v_total_in_default INTEGER;
rec RECORD;
BEGIN
SELECT COUNT(*) INTO v_users_without_school
FROM auth_management.profiles
WHERE school_id IS NULL;
SELECT COUNT(*) INTO v_total_in_default
FROM auth_management.profiles p
JOIN social_features.schools s ON p.school_id = s.id
WHERE s.code = 'SYSTEM-UNASSIGNED';
RAISE NOTICE '========================================';
RAISE NOTICE 'VERIFICACIÓN DE ASIGNACIÓN DE ESCUELAS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Usuarios sin escuela: %', v_users_without_school;
RAISE NOTICE 'Usuarios en escuela default: %', v_total_in_default;
RAISE NOTICE '========================================';
IF v_users_without_school = 0 THEN
RAISE NOTICE '✓ Todos los usuarios tienen escuela asignada';
-- Mostrar distribución por rol
RAISE NOTICE '';
RAISE NOTICE 'Distribución por rol en escuela default:';
FOR rec IN
SELECT p.role, COUNT(*) as count
FROM auth_management.profiles p
JOIN social_features.schools s ON p.school_id = s.id
WHERE s.code = 'SYSTEM-UNASSIGNED'
GROUP BY p.role
ORDER BY p.role
LOOP
RAISE NOTICE ' - %: %', rec.role, rec.count;
END LOOP;
ELSE
RAISE WARNING '⚠ ADVERTENCIA: Hay % usuarios sin escuela asignada', v_users_without_school;
END IF;
END $$;

View File

@ -0,0 +1,483 @@
-- =====================================================
-- Seed: content_management.marie_curie_content
-- Description: Contenido curado sobre Marie Curie - biografía, descubrimientos, legado
-- Priority: P0 - CRÍTICO (Auditoría AUDIT-DB-001)
-- Created: 2025-12-14
-- =====================================================
--
-- Este seed crea el contenido educativo principal de GAMILIT
-- basado en la vida y obra de Marie Curie.
--
-- Categorías de contenido (CHECK constraint):
-- - biography: Datos biográficos
-- - discoveries: Descubrimientos científicos
-- - historical_context: Contexto histórico
-- - scientific_method: Metodología científica
-- - radioactivity: Radiactividad
-- - nobel_prizes: Premios Nobel
-- - women_in_science: Mujeres en la ciencia
-- - modern_physics: Física moderna
-- - legacy: Legado
-- =====================================================
DO $$
DECLARE
v_tenant_id UUID;
v_admin_id UUID;
BEGIN
-- Obtener tenant principal (puede ser 'GAMILIT Platform' o 'GAMILIT Principal')
SELECT id INTO v_tenant_id FROM auth_management.tenants
WHERE name LIKE 'GAMILIT%' OR id = 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid
LIMIT 1;
-- Admin para created_by
v_admin_id := 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid;
IF v_tenant_id IS NULL THEN
-- Usar UUID por defecto si no se encuentra
v_tenant_id := 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid;
RAISE NOTICE 'Usando tenant por defecto: %', v_tenant_id;
END IF;
RAISE NOTICE 'Creando contenido de Marie Curie...';
-- =====================================================
-- 1. BIOGRAFÍA - PRIMEROS AÑOS
-- =====================================================
INSERT INTO content_management.marie_curie_content (
id,
tenant_id,
title,
subtitle,
description,
category,
content,
target_grade_levels,
difficulty_level,
learning_objectives,
key_vocabulary,
historical_period,
scientific_field,
status,
is_featured,
keywords,
search_tags,
created_by
) VALUES (
'50000001-0000-0000-0000-000000000001'::uuid,
v_tenant_id,
'Marie Curie: Primeros Años en Polonia',
'El nacimiento de una mente brillante',
'Explora la infancia y juventud de Maria Sklodowska en Varsovia, Polonia, su temprano amor por el aprendizaje y los desafíos que enfrentó como mujer en busca de educación en el siglo XIX.',
'biography',
'{
"introduction": "Maria Salomea Sklodowska nació el 7 de noviembre de 1867 en Varsovia, Polonia, cuando el país estaba bajo el dominio del Imperio Ruso.",
"main_content": "Desde muy joven, Maria demostró una extraordinaria capacidad intelectual. Era la menor de cinco hermanos en una familia de educadores. Su padre, Wladyslaw, era profesor de matemáticas y física, y su madre, Bronislawa, dirigía una prestigiosa escuela para niñas. La educación era profundamente valorada en la familia Sklodowski.",
"key_points": [
"Nació el 7 de noviembre de 1867 en Varsovia, Polonia",
"Era la menor de cinco hermanos",
"Su padre era profesor de matemáticas y física",
"Desde niña mostró memoria excepcional y amor por el aprendizaje",
"Aprendió a leer a los 4 años"
],
"timeline": [
{"year": 1867, "event": "Nacimiento en Varsovia"},
{"year": 1876, "event": "Muerte de su hermana Zofia por tifus"},
{"year": 1878, "event": "Muerte de su madre por tuberculosis"},
{"year": 1883, "event": "Graduación con medalla de oro"}
],
"quotes": [
{"text": "Nada en la vida debe ser temido, solo debe ser entendido.", "context": "Sobre el conocimiento científico"}
]
}'::jsonb,
ARRAY['6', '7', '8'],
'beginner',
ARRAY['Conocer los orígenes de Marie Curie', 'Comprender el contexto histórico de Polonia', 'Identificar influencias familiares en su educación'],
ARRAY['Polonia', 'Varsovia', 'Imperio Ruso', 'educación', 'familia Sklodowski'],
'1867-1891',
'Biography',
'published',
true,
ARRAY['marie curie', 'biografía', 'polonia', 'infancia', 'educación'],
ARRAY['#marie-curie', '#biografia', '#primeros-años', '#polonia'],
v_admin_id
)
ON CONFLICT (id) DO UPDATE SET
title = EXCLUDED.title,
content = EXCLUDED.content,
status = 'published',
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Biografía: Primeros Años en Polonia';
-- =====================================================
-- 2. BIOGRAFÍA - LLEGADA A PARÍS
-- =====================================================
INSERT INTO content_management.marie_curie_content (
id,
tenant_id,
title,
subtitle,
description,
category,
content,
target_grade_levels,
difficulty_level,
learning_objectives,
key_vocabulary,
historical_period,
scientific_field,
status,
is_featured,
keywords,
search_tags,
created_by
) VALUES (
'50000001-0000-0000-0000-000000000002'::uuid,
v_tenant_id,
'El Sueño de París: Marie en la Sorbona',
'Persiguiendo la educación contra todo pronóstico',
'La determinación de Marie para estudiar en la Universidad de París y sus primeros años como estudiante de física y matemáticas en la Sorbona.',
'biography',
'{
"introduction": "En 1891, a los 24 años, Maria Sklodowska finalmente llegó a París para cumplir su sueño de estudiar ciencias en la prestigiosa Universidad de la Sorbona.",
"main_content": "Marie vivía en condiciones muy humildes en el Barrio Latino. Su pequeña habitación en el sexto piso no tenía calefacción ni agua corriente. A menudo se olvidaba de comer, tan absorta estaba en sus estudios. A pesar de las dificultades económicas y el frío parisino, Marie se graduó primera de su promoción en física en 1893, y segunda en matemáticas en 1894.",
"key_points": [
"Llegó a París en noviembre de 1891",
"Se inscribió en la Facultad de Ciencias de la Sorbona",
"Cambió su nombre a Marie",
"Primera de su promoción en física (1893)",
"Segunda en matemáticas (1894)"
],
"timeline": [
{"year": 1891, "event": "Llegada a París e inscripción en la Sorbona"},
{"year": 1893, "event": "Licenciatura en Física (1ª de su promoción)"},
{"year": 1894, "event": "Licenciatura en Matemáticas"},
{"year": 1894, "event": "Conoce a Pierre Curie"}
],
"quotes": [
{"text": "La vida no es fácil para ninguno de nosotros. Pero... ¡qué importa! Debemos tener perseverancia.", "context": "Sobre su tiempo en París"}
]
}'::jsonb,
ARRAY['6', '7', '8'],
'beginner',
ARRAY['Valorar la perseverancia académica', 'Comprender las barreras para mujeres en educación', 'Conocer la vida universitaria del siglo XIX'],
ARRAY['Sorbona', 'París', 'universidad', 'Barrio Latino', 'física', 'matemáticas'],
'1891-1894',
'Biography',
'published',
true,
ARRAY['marie curie', 'sorbona', 'paris', 'universidad', 'educación'],
ARRAY['#marie-curie', '#sorbona', '#paris', '#universidad'],
v_admin_id
)
ON CONFLICT (id) DO UPDATE SET
title = EXCLUDED.title,
content = EXCLUDED.content,
status = 'published',
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Biografía: Llegada a París';
-- =====================================================
-- 3. DESCUBRIMIENTOS - RADIACTIVIDAD
-- =====================================================
INSERT INTO content_management.marie_curie_content (
id,
tenant_id,
title,
subtitle,
description,
category,
content,
target_grade_levels,
difficulty_level,
learning_objectives,
key_vocabulary,
historical_period,
scientific_field,
status,
is_featured,
keywords,
search_tags,
created_by
) VALUES (
'50000001-0000-0000-0000-000000000003'::uuid,
v_tenant_id,
'El Descubrimiento de la Radiactividad',
'Una nueva era en la física',
'El revolucionario trabajo de Marie Curie que llevó al descubrimiento del polonio y el radio, y la acuñación del término "radiactividad".',
'discoveries',
'{
"introduction": "En 1898, Marie Curie descubrió dos nuevos elementos químicos y acuñó el término radiactividad para describir la emisión espontánea de radiación por ciertos materiales.",
"main_content": "Marie eligió estudiar los misteriosos rayos de uranio descubiertos por Henri Becquerel para su tesis doctoral. Trabajando en un cobertizo frío y húmedo en la Escuela de Física, desarrolló técnicas innovadoras para medir la intensidad de la radiación. Descubrió que el mineral pechblenda era más radiactivo que el uranio puro, lo que sugería la presencia de elementos desconocidos.",
"key_points": [
"Acuñó el término ''radiactividad'' en 1898",
"Descubrió el polonio (nombrado en honor a Polonia)",
"Descubrió el radio (del latín radius, rayo)",
"Trabajó en condiciones extremadamente difíciles",
"Procesó toneladas de pechblenda para aislar el radio"
],
"timeline": [
{"year": 1897, "event": "Inicio de investigación sobre rayos de uranio"},
{"year": 1898, "event": "Descubrimiento del polonio (julio)"},
{"year": 1898, "event": "Descubrimiento del radio (diciembre)"},
{"year": 1902, "event": "Aislamiento de radio puro"},
{"year": 1903, "event": "Tesis doctoral sobre sustancias radiactivas"}
],
"quotes": [
{"text": "Uno nunca nota lo que se ha hecho; uno solo puede ver lo que queda por hacer.", "context": "Sobre el trabajo científico"}
]
}'::jsonb,
ARRAY['7', '8', '9'],
'intermediate',
ARRAY['Comprender el concepto de radiactividad', 'Conocer el proceso del descubrimiento científico', 'Valorar la metodología de investigación'],
ARRAY['radiactividad', 'polonio', 'radio', 'pechblenda', 'uranio', 'elementos químicos'],
'1897-1903',
'Physics',
'published',
true,
ARRAY['radiactividad', 'polonio', 'radio', 'descubrimiento', 'física'],
ARRAY['#radiactividad', '#polonio', '#radio', '#descubrimiento'],
v_admin_id
)
ON CONFLICT (id) DO UPDATE SET
title = EXCLUDED.title,
content = EXCLUDED.content,
status = 'published',
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Descubrimientos: Radiactividad';
-- =====================================================
-- 4. PREMIOS NOBEL
-- =====================================================
INSERT INTO content_management.marie_curie_content (
id,
tenant_id,
title,
subtitle,
description,
category,
content,
target_grade_levels,
difficulty_level,
learning_objectives,
key_vocabulary,
historical_period,
scientific_field,
status,
is_featured,
keywords,
search_tags,
created_by
) VALUES (
'50000001-0000-0000-0000-000000000004'::uuid,
v_tenant_id,
'Dos Premios Nobel: Un Logro Histórico',
'La primera persona en ganar dos Premios Nobel',
'Marie Curie hizo historia al ser la primera mujer en ganar un Premio Nobel y la primera persona en ganar dos en diferentes disciplinas científicas.',
'nobel_prizes',
'{
"introduction": "Marie Curie es la única persona en la historia en recibir Premios Nobel en dos ciencias diferentes: Física (1903) y Química (1911).",
"main_content": "En 1903, Marie compartió el Premio Nobel de Física con su esposo Pierre y Henri Becquerel por sus investigaciones sobre radiactividad. Inicialmente, el comité solo había nominado a Pierre y Becquerel, pero Pierre insistió en que Marie fuera incluida. En 1911, recibió el Premio Nobel de Química en solitario por el descubrimiento del polonio y el radio.",
"key_points": [
"Primera mujer en ganar un Premio Nobel (1903)",
"Premio Nobel de Física 1903 (compartido)",
"Premio Nobel de Química 1911 (individual)",
"Única persona con Nobel en dos ciencias diferentes",
"Primera mujer en ser profesora en la Sorbona"
],
"timeline": [
{"year": 1903, "event": "Premio Nobel de Física (con Pierre y Becquerel)"},
{"year": 1906, "event": "Sucede a Pierre como profesora en la Sorbona"},
{"year": 1911, "event": "Premio Nobel de Química (individual)"}
],
"quotes": [
{"text": "Soy de las que piensan que la ciencia tiene una gran belleza.", "context": "Sobre su pasión por la ciencia"}
]
}'::jsonb,
ARRAY['7', '8', '9'],
'intermediate',
ARRAY['Conocer los logros históricos de Marie Curie', 'Comprender la importancia de los Premios Nobel', 'Valorar el reconocimiento científico'],
ARRAY['Premio Nobel', 'Física', 'Química', 'Estocolmo', 'reconocimiento científico'],
'1903-1911',
'Physics',
'published',
true,
ARRAY['premio nobel', 'física', 'química', 'historia', 'logros'],
ARRAY['#nobel', '#premio', '#historia', '#logros'],
v_admin_id
)
ON CONFLICT (id) DO UPDATE SET
title = EXCLUDED.title,
content = EXCLUDED.content,
status = 'published',
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Premios Nobel';
-- =====================================================
-- 5. MUJERES EN LA CIENCIA
-- =====================================================
INSERT INTO content_management.marie_curie_content (
id,
tenant_id,
title,
subtitle,
description,
category,
content,
target_grade_levels,
difficulty_level,
learning_objectives,
key_vocabulary,
historical_period,
scientific_field,
status,
is_featured,
keywords,
search_tags,
created_by
) VALUES (
'50000001-0000-0000-0000-000000000005'::uuid,
v_tenant_id,
'Rompiendo Barreras: Marie Curie y las Mujeres en la Ciencia',
'Un legado de inspiración',
'El impacto de Marie Curie como pionera para las mujeres en la ciencia y su lucha contra los prejuicios de género en la academia.',
'women_in_science',
'{
"introduction": "Marie Curie no solo hizo contribuciones monumentales a la ciencia, sino que abrió puertas para las mujeres en campos tradicionalmente dominados por hombres.",
"main_content": "En una época donde las mujeres tenían acceso limitado a la educación superior, Marie tuvo que superar innumerables obstáculos. Fue la primera mujer en obtener un doctorado en ciencias en Francia, la primera profesora en la Sorbona, y la primera mujer en ser enterrada en el Panteón de París por méritos propios. Su hija Irène continuó su legado y también ganó el Premio Nobel.",
"key_points": [
"Primera mujer con doctorado en ciencias en Francia",
"Primera profesora de la Universidad de París",
"Primera mujer enterrada en el Panteón por méritos propios",
"Su hija Irène también ganó el Premio Nobel (1935)",
"Inspiración para generaciones de científicas"
],
"timeline": [
{"year": 1903, "event": "Primera mujer en ganar un Premio Nobel"},
{"year": 1906, "event": "Primera profesora en la Sorbona"},
{"year": 1995, "event": "Primera mujer enterrada en el Panteón por méritos propios"}
],
"quotes": [
{"text": "Sé menos curioso sobre las personas y más curioso sobre las ideas.", "context": "Consejo a jóvenes científicos"}
]
}'::jsonb,
ARRAY['6', '7', '8', '9'],
'beginner',
ARRAY['Valorar la lucha por la igualdad de género', 'Conocer barreras históricas para mujeres', 'Inspirarse en el legado de Marie Curie'],
ARRAY['igualdad', 'mujeres', 'ciencia', 'pionera', 'Irène Joliot-Curie'],
'1867-presente',
'History of Science',
'published',
true,
ARRAY['mujeres', 'ciencia', 'igualdad', 'pionera', 'inspiración'],
ARRAY['#mujeres-en-ciencia', '#igualdad', '#pionera', '#inspiración'],
v_admin_id
)
ON CONFLICT (id) DO UPDATE SET
title = EXCLUDED.title,
content = EXCLUDED.content,
status = 'published',
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Mujeres en la Ciencia';
-- =====================================================
-- 6. LEGADO
-- =====================================================
INSERT INTO content_management.marie_curie_content (
id,
tenant_id,
title,
subtitle,
description,
category,
content,
target_grade_levels,
difficulty_level,
learning_objectives,
key_vocabulary,
historical_period,
scientific_field,
status,
is_featured,
keywords,
search_tags,
created_by
) VALUES (
'50000001-0000-0000-0000-000000000006'::uuid,
v_tenant_id,
'El Legado Eterno de Marie Curie',
'Una vida dedicada a la ciencia y la humanidad',
'El impacto duradero de Marie Curie en la ciencia, la medicina y la sociedad, desde el tratamiento del cáncer hasta la inspiración de futuras generaciones.',
'legacy',
'{
"introduction": "El legado de Marie Curie trasciende sus descubrimientos científicos: sus contribuciones salvaron millones de vidas y continúan inspirando a científicos de todo el mundo.",
"main_content": "Durante la Primera Guerra Mundial, Marie organizó unidades móviles de rayos X (''petites Curies'') para ayudar a los médicos del frente a localizar balas y metralla en los cuerpos de los soldados. Ella misma condujo estas unidades y entrenó a otras mujeres para operarlas. El Instituto del Radio que fundó en París (hoy Instituto Curie) sigue siendo un centro líder en investigación del cáncer.",
"key_points": [
"Fundó el Instituto del Radio (hoy Instituto Curie)",
"Creó unidades móviles de rayos X en la WWI",
"Sus investigaciones llevaron a tratamientos contra el cáncer",
"El elemento 96 (Curio) lleva su nombre",
"Inspiración para generaciones de científicos"
],
"timeline": [
{"year": 1914, "event": "Organización de unidades de rayos X en WWI"},
{"year": 1921, "event": "Visita a EE.UU. - Recibe 1g de radio"},
{"year": 1934, "event": "Fallecimiento por anemia aplásica"},
{"year": 1944, "event": "Elemento 96 (Curio) nombrado en su honor"},
{"year": 1995, "event": "Traslado al Panteón de París"}
],
"quotes": [
{"text": "En la vida no hay cosas que temer, solo cosas que comprender.", "context": "Su filosofía de vida"}
]
}'::jsonb,
ARRAY['7', '8', '9'],
'intermediate',
ARRAY['Comprender el impacto de la ciencia en la sociedad', 'Valorar las contribuciones humanitarias', 'Conocer aplicaciones médicas de la radiactividad'],
ARRAY['legado', 'Instituto Curie', 'rayos X', 'medicina', 'cáncer', 'Primera Guerra Mundial'],
'1914-presente',
'Medicine',
'published',
true,
ARRAY['legado', 'instituto curie', 'medicina', 'rayos x', 'humanidad'],
ARRAY['#legado', '#instituto-curie', '#medicina', '#humanidad'],
v_admin_id
)
ON CONFLICT (id) DO UPDATE SET
title = EXCLUDED.title,
content = EXCLUDED.content,
status = 'published',
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Legado';
-- =====================================================
-- VERIFICACIÓN
-- =====================================================
RAISE NOTICE '';
RAISE NOTICE '=== CONTENIDO MARIE CURIE CREADO ===';
RAISE NOTICE 'Total artículos: %', (SELECT COUNT(*) FROM content_management.marie_curie_content);
RAISE NOTICE 'Publicados: %', (SELECT COUNT(*) FROM content_management.marie_curie_content WHERE status = 'published');
RAISE NOTICE 'Destacados: %', (SELECT COUNT(*) FROM content_management.marie_curie_content WHERE is_featured = true);
END $$;
-- =====================================================
-- VERIFICACIÓN FINAL
-- =====================================================
DO $$
DECLARE
v_count INTEGER;
BEGIN
SELECT COUNT(*) INTO v_count FROM content_management.marie_curie_content;
IF v_count < 5 THEN
RAISE WARNING '⚠️ Se esperaban al menos 5 artículos de Marie Curie';
ELSE
RAISE NOTICE '✅ Seed de marie_curie_content completado exitosamente';
END IF;
END $$;

View File

@ -0,0 +1,317 @@
-- =====================================================
-- Seed: educational_content.assignments (PROD)
-- Description: Assignments demo para Portal Teacher
-- Environment: PRODUCTION
-- Dependencies: auth.users (teachers)
-- Order: 05
-- Created: 2025-11-24
-- Version: 2.0 (Corregido CORR-006)
-- =====================================================
--
-- CAMBIOS v2.0:
-- - Corregida estructura para coincidir con DDL real de assignments
-- - Eliminadas referencias a tablas inexistentes (assignment_classrooms, assignment_exercises)
-- - Ajustado a columnas reales: teacher_id, title, description, assignment_type, due_date, total_points, is_published
-- - 9 assignments distribuidos en 3 módulos conceptuales
-- - Fechas variadas: past (vencidos), present (activos), future (pendientes)
-- - Tipos variados: practice, quiz, exam, homework
--
-- ASSIGNMENTS INCLUIDOS:
-- - 3 para conceptos del Módulo 1 (Comprensión Literal)
-- - 3 para conceptos del Módulo 2 (Comprensión Inferencial)
-- - 3 para conceptos del Módulo 3 (Comprensión Crítica)
--
-- TOTAL: 9 assignments demo para Portal Teacher
--
-- =====================================================
SET search_path TO educational_content, auth, public;
-- =====================================================
-- LIMPIAR DATOS EXISTENTES (SOLO DEMO)
-- =====================================================
-- Eliminar assignments del teacher demo si existen
DELETE FROM educational_content.assignments
WHERE teacher_id = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb';
-- =====================================================
-- Obtener IDs necesarios y validar dependencias
-- =====================================================
DO $$
DECLARE
v_teacher_id UUID;
BEGIN
-- Obtener el ID del profesor de testing
SELECT id INTO v_teacher_id
FROM auth.users
WHERE email = 'teacher@gamilit.com'
LIMIT 1;
IF v_teacher_id IS NULL THEN
RAISE EXCEPTION 'Teacher "teacher@gamilit.com" no encontrado. Ejecutar primero seed de auth/users.';
END IF;
RAISE NOTICE 'Usando teacher_id: %', v_teacher_id;
-- =====================================================
-- INSERT: 9 Assignments Demo
-- =====================================================
INSERT INTO educational_content.assignments (
id,
teacher_id,
title,
description,
assignment_type,
due_date,
total_points,
is_published,
created_at,
updated_at
) VALUES
-- =====================================================
-- MÓDULO 1: Comprensión Literal (3 assignments)
-- =====================================================
-- Assignment 1.1: Completado (vencido hace 7 días)
(
gen_random_uuid(),
v_teacher_id,
'Tarea 1.1: Crucigrama y Vocabulario Científico',
'Completa el crucigrama sobre términos científicos de Marie Curie y responde 5 preguntas de vocabulario. Incluye los ejercicios: Crucigrama Científico y Sopa de Letras. Esta tarea evaluará tu comprensión literal de los descubrimientos científicos de Marie Curie.',
'homework',
gamilit.now_mexico() - INTERVAL '7 days', -- Vencido hace 7 días
100,
true, -- Publicado
gamilit.now_mexico() - INTERVAL '14 days',
gamilit.now_mexico() - INTERVAL '14 days'
),
-- Assignment 1.2: Activo (vence en 2 días - URGENTE)
(
gen_random_uuid(),
v_teacher_id,
'Quiz 1.2: Línea de Tiempo de Marie Curie',
'Organiza cronológicamente los eventos más importantes de la vida de Marie Curie. Este quiz evaluará tu capacidad para identificar fechas y secuencias temporales del texto biográfico. Duración: 30 minutos.',
'quiz',
gamilit.now_mexico() + INTERVAL '2 days', -- Vence en 2 días
50,
true, -- Publicado
gamilit.now_mexico() - INTERVAL '5 days',
gamilit.now_mexico() - INTERVAL '5 days'
),
-- Assignment 1.3: Pendiente (vence en 10 días)
(
gen_random_uuid(),
v_teacher_id,
'Práctica 1.3: Mapa Conceptual - Descubrimientos',
'Crea un mapa conceptual que conecte a Marie Curie con sus descubrimientos científicos, instituciones y colaboradores. Esta práctica te permitirá visualizar las relaciones entre conceptos del módulo literal.',
'practice',
gamilit.now_mexico() + INTERVAL '10 days', -- Vence en 10 días
75,
true, -- Publicado
gamilit.now_mexico() - INTERVAL '2 days',
gamilit.now_mexico() - INTERVAL '2 days'
),
-- =====================================================
-- MÓDULO 2: Comprensión Inferencial (3 assignments)
-- =====================================================
-- Assignment 2.1: OVERDUE (vencido hace 3 días, aún publicado)
(
gen_random_uuid(),
v_teacher_id,
'Tarea 2.1: Relaciones Causa-Efecto',
'Identifica 3 relaciones causa-efecto en la vida de Marie Curie. Por ejemplo: la muerte de su madre → Marie se dedicó intensamente a los estudios. Debes encontrar al menos 3 ejemplos bien argumentados del texto.',
'homework',
gamilit.now_mexico() - INTERVAL '3 days', -- OVERDUE hace 3 días
120,
true, -- Publicado (aún pueden entregarla tarde)
gamilit.now_mexico() - INTERVAL '10 days',
gamilit.now_mexico() - INTERVAL '10 days'
),
-- Assignment 2.2: Activo (vence en 5 días)
(
gen_random_uuid(),
v_teacher_id,
'Quiz 2.2: Rueda de Inferencias',
'Resuelve 5 preguntas de inferencia sobre las motivaciones y decisiones de Marie Curie. Usa la Rueda de Inferencias para analizar contextos implícitos del texto. Duración: 45 minutos.',
'quiz',
gamilit.now_mexico() + INTERVAL '5 days', -- Vence en 5 días
100,
true, -- Publicado
gamilit.now_mexico() - INTERVAL '3 days',
gamilit.now_mexico() - INTERVAL '3 days'
),
-- Assignment 2.3: Pendiente (vence en 15 días)
(
gen_random_uuid(),
v_teacher_id,
'Práctica 2.3: Análisis de Decisiones',
'Analiza 3 decisiones importantes de Marie Curie (ejemplo: rechazar comercializar el radio) y explica las razones implícitas detrás de cada una. Usa evidencia del texto para respaldar tus inferencias.',
'practice',
gamilit.now_mexico() + INTERVAL '15 days', -- Vence en 15 días
150,
true, -- Publicado
gamilit.now_mexico() - INTERVAL '1 day',
gamilit.now_mexico() - INTERVAL '1 day'
),
-- =====================================================
-- MÓDULO 3: Comprensión Crítica (3 assignments)
-- =====================================================
-- Assignment 3.1: Activo (vence en 7 días)
(
gen_random_uuid(),
v_teacher_id,
'Tarea 3.1: Ensayo Crítico - Rol de la Mujer en Ciencia',
'Escribe un ensayo corto (300-400 palabras) sobre cómo Marie Curie desafió los roles de género de su época. Incluye 3 argumentos fundamentados en el texto y 1 reflexión personal sobre la importancia de su legado.',
'homework',
gamilit.now_mexico() + INTERVAL '7 days', -- Vence en 7 días
200,
true, -- Publicado
gamilit.now_mexico() - INTERVAL '4 days',
gamilit.now_mexico() - INTERVAL '4 days'
),
-- Assignment 3.2: Activo (vence en 3 días - URGENTE, quiz corto)
(
gen_random_uuid(),
v_teacher_id,
'Quiz 3.2: Evaluación Crítica Express',
'Quiz corto (15 minutos) con 3 preguntas de evaluación crítica sobre las decisiones éticas de Marie Curie. Ejemplo: ¿Fue correcto que no patentara el proceso de extracción del radio?',
'quiz',
gamilit.now_mexico() + INTERVAL '3 days', -- Vence en 3 días
50,
true, -- Publicado
gamilit.now_mexico() - INTERVAL '1 day',
gamilit.now_mexico() - INTERVAL '1 day'
),
-- Assignment 3.3: Pendiente (vence en 30 días - proyecto final)
(
gen_random_uuid(),
v_teacher_id,
'Proyecto Final: Presentación Multimedia sobre Marie Curie',
'Crea una presentación multimedia (video, podcast o infografía) que analice críticamente el impacto de Marie Curie en la ciencia moderna y la igualdad de género. Debe incluir: biografía, descubrimientos, obstáculos superados y legado actual. Duración: 5-7 minutos.',
'exam',
gamilit.now_mexico() + INTERVAL '30 days', -- Vence en 30 días (proyecto final)
300,
false, -- Borrador (aún no publicado)
gamilit.now_mexico() - INTERVAL '1 day',
gamilit.now_mexico() - INTERVAL '1 day'
)
ON CONFLICT (id) DO NOTHING;
END $$;
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
assignment_count INTEGER;
published_count INTEGER;
overdue_count INTEGER;
soon_count INTEGER;
future_count INTEGER;
BEGIN
-- Contar assignments totales
SELECT COUNT(*) INTO assignment_count
FROM educational_content.assignments;
-- Contar publicados
SELECT COUNT(*) INTO published_count
FROM educational_content.assignments
WHERE is_published = true;
-- Contar OVERDUE (vencidos y publicados)
SELECT COUNT(*) INTO overdue_count
FROM educational_content.assignments
WHERE due_date < gamilit.now_mexico() AND is_published = true;
-- Contar SOON (vencen en menos de 3 días)
SELECT COUNT(*) INTO soon_count
FROM educational_content.assignments
WHERE due_date < gamilit.now_mexico() + INTERVAL '3 days'
AND due_date > gamilit.now_mexico()
AND is_published = true;
-- Contar FUTURE (vencen en más de 3 días)
SELECT COUNT(*) INTO future_count
FROM educational_content.assignments
WHERE due_date > gamilit.now_mexico() + INTERVAL '3 days'
AND is_published = true;
RAISE NOTICE '========================================';
RAISE NOTICE 'ASSIGNMENTS DEMO CREADOS EXITOSAMENTE';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total assignments: %', assignment_count;
RAISE NOTICE ' - Publicados: %', published_count;
RAISE NOTICE ' - Borradores: %', assignment_count - published_count;
RAISE NOTICE '';
RAISE NOTICE 'Estado de assignments publicados:';
RAISE NOTICE ' - OVERDUE (vencidos): %', overdue_count;
RAISE NOTICE ' - SOON (vencen <3 días): %', soon_count;
RAISE NOTICE ' - FUTURE (vencen >3 días): %', future_count;
RAISE NOTICE '========================================';
IF assignment_count >= 9 THEN
RAISE NOTICE '✓ Assignments demo creados correctamente';
ELSE
RAISE WARNING '⚠ Se esperaban al menos 9 assignments, se crearon %', assignment_count;
END IF;
END $$;
-- =====================================================
-- Listado de assignments por tipo y urgencia
-- =====================================================
DO $$
DECLARE
assignment_record RECORD;
BEGIN
RAISE NOTICE '';
RAISE NOTICE 'Listado de assignments demo:';
RAISE NOTICE '========================================';
FOR assignment_record IN
SELECT
a.title,
a.assignment_type,
a.due_date,
a.total_points,
a.is_published,
CASE
WHEN a.due_date < gamilit.now_mexico() AND a.is_published THEN 'OVERDUE'
WHEN a.due_date < gamilit.now_mexico() + INTERVAL '3 days' AND a.due_date > gamilit.now_mexico() THEN 'SOON'
WHEN NOT a.is_published THEN 'DRAFT'
ELSE 'FUTURE'
END AS urgency,
TO_CHAR(a.due_date, 'YYYY-MM-DD HH24:MI') AS due_formatted
FROM educational_content.assignments a
ORDER BY a.due_date NULLS LAST
LOOP
RAISE NOTICE ' [%] % - % (% pts) - Vence: %',
assignment_record.urgency,
assignment_record.title,
assignment_record.assignment_type,
assignment_record.total_points,
COALESCE(assignment_record.due_formatted, 'Sin fecha');
END LOOP;
RAISE NOTICE '========================================';
END $$;
-- =====================================================
-- FIN DEL SEED
-- =====================================================

View File

@ -1,12 +1,18 @@
-- =====================================================
-- Seed Data: Exercises Module 4 - Textos Digitales (PRODUCTION)
-- Seed Data: Exercises Module 4 - Lectura Digital y Multimodal (DEV)
-- =====================================================
-- Description: 9 ejercicios completos del Módulo 4
-- Description: 5 ejercicios oficiales del Módulo 4 (según DocumentoDeDiseño v6.4)
-- Module: MOD-04-DIGITAL
-- Source: Migrado desde /home/isem/workspace/projects/glit/database
-- Date: 2025-11-03
-- Migration: ATLAS-DATABASE - ANALISIS-PRE-CORRECCIONES-BD-ORIGEN.md
-- Changes: Reemplazó 3 ejercicios compactos con 9 ejercicios completos
-- Exercises:
-- 4.1 Verificador Fake News
-- 4.2 Infografía Interactiva
-- 4.3 Quiz TikTok
-- 4.4 Navegación Hipertextual
-- 4.5 Análisis Memes
-- Reference: DocumentoDeDiseño_Mecanicas_GAMILIT_v6_1.md líneas 782-965
-- Date: 2025-12-18 (Limpieza: eliminados 4 ejercicios no oficiales)
-- NOTA: Ejercicios 4.6-4.9 (resena_critica, chat_literario, email_formal,
-- ensayo_argumentativo) fueron eliminados por no estar en el documento de diseño
-- =====================================================
SET search_path TO educational_content, public;
@ -151,6 +157,7 @@ BEGIN
);
-- Exercise 4.3: Navegación Hipertextual
-- Estructura: nodes[] con id, title, content, links[{targetId, label}]
INSERT INTO educational_content.exercises (
module_id, title, subtitle, description, instructions,
exercise_type, order_index,
@ -173,26 +180,58 @@ BEGIN
}'::jsonb,
'{
"researchQuestion": "¿Qué experimentos realizó Marie Curie para aislar el radio?",
"mainArticle": {
"title": "Marie Curie: Pionera de la Radiactividad",
"paragraphs": [
"Marie Curie revolucionó la ciencia con sus <link to=radiactividad>descubrimientos en radiactividad</link>...",
"Trabajó intensamente en el <link to=aislamiento>aislamiento de elementos radiactivos</link>..."
],
"links": [
{
"text": "radiactividad",
"relevance": "high",
"leadsTo": "Historia de la radiactividad"
},
{
"text": "aislamiento",
"relevance": "very high",
"leadsTo": "Proceso de aislamiento del radio"
}
]
},
"optimalPath": ["mainArticle", "aislamiento", "proceso experimental"]
"nodes": [
{
"id": "main-article",
"title": "Marie Curie: Pionera de la Radiactividad",
"content": "Marie Curie (1867-1934) fue una científica polaca-francesa que revolucionó nuestra comprensión de la física y la química. Junto con su esposo Pierre, realizó investigaciones pioneras sobre los fenómenos radiactivos, un término que ella misma acuñó.\n\nSus descubrimientos en radiactividad cambiaron para siempre el campo de la física nuclear. Trabajó intensamente durante años en el aislamiento de elementos radiactivos, un proceso que requirió una dedicación extraordinaria.",
"links": [
{ "targetId": "radiactividad", "label": "descubrimientos en radiactividad" },
{ "targetId": "aislamiento", "label": "aislamiento de elementos radiactivos" },
{ "targetId": "premios", "label": "reconocimientos y premios" }
]
},
{
"id": "radiactividad",
"title": "Historia de la Radiactividad",
"content": "El término ''radiactividad'' fue acuñado por Marie Curie en 1898. Henri Becquerel había descubierto en 1896 que las sales de uranio emitían rayos que podían impresionar placas fotográficas.\n\nMarie Curie decidió estudiar este fenómeno como tema de su tesis doctoral. Descubrió que la radiactividad era una propiedad atómica, no molecular, lo que fue revolucionario para la física de la época.",
"links": [
{ "targetId": "main-article", "label": "volver al artículo principal" },
{ "targetId": "aislamiento", "label": "proceso de aislamiento" }
]
},
{
"id": "aislamiento",
"title": "El Proceso de Aislamiento del Radio",
"content": "El aislamiento del radio fue uno de los logros más impresionantes de Marie Curie. Trabajando en condiciones precarias en un cobertizo sin calefacción, procesó toneladas de pechblenda para obtener pequeñas cantidades de radio puro.\n\nEl proceso requirió:\n• Trituración de toneladas de mineral de pechblenda\n• Disolución en ácidos y precipitación química\n• Cristalización fraccionada repetida durante años\n• Mediciones precisas de radiactividad\n\nEn 1902, logró aislar 0.1 gramos de cloruro de radio puro.",
"links": [
{ "targetId": "main-article", "label": "volver al artículo principal" },
{ "targetId": "experimentos", "label": "experimentos específicos" },
{ "targetId": "radiactividad", "label": "qué es la radiactividad" }
]
},
{
"id": "experimentos",
"title": "Experimentos de Marie Curie con el Radio",
"content": "Los experimentos de Marie Curie para aislar el radio fueron meticulosos y agotadores:\n\n1. **Análisis de la pechblenda**: Descubrió que era más radiactiva de lo esperado, lo que sugería la presencia de elementos desconocidos.\n\n2. **Separación química**: Usó técnicas de precipitación selectiva para separar diferentes fracciones del mineral.\n\n3. **Cristalización fraccionada**: El proceso más largo. Disolvía cloruros y los cristalizaba repetidamente, separando el radio del bario por sus diferentes solubilidades.\n\n4. **Medición con electrómetro**: Usó un electrómetro piezoeléctrico diseñado por Pierre para medir la radiactividad y seguir el rastro del radio.\n\n¡Este es el objetivo de tu investigación! Has encontrado la información sobre los experimentos.",
"links": [
{ "targetId": "aislamiento", "label": "volver a aislamiento" },
{ "targetId": "premios", "label": "premios recibidos" }
]
},
{
"id": "premios",
"title": "Premios y Reconocimientos",
"content": "Marie Curie recibió numerosos reconocimientos por su trabajo:\n\n• **Premio Nobel de Física (1903)**: Compartido con Pierre Curie y Henri Becquerel por sus investigaciones sobre radiación.\n\n• **Premio Nobel de Química (1911)**: Por el descubrimiento del radio y polonio, y por el aislamiento del radio.\n\nFue la primera persona en ganar dos Premios Nobel en diferentes ciencias.",
"links": [
{ "targetId": "main-article", "label": "volver al artículo principal" },
{ "targetId": "aislamiento", "label": "proceso de aislamiento" }
]
}
],
"startNodeId": "main-article",
"targetNodeId": "experimentos",
"optimalPath": ["main-article", "aislamiento", "experimentos"]
}'::jsonb,
'{"informationFound": true, "pathEfficiency": 0.8, "relevantLinks": 3}'::jsonb,
'intermediate', 100, 70,
@ -330,6 +369,5 @@ BEGIN
true
);
RAISE NOTICE '✓ Module 4 (Textos Digitales) created with 5 exercises';
END $$;
RAISE NOTICE '✓ Module 4 (Lectura Digital y Multimodal) created with 5 exercises';
END $$;

View File

@ -0,0 +1,468 @@
-- ============================================================================
-- SEED: exercise_validation_config
-- Descripción: Configuración de validación para 17 tipos de ejercicios
-- Autor: Database Agent
-- Fecha: 2025-11-19
-- Actualizado: 2025-11-28 (BUG-002, BUG-003 - Agregados mapa_conceptual y emparejamiento)
-- Tarea: DB-116 (Handoff FE-059)
-- Alcance: Módulos 1, 2, 3 (17 tipos implementados)
-- ============================================================================
INSERT INTO educational_content.exercise_validation_config (
exercise_type,
validation_function,
case_sensitive,
allow_partial_credit,
fuzzy_matching_threshold,
normalize_text,
special_rules,
default_max_points,
default_passing_score,
description,
examples
) VALUES
-- ============================================================================
-- MÓDULO 1: COMPRENSIÓN LITERAL (7 tipos)
-- ============================================================================
-- 1.1. CRUCIGRAMA
(
'crucigrama',
'validate_crucigrama',
false, -- No case-sensitive
true, -- Puntuación parcial por respuesta correcta
NULL, -- No fuzzy matching (respuestas exactas)
true, -- Normalizar texto (quitar acentos)
'{
"allow_empty_cells": false,
"score_per_word": true
}'::jsonb,
100,
70,
'Validación de crucigrama: compara cada respuesta con solution por id (h1, h2, v1, etc.)',
'{
"submitted": {"clues": {"h1": "sorbona", "h2": "nobel"}},
"solution": {"clues": {"h1": "SORBONA", "h2": "NOBEL"}},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- 1.2. LÍNEA DE TIEMPO
(
'linea_tiempo',
'validate_timeline',
false,
true,
NULL,
true,
'{
"scoring_method": "position_based",
"allow_partial_order": true
}'::jsonb,
100,
70,
'Validación de línea de tiempo: compara orden de eventos',
'{
"submitted": {"events": ["event-1", "event-2", "event-3"]},
"solution": {"correctOrder": ["event-1", "event-2", "event-3"]},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- 1.3. SOPA DE LETRAS
(
'sopa_letras',
'validate_word_search',
false,
true,
NULL,
true,
'{
"score_per_word_found": true,
"require_all_words": false
}'::jsonb,
100,
70,
'Validación de sopa de letras: verifica palabras encontradas vs esperadas',
'{
"submitted": {"words": ["MARIE", "CURIE", "POLONIA"]},
"solution": {"allWords": ["MARIE", "CURIE", "POLONIA", "NOBEL", "RADIO"]},
"result": {"is_correct": false, "score": 60}
}'::jsonb
),
-- 1.4. COMPLETAR ESPACIOS
(
'completar_espacios',
'validate_fill_in_blank',
false,
true,
0.85, -- Permitir 85% de similaridad (fuzzy matching)
true,
'{
"allow_synonyms": false,
"score_per_blank": true
}'::jsonb,
100,
70,
'Validación de completar espacios: compara cada respuesta con correctAnswers por id',
'{
"submitted": {"blanks": {"blank1": "varsovia", "blank2": "wladyslaw"}},
"solution": {"correctAnswers": {"blank1": "Varsovia", "blank2": "Władysław"}},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- 1.5. VERDADERO O FALSO
(
'verdadero_falso',
'validate_true_false',
false,
true,
NULL,
false,
'{
"score_per_statement": true
}'::jsonb,
100,
70,
'Validación de verdadero/falso: compara objeto de statements',
'{
"submitted": {"statements": {"stmt1": false, "stmt2": true, "stmt3": true, "stmt4": false}},
"solution": {"correctAnswers": {"stmt1": false, "stmt2": true, "stmt3": true, "stmt4": false}},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- 1.6. MAPA CONCEPTUAL
(
'mapa_conceptual',
'validate_mapa_conceptual',
false,
true,
NULL,
false,
'{
"score_per_connection": true,
"allow_partial_graph": true
}'::jsonb,
100,
70,
'Validación de mapa conceptual: verifica conexiones entre conceptos',
'{
"submitted": {"connections": [{"from": "concept1", "to": "concept2", "label": "relaciona"}]},
"solution": {"connections": [{"from": "concept1", "to": "concept2", "label": "relaciona"}]},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- 1.7. EMPAREJAMIENTO
(
'emparejamiento',
'validate_emparejamiento',
false,
true,
NULL,
true,
'{
"score_per_match": true,
"allow_partial_matches": true
}'::jsonb,
100,
70,
'Validación de emparejamiento: verifica pares correctos',
'{
"submitted": {"matches": {"item1": "pair1", "item2": "pair2"}},
"solution": {"correctMatches": {"item1": "pair1", "item2": "pair2"}},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- ============================================================================
-- MÓDULO 2: COMPRENSIÓN INFERENCIAL (5 tipos)
-- ============================================================================
-- 2.1. DETECTIVE TEXTUAL
(
'detective_textual',
'validate_detective_textual',
false,
true,
NULL,
false,
'{
"allowPartialCredit": true
}'::jsonb,
100,
70,
'Validación de detective textual: preguntas de inferencia con opciones múltiples',
'{
"submitted": {"questions": {"q1": "1", "q2": "1", "q3": "1", "q4": "1"}},
"solution": {"correctAnswers": {"q1": "1", "q2": "1", "q3": "1", "q4": "1"}, "totalQuestions": 4},
"result": {"is_correct": true, "correct_answers": 4, "score": 100}
}'::jsonb
),
-- 2.2. CONSTRUCCIÓN DE HIPÓTESIS (Causa-Efecto Matching)
(
'construccion_hipotesis',
'validate_cause_effect_matching',
false,
true,
NULL,
true,
'{
"allowPartialMatches": true,
"strictOrder": false
}'::jsonb,
100,
70,
'Validación de causa-efecto: asociación de causas con consecuencias mediante drag & drop',
'{
"submitted": {"causes": {"c1": ["cons1", "cons2"], "c2": ["cons3"], "c3": ["cons4"]}},
"solution": {"causes": {"c1": ["cons1", "cons2"], "c2": ["cons3"], "c3": ["cons4"]}},
"result": {"is_correct": true, "correctCount": 4, "totalCount": 4, "score": 100}
}'::jsonb
),
-- 2.3. PREDICCIÓN NARRATIVA
(
'prediccion_narrativa',
'validate_prediction_scenarios',
false,
true,
NULL,
true,
'{
"allowPartialCredit": true
}'::jsonb,
100,
70,
'Validación de predicción narrativa: selección de predicciones predefinidas para múltiples escenarios',
'{
"submitted": {"scenarios": {"pred-1": "p2", "pred-2": "p1"}},
"solution": {"scenarios": {"pred-1": "p2", "pred-2": "p1"}},
"result": {"is_correct": true, "correctCount": 2, "score": 100}
}'::jsonb
),
-- 2.4. PUZZLE DE CONTEXTO
(
'puzzle_contexto',
'validate_puzzle_contexto',
false,
true,
NULL,
false,
'{
"score_per_question": true,
"question_type": "context_inference"
}'::jsonb,
100,
70,
'Validación de puzzle de contexto: multiple choice con inferencias contextuales',
'{
"submitted": {"questions": {"q1": "option_c", "q2": "option_a"}},
"solution": {"correctAnswers": {"q1": "option_c", "q2": "option_a"}},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- 2.5. RUEDA DE INFERENCIAS (Texto Libre)
(
'rueda_inferencias',
'validate_rueda_inferencias',
false,
true,
NULL,
true,
'{
"validation_type": "keyword_based",
"min_keywords": 2,
"min_length": 20,
"max_length": 200,
"score_per_fragment": true
}'::jsonb,
100,
70,
'Validación de rueda de inferencias con texto libre: wrapper estándar que valida múltiples fragmentos con keywords',
'{
"submitted": {"fragments": {"frag-1": "Marie Curie fue la primera mujer en ganar el Nobel en física y química", "frag-2": "Ella usaba el apellido Curie en sus publicaciones"}},
"solution": {"fragments": [{"id": "frag-1", "keywords": ["nobel", "física", "química", "primera", "mujer"], "points": 20}, {"id": "frag-2", "keywords": ["apellido", "curie", "publicaciones"], "points": 20}], "validation": {"minKeywords": 2, "minLength": 20, "maxLength": 200}},
"result": {"is_correct": true, "valid_fragments": 2, "total_points": 40, "score": 100}
}'::jsonb
),
-- ============================================================================
-- MÓDULO 3: COMPRENSIÓN CRÍTICA (5 tipos)
-- ============================================================================
-- 3.1. TRIBUNAL DE OPINIONES
(
'tribunal_opiniones',
'validate_tribunal_opiniones',
false,
true,
0.75,
true,
'{
"min_word_count": 100,
"require_keywords": true,
"keywords": ["argumento", "evidencia", "porque", "razón"],
"rubric_criteria": ["argumentación", "evidencia", "contra-argumentos"]
}'::jsonb,
100,
70,
'Validación heurística de tribunal: verifica longitud y palabras clave de argumentación',
'{
"submitted": {"opinion": "Opino que Marie Curie fue importante porque..."},
"solution": {"keywords": ["argumento", "evidencia", "porque"], "min_words": 100},
"result": {"is_correct": true, "score": 85}
}'::jsonb
),
-- 3.2. DEBATE DIGITAL
(
'debate_digital',
'validate_debate_digital',
false,
true,
0.75,
true,
'{
"min_word_count": 150,
"require_keywords": true,
"keywords": ["postura", "evidencia", "argumento", "contra-argumento"],
"rubric_criteria": ["postura_clara", "evidencias", "respeto"]
}'::jsonb,
100,
70,
'Validación heurística de debate: verifica longitud, palabras clave y estructura argumentativa',
'{
"submitted": {"debate": "Mi postura es que... porque las evidencias muestran..."},
"solution": {"keywords": ["postura", "evidencia", "argumento"], "min_words": 150},
"result": {"is_correct": true, "score": 90}
}'::jsonb
),
-- 3.3. ANÁLISIS DE FUENTES
(
'analisis_fuentes',
'validate_analisis_fuentes',
false,
true,
NULL,
false,
'{
"score_per_question": true,
"question_type": "source_analysis"
}'::jsonb,
100,
70,
'Validación de análisis de fuentes: preguntas de análisis crítico',
'{
"submitted": {"questions": {"q1": "option_a", "q2": "option_c"}},
"solution": {"correctAnswers": {"q1": "option_a", "q2": "option_c"}},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- 3.4. PODCAST ARGUMENTATIVO
(
'podcast_argumentativo',
'validate_podcast_argumentativo',
false,
true,
NULL,
false,
'{
"check_duration": true,
"min_duration_seconds": 120,
"max_duration_seconds": 300,
"check_format": true,
"allowed_formats": ["mp3", "wav", "ogg"]
}'::jsonb,
100,
70,
'Validación de podcast: verifica duración y formato de audio',
'{
"submitted": {"audio_url": "https://example.com/podcast.mp3", "duration": 180},
"solution": {"min_duration": 120, "max_duration": 300},
"result": {"is_correct": true, "score": 100}
}'::jsonb
),
-- 3.5. MATRIZ DE PERSPECTIVAS
(
'matriz_perspectivas',
'validate_matriz_perspectivas',
false,
true,
0.75,
true,
'{
"score_per_cell": true,
"require_all_cells": true,
"min_chars_per_cell": 50
}'::jsonb,
100,
70,
'Validación de matriz: verifica que todas las celdas estén completadas correctamente',
'{
"submitted": {"matrix": {"cell1": "perspectiva A", "cell2": "perspectiva B"}},
"solution": {"required_cells": ["cell1", "cell2"], "min_chars": 50},
"result": {"is_correct": true, "score": 100}
}'::jsonb
)
ON CONFLICT (exercise_type)
DO UPDATE SET
validation_function = EXCLUDED.validation_function,
case_sensitive = EXCLUDED.case_sensitive,
allow_partial_credit = EXCLUDED.allow_partial_credit,
fuzzy_matching_threshold = EXCLUDED.fuzzy_matching_threshold,
normalize_text = EXCLUDED.normalize_text,
special_rules = EXCLUDED.special_rules,
default_max_points = EXCLUDED.default_max_points,
default_passing_score = EXCLUDED.default_passing_score,
description = EXCLUDED.description,
examples = EXCLUDED.examples,
updated_at = gamilit.now_mexico();
-- ============================================================================
-- VERIFICACIÓN
-- ============================================================================
-- Verificar que se cargaron las 17 configuraciones
DO $$
DECLARE
v_count INTEGER;
BEGIN
SELECT COUNT(*) INTO v_count
FROM educational_content.exercise_validation_config;
IF v_count < 17 THEN
RAISE WARNING 'Solo se cargaron % configuraciones. Se esperaban 17.', v_count;
ELSE
RAISE NOTICE 'Configuraciones cargadas correctamente: % de 17', v_count;
END IF;
END $$;
-- Mostrar resumen de configuraciones
SELECT
exercise_type,
validation_function,
CASE
WHEN allow_partial_credit THEN 'Parcial'
ELSE 'Todo/Nada'
END as scoring,
CASE
WHEN fuzzy_matching_threshold IS NOT NULL
THEN fuzzy_matching_threshold::TEXT
ELSE 'Exacto'
END as matching,
default_max_points as max_pts,
default_passing_score as pass_pts
FROM educational_content.exercise_validation_config
ORDER BY exercise_type;

View File

@ -0,0 +1,262 @@
-- =====================================================
-- Seed: educational_content.module_dependencies
-- Description: Dependencias entre módulos educativos
-- Priority: P0 - CRÍTICO (Auditoría AUDIT-DB-001)
-- Created: 2025-12-14
-- =====================================================
--
-- Este seed define las dependencias/prerrequisitos entre módulos.
-- La progresión del estudiante se valida usando estas dependencias.
--
-- Estructura de módulos GAMILIT:
-- - MOD-01-LITERAL: Comprensión Literal (sin prerrequisitos)
-- - MOD-02-INFERENCIAL: Comprensión Inferencial (requiere MOD-01)
-- - MOD-03-CRITICA: Comprensión Crítica (requiere MOD-02)
-- - MOD-04-DIGITAL: Lectura Digital (requiere MOD-01, recomendado MOD-02)
-- - MOD-05-PRODUCCION: Producción Lectora (requiere MOD-03)
--
-- Tipos de dependencia:
-- - required: Debe completarse antes (bloqueante)
-- - recommended: Se recomienda completar antes
-- - optional: Complementario, no bloqueante
-- =====================================================
DO $$
DECLARE
v_mod1_id UUID;
v_mod2_id UUID;
v_mod3_id UUID;
v_mod4_id UUID;
v_mod5_id UUID;
BEGIN
-- Obtener IDs de módulos por su código
SELECT id INTO v_mod1_id FROM educational_content.modules WHERE module_code = 'MOD-01-LITERAL';
SELECT id INTO v_mod2_id FROM educational_content.modules WHERE module_code = 'MOD-02-INFERENCIAL';
SELECT id INTO v_mod3_id FROM educational_content.modules WHERE module_code = 'MOD-03-CRITICA';
SELECT id INTO v_mod4_id FROM educational_content.modules WHERE module_code = 'MOD-04-DIGITAL';
SELECT id INTO v_mod5_id FROM educational_content.modules WHERE module_code = 'MOD-05-PRODUCCION';
-- Verificar que todos los módulos existen
IF v_mod1_id IS NULL THEN
RAISE EXCEPTION 'Módulo MOD-01-LITERAL no encontrado. Ejecutar primero 01-modules.sql';
END IF;
IF v_mod2_id IS NULL THEN
RAISE EXCEPTION 'Módulo MOD-02-INFERENCIAL no encontrado. Ejecutar primero 01-modules.sql';
END IF;
IF v_mod3_id IS NULL THEN
RAISE EXCEPTION 'Módulo MOD-03-CRITICA no encontrado. Ejecutar primero 01-modules.sql';
END IF;
IF v_mod4_id IS NULL THEN
RAISE EXCEPTION 'Módulo MOD-04-DIGITAL no encontrado. Ejecutar primero 01-modules.sql';
END IF;
IF v_mod5_id IS NULL THEN
RAISE EXCEPTION 'Módulo MOD-05-PRODUCCION no encontrado. Ejecutar primero 01-modules.sql';
END IF;
RAISE NOTICE 'Todos los módulos encontrados. Creando dependencias...';
-- =====================================================
-- DEPENDENCIA 1: MOD-02 requiere MOD-01 (100%)
-- Comprensión Inferencial requiere Comprensión Literal
-- =====================================================
INSERT INTO educational_content.module_dependencies (
id,
module_id,
prerequisite_module_id,
dependency_type,
minimum_completion_percentage
) VALUES (
'30000001-0000-0000-0000-000000000001'::uuid,
v_mod2_id,
v_mod1_id,
'required',
80 -- 80% del módulo 1 debe completarse
)
ON CONFLICT (module_id, prerequisite_module_id) DO UPDATE SET
dependency_type = EXCLUDED.dependency_type,
minimum_completion_percentage = EXCLUDED.minimum_completion_percentage;
RAISE NOTICE '✅ MOD-02 → MOD-01 (required, 80%%)';
-- =====================================================
-- DEPENDENCIA 2: MOD-03 requiere MOD-02 (100%)
-- Comprensión Crítica requiere Comprensión Inferencial
-- =====================================================
INSERT INTO educational_content.module_dependencies (
id,
module_id,
prerequisite_module_id,
dependency_type,
minimum_completion_percentage
) VALUES (
'30000001-0000-0000-0000-000000000002'::uuid,
v_mod3_id,
v_mod2_id,
'required',
80 -- 80% del módulo 2 debe completarse
)
ON CONFLICT (module_id, prerequisite_module_id) DO UPDATE SET
dependency_type = EXCLUDED.dependency_type,
minimum_completion_percentage = EXCLUDED.minimum_completion_percentage;
RAISE NOTICE '✅ MOD-03 → MOD-02 (required, 80%%)';
-- =====================================================
-- DEPENDENCIA 3: MOD-04 requiere MOD-01 (50%)
-- Lectura Digital requiere base de Comprensión Literal
-- =====================================================
INSERT INTO educational_content.module_dependencies (
id,
module_id,
prerequisite_module_id,
dependency_type,
minimum_completion_percentage
) VALUES (
'30000001-0000-0000-0000-000000000003'::uuid,
v_mod4_id,
v_mod1_id,
'required',
50 -- 50% del módulo 1 (más flexible para ruta paralela)
)
ON CONFLICT (module_id, prerequisite_module_id) DO UPDATE SET
dependency_type = EXCLUDED.dependency_type,
minimum_completion_percentage = EXCLUDED.minimum_completion_percentage;
RAISE NOTICE '✅ MOD-04 → MOD-01 (required, 50%%)';
-- =====================================================
-- DEPENDENCIA 4: MOD-04 recomienda MOD-02
-- Se beneficia de habilidades inferenciales pero no es bloqueante
-- =====================================================
INSERT INTO educational_content.module_dependencies (
id,
module_id,
prerequisite_module_id,
dependency_type,
minimum_completion_percentage
) VALUES (
'30000001-0000-0000-0000-000000000004'::uuid,
v_mod4_id,
v_mod2_id,
'recommended',
60 -- 60% recomendado pero no obligatorio
)
ON CONFLICT (module_id, prerequisite_module_id) DO UPDATE SET
dependency_type = EXCLUDED.dependency_type,
minimum_completion_percentage = EXCLUDED.minimum_completion_percentage;
RAISE NOTICE '✅ MOD-04 → MOD-02 (recommended, 60%%)';
-- =====================================================
-- DEPENDENCIA 5: MOD-05 requiere MOD-03 (100%)
-- Producción Lectora requiere maestría en Comprensión Crítica
-- =====================================================
INSERT INTO educational_content.module_dependencies (
id,
module_id,
prerequisite_module_id,
dependency_type,
minimum_completion_percentage
) VALUES (
'30000001-0000-0000-0000-000000000005'::uuid,
v_mod5_id,
v_mod3_id,
'required',
80 -- 80% del módulo 3 (alto requisito para producción)
)
ON CONFLICT (module_id, prerequisite_module_id) DO UPDATE SET
dependency_type = EXCLUDED.dependency_type,
minimum_completion_percentage = EXCLUDED.minimum_completion_percentage;
RAISE NOTICE '✅ MOD-05 → MOD-03 (required, 80%%)';
-- =====================================================
-- DEPENDENCIA 6: MOD-05 recomienda MOD-04
-- Habilidades digitales complementan la producción
-- =====================================================
INSERT INTO educational_content.module_dependencies (
id,
module_id,
prerequisite_module_id,
dependency_type,
minimum_completion_percentage
) VALUES (
'30000001-0000-0000-0000-000000000006'::uuid,
v_mod5_id,
v_mod4_id,
'recommended',
50 -- 50% recomendado para producción digital
)
ON CONFLICT (module_id, prerequisite_module_id) DO UPDATE SET
dependency_type = EXCLUDED.dependency_type,
minimum_completion_percentage = EXCLUDED.minimum_completion_percentage;
RAISE NOTICE '✅ MOD-05 → MOD-04 (recommended, 50%%)';
-- =====================================================
-- VERIFICACIÓN
-- =====================================================
RAISE NOTICE '';
RAISE NOTICE '=== DEPENDENCIAS DE MÓDULOS CREADAS ===';
RAISE NOTICE 'Total dependencias: %', (SELECT COUNT(*) FROM educational_content.module_dependencies);
RAISE NOTICE 'Required: %', (SELECT COUNT(*) FROM educational_content.module_dependencies WHERE dependency_type = 'required');
RAISE NOTICE 'Recommended: %', (SELECT COUNT(*) FROM educational_content.module_dependencies WHERE dependency_type = 'recommended');
END $$;
-- =====================================================
-- VERIFICACIÓN FINAL
-- =====================================================
DO $$
DECLARE
v_count INTEGER;
BEGIN
SELECT COUNT(*) INTO v_count FROM educational_content.module_dependencies;
IF v_count < 5 THEN
RAISE WARNING '⚠️ Se esperaban al menos 5 dependencias de módulos';
ELSE
RAISE NOTICE '✅ Seed de module_dependencies completado exitosamente';
END IF;
END $$;
-- =====================================================
-- MAPA DE DEPENDENCIAS (COMENTARIO)
-- =====================================================
/*
RUTA DE PROGRESIÓN GAMILIT:
MOD-01-LITERAL Punto de entrada (sin prerrequisitos)
(Comprensión
Literal)
required (80%)
MOD-02-INFEREN. MOD-04-DIGITAL
(Comprensión (Lectura Ruta paralela (50% MOD-01)
Inferencial) ········> Digital) recommended MOD-02
required (80%) recommended (50%)
MOD-03-CRITICA
(Comprensión
Crítica)
required (80%)
MOD-05-PRODUC.
(Producción Requiere MOD-03, recomienda MOD-04
Lectora)
*/

View File

@ -0,0 +1,158 @@
-- =====================================================
-- Seed: educational_content.taxonomies
-- Description: Taxonomías educativas para clasificación de ejercicios
-- Priority: P0 - CRÍTICO (Auditoría AUDIT-DB-001)
-- Created: 2025-12-14
-- =====================================================
--
-- Este seed completa las taxonomías educativas del sistema.
-- La taxonomía de Bloom ya existe en el DDL, aquí agregamos:
-- - SOLO Taxonomy (Structure of Observed Learning Outcomes)
-- - Webb's DOK (Depth of Knowledge)
-- - Taxonomía GAMILIT (personalizada para lectura)
--
-- Tipos de taxonomía (CHECK constraint):
-- - bloom: Taxonomía de Bloom (cognitiva)
-- - solo: SOLO Taxonomy (estructural)
-- - webb: Webb's Depth of Knowledge
-- - custom: Taxonomías personalizadas
-- =====================================================
DO $$
BEGIN
-- =====================================================
-- 1. TAXONOMÍA DE BLOOM (ACTUALIZACIÓN/INSERCIÓN)
-- =====================================================
INSERT INTO educational_content.taxonomies (
id, name, description, taxonomy_type, levels, is_active
) VALUES (
'40000001-0000-0000-0000-000000000001'::uuid,
'Taxonomía de Bloom',
'Taxonomía cognitiva de Benjamin Bloom para clasificar objetivos educativos',
'bloom',
'[
{"level": 1, "name": "Recordar", "description": "Recuperar conocimiento de la memoria", "verbs": ["definir", "identificar", "listar", "nombrar", "recordar"]},
{"level": 2, "name": "Comprender", "description": "Construir significado a partir de mensajes", "verbs": ["explicar", "interpretar", "resumir", "clasificar", "comparar"]},
{"level": 3, "name": "Aplicar", "description": "Usar procedimientos en situaciones dadas", "verbs": ["aplicar", "demostrar", "ejecutar", "implementar", "resolver"]},
{"level": 4, "name": "Analizar", "description": "Descomponer en partes e identificar relaciones", "verbs": ["analizar", "diferenciar", "organizar", "atribuir", "deconstruir"]},
{"level": 5, "name": "Evaluar", "description": "Hacer juicios basados en criterios", "verbs": ["evaluar", "criticar", "juzgar", "justificar", "argumentar"]},
{"level": 6, "name": "Crear", "description": "Reorganizar elementos en nuevo patrón", "verbs": ["crear", "diseñar", "construir", "producir", "inventar"]}
]'::jsonb,
true
)
ON CONFLICT (name) DO UPDATE SET
description = EXCLUDED.description,
levels = EXCLUDED.levels,
is_active = true,
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Taxonomía de Bloom creada/actualizada';
-- =====================================================
-- 2. TAXONOMÍA SOLO (Structure of Observed Learning Outcomes)
-- =====================================================
INSERT INTO educational_content.taxonomies (
id, name, description, taxonomy_type, levels, is_active
) VALUES (
'40000001-0000-0000-0000-000000000002'::uuid,
'Taxonomía SOLO',
'Structure of Observed Learning Outcomes - Biggs & Collis para evaluar calidad de respuestas',
'solo',
'[
{"level": 1, "name": "Preestructural", "description": "El estudiante no entiende la tarea", "indicator": "Respuesta irrelevante o sin relación"},
{"level": 2, "name": "Uniestructural", "description": "El estudiante enfoca un aspecto relevante", "indicator": "Un punto relevante identificado"},
{"level": 3, "name": "Multiestructural", "description": "El estudiante enfoca varios aspectos relevantes independientes", "indicator": "Varios puntos sin conexión"},
{"level": 4, "name": "Relacional", "description": "El estudiante integra aspectos en una estructura coherente", "indicator": "Puntos conectados y relacionados"},
{"level": 5, "name": "Abstracto Extendido", "description": "El estudiante generaliza más allá de la tarea", "indicator": "Aplicación a nuevos dominios"}
]'::jsonb,
true
)
ON CONFLICT (name) DO UPDATE SET
description = EXCLUDED.description,
levels = EXCLUDED.levels,
is_active = true,
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Taxonomía SOLO creada/actualizada';
-- =====================================================
-- 3. WEBB'S DEPTH OF KNOWLEDGE (DOK)
-- =====================================================
INSERT INTO educational_content.taxonomies (
id, name, description, taxonomy_type, levels, is_active
) VALUES (
'40000001-0000-0000-0000-000000000003'::uuid,
'Webb DOK',
'Depth of Knowledge de Norman Webb para alinear estándares con evaluaciones',
'webb',
'[
{"level": 1, "name": "Recordar y Reproducir", "description": "Recuerdo de hechos, definiciones, términos", "examples": ["Identificar", "Definir", "Reconocer", "Localizar"]},
{"level": 2, "name": "Habilidades y Conceptos", "description": "Usar información, aplicar conceptos", "examples": ["Resumir", "Interpretar", "Organizar", "Clasificar"]},
{"level": 3, "name": "Pensamiento Estratégico", "description": "Razonamiento complejo, múltiples pasos", "examples": ["Analizar", "Evaluar", "Formular", "Investigar"]},
{"level": 4, "name": "Pensamiento Extendido", "description": "Pensamiento complejo a largo plazo", "examples": ["Diseñar", "Crear", "Sintetizar", "Aplicar conceptos"]}
]'::jsonb,
true
)
ON CONFLICT (name) DO UPDATE SET
description = EXCLUDED.description,
levels = EXCLUDED.levels,
is_active = true,
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Webb DOK creada/actualizada';
-- =====================================================
-- 4. TAXONOMÍA GAMILIT (Personalizada para Comprensión Lectora)
-- =====================================================
INSERT INTO educational_content.taxonomies (
id, name, description, taxonomy_type, levels, is_active
) VALUES (
'40000001-0000-0000-0000-000000000004'::uuid,
'Taxonomía GAMILIT',
'Taxonomía personalizada de GAMILIT para comprensión lectora basada en Marie Curie',
'custom',
'[
{"level": 1, "name": "Comprensión Literal", "description": "Identificar información explícita en el texto", "module": "MOD-01-LITERAL", "skills": ["Identificar hechos", "Localizar información", "Reconocer secuencias"]},
{"level": 2, "name": "Comprensión Inferencial", "description": "Deducir información no explícita del texto", "module": "MOD-02-INFERENCIAL", "skills": ["Inferir causas", "Predecir consecuencias", "Interpretar significados"]},
{"level": 3, "name": "Comprensión Crítica", "description": "Evaluar y juzgar el contenido del texto", "module": "MOD-03-CRITICA", "skills": ["Evaluar argumentos", "Detectar sesgos", "Contrastar fuentes"]},
{"level": 4, "name": "Lectura Digital", "description": "Navegar y evaluar información en medios digitales", "module": "MOD-04-DIGITAL", "skills": ["Verificar fuentes", "Navegar hipertexto", "Evaluar credibilidad"]},
{"level": 5, "name": "Producción Lectora", "description": "Crear textos basados en comprensión profunda", "module": "MOD-05-PRODUCCION", "skills": ["Sintetizar información", "Argumentar posiciones", "Crear contenido"]}
]'::jsonb,
true
)
ON CONFLICT (name) DO UPDATE SET
description = EXCLUDED.description,
levels = EXCLUDED.levels,
is_active = true,
updated_at = gamilit.now_mexico();
RAISE NOTICE '✅ Taxonomía GAMILIT creada/actualizada';
-- =====================================================
-- VERIFICACIÓN
-- =====================================================
RAISE NOTICE '';
RAISE NOTICE '=== TAXONOMÍAS EDUCATIVAS ===';
RAISE NOTICE 'Total taxonomías activas: %', (SELECT COUNT(*) FROM educational_content.taxonomies WHERE is_active = true);
RAISE NOTICE 'Bloom: %', (SELECT COUNT(*) FROM educational_content.taxonomies WHERE taxonomy_type = 'bloom');
RAISE NOTICE 'SOLO: %', (SELECT COUNT(*) FROM educational_content.taxonomies WHERE taxonomy_type = 'solo');
RAISE NOTICE 'Webb DOK: %', (SELECT COUNT(*) FROM educational_content.taxonomies WHERE taxonomy_type = 'webb');
RAISE NOTICE 'Custom (GAMILIT): %', (SELECT COUNT(*) FROM educational_content.taxonomies WHERE taxonomy_type = 'custom');
END $$;
-- =====================================================
-- VERIFICACIÓN FINAL
-- =====================================================
DO $$
DECLARE
v_count INTEGER;
BEGIN
SELECT COUNT(*) INTO v_count FROM educational_content.taxonomies WHERE is_active = true;
IF v_count < 3 THEN
RAISE WARNING '⚠️ Se esperaban al menos 3 taxonomías';
ELSE
RAISE NOTICE '✅ Seed de taxonomies completado exitosamente (%s taxonomías)', v_count;
END IF;
END $$;

View File

@ -63,8 +63,8 @@ INSERT INTO gamification_system.achievements (
'90000001-0000-0000-0000-000000000001'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, -- Tenant principal
'Primeros Pasos',
'Completa tu primer ejercicio de comprensi<EFBFBD>n lectora',
'<<3C>',
'Completa tu primer ejercicio de comprensión lectora',
'footprints',
'progress'::gamification_system.achievement_category,
'common',
'beginner'::educational_content.difficulty_level,
@ -105,8 +105,8 @@ INSERT INTO gamification_system.achievements (
'90000001-0000-0000-0000-000000000002'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Lector Principiante',
'Completa 10 ejercicios de comprensi<EFBFBD>n lectora',
'=<3D>',
'Completa 10 ejercicios de comprensión lectora',
'book-open',
'progress'::gamification_system.achievement_category,
'common',
'elementary'::educational_content.difficulty_level,
@ -146,8 +146,8 @@ INSERT INTO gamification_system.achievements (
'90000001-0000-0000-0000-000000000003'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Lector Experimentado',
'Completa 50 ejercicios de comprensi<EFBFBD>n lectora',
'=<3D>',
'Completa 50 ejercicios de comprensión lectora',
'book-open',
'progress'::gamification_system.achievement_category,
'rare',
'pre_intermediate'::educational_content.difficulty_level,
@ -188,7 +188,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Lector Experto',
'Completa 100 ejercicios de comprensi<73>n lectora',
'<<3C>',
'footprints',
'progress'::gamification_system.achievement_category,
'epic',
'upper_intermediate'::educational_content.difficulty_level,
@ -229,7 +229,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Maestro de la Lectura',
'Completa 200 ejercicios de comprensi<73>n lectora',
'=Q',
'graduation-cap',
'progress'::gamification_system.achievement_category,
'legendary',
'proficient'::educational_content.difficulty_level,
@ -274,7 +274,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Racha de 3 D<>as',
'Mant<EFBFBD>n una racha de 3 d<>as consecutivos practicando',
'=%',
'flame',
'streak'::gamification_system.achievement_category,
'common',
'elementary'::educational_content.difficulty_level,
@ -315,7 +315,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Racha de 7 D<>as',
'Mant<EFBFBD>n una racha de 7 d<>as consecutivos practicando',
'=%=%',
'flame',
'streak'::gamification_system.achievement_category,
'rare',
'pre_intermediate'::educational_content.difficulty_level,
@ -356,7 +356,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Racha de 30 D<>as',
'Mant<EFBFBD>n una racha de 30 d<>as consecutivos practicando',
'=%=%=%',
'flame',
'streak'::gamification_system.achievement_category,
'epic',
'proficient'::educational_content.difficulty_level,
@ -401,7 +401,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Comprensi<EFBFBD>n Literal Dominada',
'Completa todos los ejercicios del M<>dulo 1: Comprensi<73>n Literal',
'',
'brain',
'completion'::gamification_system.achievement_category,
'rare',
'pre_intermediate'::educational_content.difficulty_level,
@ -443,7 +443,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Comprensi<EFBFBD>n Inferencial Dominada',
'Completa todos los ejercicios del M<>dulo 2: Comprensi<73>n Inferencial',
'',
'brain',
'completion'::gamification_system.achievement_category,
'rare',
'pre_intermediate'::educational_content.difficulty_level,
@ -485,7 +485,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Comprensi<EFBFBD>n Cr<43>tica Dominada',
'Completa todos los ejercicios del M<>dulo 3: Comprensi<73>n Cr<43>tica',
'',
'brain',
'completion'::gamification_system.achievement_category,
'epic',
'upper_intermediate'::educational_content.difficulty_level,
@ -527,7 +527,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Completista Total',
'Completa todos los m<>dulos del sistema',
'<<3C>',
'trophy',
'completion'::gamification_system.achievement_category,
'legendary',
'proficient'::educational_content.difficulty_level,
@ -573,7 +573,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Perfeccionista',
'Obt<EFBFBD>n 100% de aciertos en 10 ejercicios',
'P',
'target',
'mastery'::gamification_system.achievement_category,
'rare',
'upper_intermediate'::educational_content.difficulty_level,
@ -615,7 +615,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Experto en Inferencias',
'Completa 20 ejercicios de inferencia con 90% o m<>s de aciertos',
'><3E>',
'brain',
'mastery'::gamification_system.achievement_category,
'epic',
'upper_intermediate'::educational_content.difficulty_level,
@ -659,7 +659,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Cr<EFBFBD>tico Avanzado',
'Completa 20 ejercicios de pensamiento cr<63>tico con 90% o m<>s',
'<<3C>',
'footprints',
'mastery'::gamification_system.achievement_category,
'epic',
'proficient'::educational_content.difficulty_level,
@ -707,7 +707,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Explorador Curioso',
'Explora al menos 3 m<>dulos diferentes',
'= ',
'compass',
'exploration'::gamification_system.achievement_category,
'common',
'elementary'::educational_content.difficulty_level,
@ -749,7 +749,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Aventurero del Conocimiento',
'Completa ejercicios de todos los niveles de dificultad',
'=<3D>',
'compass',
'exploration'::gamification_system.achievement_category,
'rare',
'pre_intermediate'::educational_content.difficulty_level,
@ -795,7 +795,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Compa<EFBFBD>ero de Aula',
'<EFBFBD>nete a tu primera aula virtual',
'=e',
'users',
'social'::gamification_system.achievement_category,
'common',
'beginner'::educational_content.difficulty_level,
@ -836,7 +836,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Estudiante Colaborativo',
'Participa en 5 actividades sociales (aulas, desaf<61>os, etc.)',
'>',
'handshake',
'social'::gamification_system.achievement_category,
'rare',
'pre_intermediate'::educational_content.difficulty_level,
@ -881,7 +881,7 @@ INSERT INTO gamification_system.achievements (
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Primera Visita',
'Inicia sesi<73>n por primera vez en GAMILIT',
'<<3C>',
'footprints',
'special'::gamification_system.achievement_category,
'common',
'beginner'::educational_content.difficulty_level,

View File

@ -0,0 +1,580 @@
-- =====================================================
-- Seed: gamification_system.user_stats (PROD) - v2.0
-- Description: Estadísticas de gamificación para usuarios demo
-- Environment: PRODUCTION
-- Dependencies: auth_management.profiles, gamification_system.maya_ranks
-- Order: 05
-- Created: 2025-01-11
-- Updated: 2025-11-15
-- Version: 2.0 (Refactored - Trigger-based creation)
-- =====================================================
--
-- CAMBIOS v2.0:
-- ============
-- ❌ ELIMINADO: INSERTs directos a user_stats (causaban duplicados y huérfanos)
-- ✅ NUEVO: El trigger initialize_user_stats() crea automáticamente los registros
-- ✅ NUEVO: UPDATEs para agregar progreso variado a los usuarios demo
--
-- FUNCIONAMIENTO:
-- ===============
-- 1. El trigger initialize_user_stats() (en profiles) crea automáticamente:
-- - user_stats con 100 ML Coins iniciales
-- - user_ranks con rango 'Ajaw'
-- - comodines_inventory
--
-- 2. Este seed actualiza los user_stats con progreso variado para demos realistas
--
-- USUARIOS CON PROGRESO VARIADO:
-- ==============================
-- - 5 estudiantes con diferentes niveles (1-4)
-- - 2 profesores con actividad alta
-- - 2 administradores con stats máximos
-- - 1 padre con actividad mínima
--
-- TOTAL: 10 usuarios demo con progreso variado
-- =====================================================
SET search_path TO gamification_system, auth_management, public;
-- =====================================================
-- FASE 1: Verificar que el trigger creó los registros base
-- =====================================================
DO $$
DECLARE
stats_count INTEGER;
expected_count INTEGER;
BEGIN
-- Contar user_stats existentes
SELECT COUNT(*) INTO stats_count
FROM gamification_system.user_stats;
-- Contar perfiles (debería haber 23: 3 testing + 20 demo)
SELECT COUNT(*) INTO expected_count
FROM auth_management.profiles;
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE 'VERIFICACIÓN TRIGGER initialize_user_stats()';
RAISE NOTICE '========================================';
RAISE NOTICE 'Perfiles existentes: %', expected_count;
RAISE NOTICE 'User stats existentes: %', stats_count;
RAISE NOTICE '========================================';
IF stats_count = expected_count THEN
RAISE NOTICE '✓ El trigger funcionó correctamente';
RAISE NOTICE '✓ Todos los perfiles tienen user_stats';
ELSIF stats_count < expected_count THEN
RAISE WARNING '⚠ Faltan % user_stats', expected_count - stats_count;
RAISE WARNING '⚠ Algunos perfiles no tienen user_stats (trigger pudo haber fallado)';
ELSE
RAISE WARNING '⚠ Hay % user_stats extras (posibles huérfanos)', stats_count - expected_count;
END IF;
RAISE NOTICE '';
END $$;
-- =====================================================
-- FASE 2: Actualizar user_stats con progreso variado
-- =====================================================
-- Esto da vida a los usuarios demo con diferentes niveles de actividad
-- Estudiante 1: Ana García - Nivel 2, Progreso Medio
UPDATE gamification_system.user_stats
SET
level = 2,
total_xp = 1250,
xp_to_next_level = 250,
current_rank = 'Ajaw'::gamification_system.maya_rank,
rank_progress = 45.50,
ml_coins = 275,
ml_coins_earned_total = 450,
ml_coins_spent_total = 175,
ml_coins_earned_today = 25,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '3 hours',
current_streak = 3,
max_streak = 5,
streak_started_at = gamilit.now_mexico() - INTERVAL '3 days',
days_active_total = 12,
exercises_completed = 15,
modules_completed = 0,
total_score = 1200,
average_score = 80.00,
perfect_scores = 2,
achievements_earned = 3,
certificates_earned = 0,
total_time_spent = '03:25:00'::interval,
weekly_time_spent = '01:15:00'::interval,
sessions_count = 12,
weekly_xp = 450,
monthly_xp = 1250,
weekly_exercises = 8,
class_rank_position = 1,
last_activity_at = gamilit.now_mexico() - INTERVAL '2 hours',
last_login_at = gamilit.now_mexico() - INTERVAL '2 hours',
metadata = jsonb_build_object(
'demo_user', true,
'preferred_theme', 'ocean',
'favorite_module', 'modulo-01-comprension-literal',
'learning_pace', 'steady'
),
updated_at = gamilit.now_mexico()
WHERE user_id = '01ac4f00-082e-4287-b899-2e169c49b05e'::uuid;
-- Estudiante 2: Carlos Ramírez - Nivel 1, Principiante
UPDATE gamification_system.user_stats
SET
level = 1,
total_xp = 250,
xp_to_next_level = 750,
current_rank = 'Ajaw'::gamification_system.maya_rank,
rank_progress = 12.50,
ml_coins = 150,
ml_coins_earned_total = 200,
ml_coins_spent_total = 50,
ml_coins_earned_today = 10,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '5 hours',
current_streak = 1,
max_streak = 2,
streak_started_at = gamilit.now_mexico() - INTERVAL '1 day',
days_active_total = 5,
exercises_completed = 5,
modules_completed = 0,
total_score = 350,
average_score = 70.00,
perfect_scores = 0,
achievements_earned = 1,
certificates_earned = 0,
total_time_spent = '01:10:00'::interval,
weekly_time_spent = '00:45:00'::interval,
sessions_count = 5,
weekly_xp = 150,
monthly_xp = 250,
weekly_exercises = 3,
class_rank_position = 2,
last_activity_at = gamilit.now_mexico() - INTERVAL '4 hours',
last_login_at = gamilit.now_mexico() - INTERVAL '4 hours',
metadata = jsonb_build_object(
'demo_user', true,
'preferred_theme', 'space',
'learning_pace', 'slow'
),
updated_at = gamilit.now_mexico()
WHERE user_id = '02bc5f00-182e-5387-c899-3f269d49c06f'::uuid;
-- Estudiante 3: María Fernanda - Nivel 3, Avanzada
UPDATE gamification_system.user_stats
SET
level = 3,
total_xp = 3200,
xp_to_next_level = 800,
current_rank = 'Nacom'::gamification_system.maya_rank,
rank_progress = 60.00,
ml_coins = 425,
ml_coins_earned_total = 800,
ml_coins_spent_total = 375,
ml_coins_earned_today = 50,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '2 hours',
current_streak = 7,
max_streak = 7,
streak_started_at = gamilit.now_mexico() - INTERVAL '7 days',
days_active_total = 20,
exercises_completed = 35,
modules_completed = 1,
total_score = 2800,
average_score = 85.00,
perfect_scores = 5,
achievements_earned = 6,
certificates_earned = 1,
total_time_spent = '06:30:00'::interval,
weekly_time_spent = '02:00:00'::interval,
sessions_count = 20,
weekly_xp = 900,
monthly_xp = 3200,
weekly_exercises = 15,
class_rank_position = 1,
last_activity_at = gamilit.now_mexico() - INTERVAL '1 hour',
last_login_at = gamilit.now_mexico() - INTERVAL '1 hour',
metadata = jsonb_build_object(
'demo_user', true,
'preferred_theme', 'forest',
'favorite_module', 'modulo-02-comprension-inferencial',
'learning_pace', 'fast',
'achievement_hunter', true
),
updated_at = gamilit.now_mexico()
WHERE user_id = '03cd6000-282e-6487-d899-40369e49d070'::uuid;
-- Estudiante 4: Luis Miguel - Nivel 2, Progreso Constante
UPDATE gamification_system.user_stats
SET
level = 2,
total_xp = 1400,
xp_to_next_level = 100,
current_rank = 'Ajaw'::gamification_system.maya_rank,
rank_progress = 52.00,
ml_coins = 300,
ml_coins_earned_total = 500,
ml_coins_spent_total = 200,
ml_coins_earned_today = 30,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '4 hours',
current_streak = 4,
max_streak = 6,
streak_started_at = gamilit.now_mexico() - INTERVAL '4 days',
days_active_total = 15,
exercises_completed = 20,
modules_completed = 0,
total_score = 1500,
average_score = 75.00,
perfect_scores = 1,
achievements_earned = 4,
certificates_earned = 0,
total_time_spent = '04:00:00'::interval,
weekly_time_spent = '01:30:00'::interval,
sessions_count = 15,
weekly_xp = 550,
monthly_xp = 1400,
weekly_exercises = 10,
class_rank_position = 2,
last_activity_at = gamilit.now_mexico() - INTERVAL '3 hours',
last_login_at = gamilit.now_mexico() - INTERVAL '3 hours',
metadata = jsonb_build_object(
'demo_user', true,
'preferred_theme', 'detective',
'learning_pace', 'steady'
),
updated_at = gamilit.now_mexico()
WHERE user_id = '04de7000-382e-7587-e899-51469f49e081'::uuid;
-- Estudiante 5: Sofía Martínez - Nivel 4, Muy Avanzada
UPDATE gamification_system.user_stats
SET
level = 4,
total_xp = 6500,
xp_to_next_level = 500,
current_rank = 'Nacom'::gamification_system.maya_rank,
rank_progress = 82.50,
ml_coins = 650,
ml_coins_earned_total = 1200,
ml_coins_spent_total = 550,
ml_coins_earned_today = 75,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '1 hour',
current_streak = 10,
max_streak = 12,
streak_started_at = gamilit.now_mexico() - INTERVAL '10 days',
days_active_total = 30,
exercises_completed = 55,
modules_completed = 2,
total_score = 4800,
average_score = 90.00,
perfect_scores = 10,
achievements_earned = 8,
certificates_earned = 2,
total_time_spent = '10:15:00'::interval,
weekly_time_spent = '03:00:00'::interval,
sessions_count = 30,
weekly_xp = 1500,
monthly_xp = 6500,
weekly_exercises = 25,
class_rank_position = 1,
last_activity_at = gamilit.now_mexico() - INTERVAL '30 minutes',
last_login_at = gamilit.now_mexico() - INTERVAL '30 minutes',
metadata = jsonb_build_object(
'demo_user', true,
'preferred_theme', 'galaxy',
'favorite_module', 'modulo-03-comprension-critica',
'learning_pace', 'very_fast',
'achievement_hunter', true,
'top_performer', true
),
updated_at = gamilit.now_mexico()
WHERE user_id = '05ef8000-482e-8687-f899-62569049f092'::uuid;
-- Profesor 1: Roberto Méndez - Nivel 5, Profesor Activo
UPDATE gamification_system.user_stats
SET
level = 5,
total_xp = 10000,
xp_to_next_level = 2000,
current_rank = 'Ah K''in'::gamification_system.maya_rank,
rank_progress = 33.33,
ml_coins = 1000,
ml_coins_earned_total = 2000,
ml_coins_spent_total = 1000,
ml_coins_earned_today = 0,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '8 hours',
current_streak = 15,
max_streak = 20,
streak_started_at = gamilit.now_mexico() - INTERVAL '15 days',
days_active_total = 60,
exercises_completed = 100,
modules_completed = 5,
total_score = 9000,
average_score = 92.00,
perfect_scores = 25,
achievements_earned = 12,
certificates_earned = 5,
total_time_spent = '25:00:00'::interval,
weekly_time_spent = '05:00:00'::interval,
sessions_count = 60,
weekly_xp = 2500,
monthly_xp = 10000,
weekly_exercises = 30,
last_activity_at = gamilit.now_mexico() - INTERVAL '1 hour',
last_login_at = gamilit.now_mexico() - INTERVAL '1 hour',
metadata = jsonb_build_object(
'demo_user', true,
'role', 'teacher',
'teacher_stats', jsonb_build_object(
'students_count', 10,
'classrooms_count', 2,
'avg_student_score', 85.00
)
),
updated_at = gamilit.now_mexico()
WHERE user_id = '10ac4f00-092e-4297-b909-2e179c49b15e'::uuid;
-- Profesor 2: Laura González - Nivel 5, Profesora Activa
UPDATE gamification_system.user_stats
SET
level = 5,
total_xp = 9500,
xp_to_next_level = 2500,
current_rank = 'Ah K''in'::gamification_system.maya_rank,
rank_progress = 25.00,
ml_coins = 950,
ml_coins_earned_total = 1900,
ml_coins_spent_total = 950,
ml_coins_earned_today = 0,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '10 hours',
current_streak = 12,
max_streak = 18,
streak_started_at = gamilit.now_mexico() - INTERVAL '12 days',
days_active_total = 55,
exercises_completed = 90,
modules_completed = 5,
total_score = 8500,
average_score = 90.00,
perfect_scores = 20,
achievements_earned = 11,
certificates_earned = 5,
total_time_spent = '22:30:00'::interval,
weekly_time_spent = '04:30:00'::interval,
sessions_count = 55,
weekly_xp = 2300,
monthly_xp = 9500,
weekly_exercises = 28,
last_activity_at = gamilit.now_mexico() - INTERVAL '2 hours',
last_login_at = gamilit.now_mexico() - INTERVAL '2 hours',
metadata = jsonb_build_object(
'demo_user', true,
'role', 'teacher',
'teacher_stats', jsonb_build_object(
'students_count', 8,
'classrooms_count', 2,
'avg_student_score', 82.50
)
),
updated_at = gamilit.now_mexico()
WHERE user_id = '11bc5f00-192e-5397-c919-3f279d49c26f'::uuid;
-- Admin 1: Admin Sistema - Nivel 10, Super Admin
UPDATE gamification_system.user_stats
SET
level = 10,
total_xp = 50000,
xp_to_next_level = 0,
current_rank = 'K''uk''ulkan'::gamification_system.maya_rank,
rank_progress = 100.00,
ml_coins = 5000,
ml_coins_earned_total = 10000,
ml_coins_spent_total = 5000,
ml_coins_earned_today = 0,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '12 hours',
current_streak = 30,
max_streak = 30,
streak_started_at = gamilit.now_mexico() - INTERVAL '30 days',
days_active_total = 100,
exercises_completed = 250,
modules_completed = 5,
total_score = 24000,
average_score = 96.00,
perfect_scores = 50,
achievements_earned = 20,
certificates_earned = 5,
total_time_spent = '50:00:00'::interval,
weekly_time_spent = '08:00:00'::interval,
sessions_count = 100,
weekly_xp = 5000,
monthly_xp = 50000,
weekly_exercises = 50,
last_activity_at = gamilit.now_mexico() - INTERVAL '30 minutes',
last_login_at = gamilit.now_mexico() - INTERVAL '30 minutes',
metadata = jsonb_build_object(
'demo_user', true,
'role', 'super_admin',
'admin_access', 'full'
),
updated_at = gamilit.now_mexico()
WHERE user_id = '20ac4f00-002e-4207-b809-2e189c49b25e'::uuid;
-- Admin 2: Directora - Nivel 8, Director
UPDATE gamification_system.user_stats
SET
level = 8,
total_xp = 25000,
xp_to_next_level = 3000,
current_rank = 'Halach Uinic'::gamification_system.maya_rank,
rank_progress = 75.00,
ml_coins = 2500,
ml_coins_earned_total = 5000,
ml_coins_spent_total = 2500,
ml_coins_earned_today = 0,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '14 hours',
current_streak = 20,
max_streak = 25,
streak_started_at = gamilit.now_mexico() - INTERVAL '20 days',
days_active_total = 80,
exercises_completed = 150,
modules_completed = 5,
total_score = 14000,
average_score = 94.00,
perfect_scores = 35,
achievements_earned = 15,
certificates_earned = 5,
total_time_spent = '35:00:00'::interval,
weekly_time_spent = '06:00:00'::interval,
sessions_count = 80,
weekly_xp = 3500,
monthly_xp = 25000,
weekly_exercises = 40,
last_activity_at = gamilit.now_mexico() - INTERVAL '1 hour',
last_login_at = gamilit.now_mexico() - INTERVAL '1 hour',
metadata = jsonb_build_object(
'demo_user', true,
'role', 'director',
'school_id', '50000000-0000-0000-0000-000000000001'
),
updated_at = gamilit.now_mexico()
WHERE user_id = '21bc5f00-102e-5307-c829-3f289d49c36f'::uuid;
-- Padre 1: Jorge García - Nivel 1, Observador
UPDATE gamification_system.user_stats
SET
level = 1,
total_xp = 100,
xp_to_next_level = 900,
current_rank = 'Ajaw'::gamification_system.maya_rank,
rank_progress = 5.00,
ml_coins = 100,
ml_coins_earned_total = 100,
ml_coins_spent_total = 0,
ml_coins_earned_today = 0,
last_ml_coins_reset = gamilit.now_mexico() - INTERVAL '24 hours',
current_streak = 0,
max_streak = 1,
streak_started_at = NULL,
days_active_total = 3,
exercises_completed = 0,
modules_completed = 0,
total_score = 0,
average_score = NULL,
perfect_scores = 0,
achievements_earned = 1,
certificates_earned = 0,
total_time_spent = '00:30:00'::interval,
weekly_time_spent = '00:10:00'::interval,
sessions_count = 3,
weekly_xp = 50,
monthly_xp = 100,
weekly_exercises = 0,
last_activity_at = gamilit.now_mexico() - INTERVAL '1 day',
last_login_at = gamilit.now_mexico() - INTERVAL '1 day',
metadata = jsonb_build_object(
'demo_user', true,
'role', 'parent',
'children_ids', jsonb_build_array('01ac4f00-082e-4287-b899-2e169c49b05e')
),
updated_at = gamilit.now_mexico()
WHERE user_id = '30ac4f00-012e-4217-b819-2e199c49b35e'::uuid;
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
stats_count INTEGER;
updated_count INTEGER;
students_count INTEGER;
teachers_count INTEGER;
admins_count INTEGER;
avg_level NUMERIC;
total_ml_coins INTEGER;
BEGIN
SELECT COUNT(*) INTO stats_count
FROM gamification_system.user_stats;
SELECT COUNT(*) INTO updated_count
FROM gamification_system.user_stats
WHERE metadata->>'demo_user' = 'true' AND level > 1;
SELECT COUNT(*) INTO students_count
FROM gamification_system.user_stats us
JOIN auth_management.profiles p ON p.user_id = us.user_id
WHERE us.metadata->>'demo_user' = 'true' AND p.role = 'student';
SELECT COUNT(*) INTO teachers_count
FROM gamification_system.user_stats us
JOIN auth_management.profiles p ON p.user_id = us.user_id
WHERE us.metadata->>'demo_user' = 'true' AND p.role = 'admin_teacher';
SELECT COUNT(*) INTO admins_count
FROM gamification_system.user_stats us
JOIN auth_management.profiles p ON p.user_id = us.user_id
WHERE us.metadata->>'demo_user' = 'true' AND p.role = 'super_admin';
SELECT AVG(level)::NUMERIC(5,2) INTO avg_level
FROM gamification_system.user_stats
WHERE metadata->>'demo_user' = 'true';
SELECT SUM(ml_coins) INTO total_ml_coins
FROM gamification_system.user_stats
WHERE metadata->>'demo_user' = 'true';
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE 'USER STATS ACTUALIZADOS EXITOSAMENTE';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total user stats: %', stats_count;
RAISE NOTICE 'User stats demo actualizados: %', updated_count;
RAISE NOTICE ' - Estudiantes: %', students_count;
RAISE NOTICE ' - Profesores: %', teachers_count;
RAISE NOTICE ' - Administradores: %', admins_count;
RAISE NOTICE '========================================';
RAISE NOTICE 'Estadísticas Agregadas:';
RAISE NOTICE ' - Nivel promedio: %', avg_level;
RAISE NOTICE ' - ML Coins totales: %', total_ml_coins;
RAISE NOTICE '========================================';
IF updated_count >= 10 THEN
RAISE NOTICE '✓ User stats demo fueron actualizados correctamente con progreso variado';
ELSE
RAISE WARNING '⚠ Se esperaban al menos 10 updates, se aplicaron %', updated_count;
END IF;
RAISE NOTICE '';
END $$;
-- =====================================================
-- Testing Info
-- =====================================================
-- Los user_stats ahora tienen progreso variado realista.
--
-- Para verificar:
-- SELECT display_name, level, total_xp, ml_coins, exercises_completed
-- FROM auth_management.profiles p
-- JOIN gamification_system.user_stats us ON us.user_id = p.user_id
-- WHERE us.metadata->>'demo_user' = 'true'
-- ORDER BY level DESC, total_xp DESC;
-- =====================================================

View File

@ -0,0 +1,468 @@
-- =====================================================
-- Seed: gamification_system.user_ranks (PROD)
-- Description: Rangos maya actuales para usuarios demo
-- Environment: PRODUCTION
-- Dependencies: auth_management.profiles, gamification_system.user_stats
-- Order: 06
-- Created: 2025-01-11
-- Version: 1.0
-- =====================================================
--
-- RANGOS INCLUIDOS:
-- - Ajaw: 4 usuarios (nivel 1-2)
-- - Nacom: 2 usuarios (nivel 3-4)
-- - Ah K'in: 2 usuarios (nivel 5)
-- - Halach Uinic: 1 usuario (nivel 8)
-- - K'uk'ulkan: 1 usuario (nivel 10, max rank)
--
-- TOTAL: 10 user ranks
--
-- IMPORTANTE: Solo se crea el rango actual (is_current = true).
-- El historial de rangos anteriores se creará cuando el usuario suba de rango.
-- =====================================================
SET search_path TO gamification_system, auth_management, public;
-- =====================================================
-- INSERT: User Ranks Demo
-- =====================================================
INSERT INTO gamification_system.user_ranks (
id,
user_id,
tenant_id,
current_rank,
previous_rank,
rank_progress_percentage,
modules_required_for_next,
modules_completed_for_rank,
xp_required_for_next,
xp_earned_for_rank,
ml_coins_bonus,
certificate_url,
badge_url,
achieved_at,
previous_rank_achieved_at,
is_current,
rank_metadata,
created_at,
updated_at
) VALUES
-- =====================================================
-- Estudiante 1: Ana García - Rango Ajaw
-- =====================================================
(
'b0000001-0000-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid, -- Ana García
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Ajaw'::gamification_system.maya_rank,
NULL, -- No hay rango previo (primer rango)
46, -- rank_progress_percentage (46% hacia Nacom)
1, -- modules_required_for_next
0, -- modules_completed_for_rank
1000, -- xp_required_for_next (1000 XP para Nacom)
1250, // xp_earned_for_rank (tiene 1250 XP)
0, -- ml_coins_bonus (Ajaw es gratis)
NULL, -- certificate_url
'/badges/ranks/ajaw.png',
gamilit.now_mexico() - INTERVAL '12 days', -- achieved_at (cuando se registró)
NULL,
true, -- is_current
jsonb_build_object(
'demo_rank', true,
'rank_tier', 1,
'rank_name_es', 'Ajaw'
),
gamilit.now_mexico() - INTERVAL '12 days',
gamilit.now_mexico()
),
-- =====================================================
-- Estudiante 2: Carlos Ramírez - Rango Ajaw
-- =====================================================
(
'b0000001-0000-0000-0000-000000000002'::uuid,
'02bc5f00-182e-5387-c899-3f269d49c06f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Ajaw'::gamification_system.maya_rank,
NULL,
13, -- rank_progress_percentage (13% hacia Nacom)
1,
0,
1000,
250,
0,
NULL,
'/badges/ranks/ajaw.png',
gamilit.now_mexico() - INTERVAL '5 days',
NULL,
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 1,
'rank_name_es', 'Ajaw'
),
gamilit.now_mexico() - INTERVAL '5 days',
gamilit.now_mexico()
),
-- =====================================================
-- Estudiante 3: María Fernanda - Rango Nacom
-- =====================================================
(
'b0000001-0000-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Nacom'::gamification_system.maya_rank,
'Ajaw'::gamification_system.maya_rank, -- Subió de Ajaw a Nacom
60, -- rank_progress_percentage (60% hacia Ah K'in)
2, -- modules_required_for_next
1, -- modules_completed_for_rank (completó Módulo 1)
3000, -- xp_required_for_next (3000 XP para Ah K'in)
3200, -- xp_earned_for_rank
50, -- ml_coins_bonus (bonus por alcanzar Nacom)
'/certificates/ranks/nacom.pdf',
'/badges/ranks/nacom.png',
gamilit.now_mexico() - INTERVAL '10 days', -- achieved_at (hace 10 días)
gamilit.now_mexico() - INTERVAL '20 days', // previous_rank_achieved_at (Ajaw hace 20 días)
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 2,
'rank_name_es', 'Nacom',
'promotion_date', (gamilit.now_mexico() - INTERVAL '10 days')::text
),
gamilit.now_mexico() - INTERVAL '10 days',
gamilit.now_mexico()
),
-- =====================================================
-- Estudiante 4: Luis Miguel - Rango Ajaw
-- =====================================================
(
'b0000001-0000-0000-0000-000000000004'::uuid,
'04de7000-382e-7587-e899-51469f49e081'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Ajaw'::gamification_system.maya_rank,
NULL,
52, -- rank_progress_percentage (52% hacia Nacom)
1,
0,
1000,
1400,
0,
NULL,
'/badges/ranks/ajaw.png',
gamilit.now_mexico() - INTERVAL '15 days',
NULL,
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 1,
'rank_name_es', 'Ajaw'
),
gamilit.now_mexico() - INTERVAL '15 days',
gamilit.now_mexico()
),
-- =====================================================
-- Estudiante 5: Sofía Martínez - Rango Nacom
-- =====================================================
(
'b0000001-0000-0000-0000-000000000005'::uuid,
'05ef8000-482e-8687-f899-62569049f092'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Nacom'::gamification_system.maya_rank,
'Ajaw'::gamification_system.maya_rank,
83, -- rank_progress_percentage (83% hacia Ah K'in, casi lo alcanza!)
2,
2, -- modules_completed_for_rank (completó Módulos 1 y 2)
3000,
6500,
50,
'/certificates/ranks/nacom.pdf',
'/badges/ranks/nacom.png',
gamilit.now_mexico() - INTERVAL '15 days',
gamilit.now_mexico() - INTERVAL '30 days',
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 2,
'rank_name_es', 'Nacom',
'promotion_date', (gamilit.now_mexico() - INTERVAL '15 days')::text,
'near_promotion', true,
'next_rank', 'Ah K''in'
),
gamilit.now_mexico() - INTERVAL '15 days',
gamilit.now_mexico()
),
-- =====================================================
-- Profesor 1: Juan Pérez - Rango Ah K'in
-- =====================================================
(
'b0000001-0000-0000-0000-000000000006'::uuid,
'10ac4f00-092e-4297-b909-2e179c49b15e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Ah K''in'::gamification_system.maya_rank,
'Nacom'::gamification_system.maya_rank,
33, // rank_progress_percentage (33% hacia Halach Uinic)
3,
5, -- modules_completed_for_rank (todos los módulos)
6000, -- xp_required_for_next
10000,
100, -- ml_coins_bonus
'/certificates/ranks/ah_kin.pdf',
'/badges/ranks/ah_kin.png',
gamilit.now_mexico() - INTERVAL '30 days',
gamilit.now_mexico() - INTERVAL '60 days',
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 3,
'rank_name_es', 'Ah K''in',
'role', 'teacher',
'promotion_date', (gamilit.now_mexico() - INTERVAL '30 days')::text
),
gamilit.now_mexico() - INTERVAL '30 days',
gamilit.now_mexico()
),
-- =====================================================
-- Profesor 2: Laura Martínez - Rango Ah K'in
-- =====================================================
(
'b0000001-0000-0000-0000-000000000007'::uuid,
'11bc5f00-192e-5397-c919-3f279d49c26f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Ah K''in'::gamification_system.maya_rank,
'Nacom'::gamification_system.maya_rank,
25, -- rank_progress_percentage (25% hacia Halach Uinic)
3,
5,
6000,
9500,
100,
'/certificates/ranks/ah_kin.pdf',
'/badges/ranks/ah_kin.png',
gamilit.now_mexico() - INTERVAL '28 days',
gamilit.now_mexico() - INTERVAL '55 days',
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 3,
'rank_name_es', 'Ah K''in',
'role', 'teacher',
'promotion_date', (gamilit.now_mexico() - INTERVAL '28 days')::text
),
gamilit.now_mexico() - INTERVAL '28 days',
gamilit.now_mexico()
),
-- =====================================================
-- Admin: Admin Sistema - Rango K'uk'ulkan (MAX)
-- =====================================================
(
'b0000001-0000-0000-0000-000000000008'::uuid,
'20ac4f00-102e-5307-c829-3f289d49c36f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'K''uk''ulkan'::gamification_system.maya_rank,
'Halach Uinic'::gamification_system.maya_rank,
100, -- rank_progress_percentage (100%, max rank)
0, -- No hay siguiente rango
5,
0, -- No hay siguiente XP requerido
50000,
500, -- ml_coins_bonus (bonus máximo)
'/certificates/ranks/kukul kan.pdf',
'/badges/ranks/kukulkan.png',
gamilit.now_mexico() - INTERVAL '50 days',
gamilit.now_mexico() - INTERVAL '100 days',
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 5,
'rank_name_es', 'K''uk''ulkan',
'role', 'super_admin',
'max_rank', true,
'promotion_date', (gamilit.now_mexico() - INTERVAL '50 days')::text
),
gamilit.now_mexico() - INTERVAL '50 days',
gamilit.now_mexico()
),
-- =====================================================
-- Director: Roberto Silva - Rango Halach Uinic
-- =====================================================
(
'b0000001-0000-0000-0000-000000000009'::uuid,
'21bc5f00-102e-5307-c829-3f289d49c36f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Halach Uinic'::gamification_system.maya_rank,
'Ah K''in'::gamification_system.maya_rank,
75, -- rank_progress_percentage (75% hacia K'uk'ulkan)
4,
5,
10000,
25000,
250,
'/certificates/ranks/halach_uinic.pdf',
'/badges/ranks/halach_uinic.png',
gamilit.now_mexico() - INTERVAL '40 days',
gamilit.now_mexico() - INTERVAL '80 days',
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 4,
'rank_name_es', 'Halach Uinic',
'role', 'director',
'promotion_date', (gamilit.now_mexico() - INTERVAL '40 days')::text
),
gamilit.now_mexico() - INTERVAL '40 days',
gamilit.now_mexico()
),
-- =====================================================
-- Padre: Carmen López - Rango Ajaw
-- =====================================================
(
'b0000001-0000-0000-0000-000000000010'::uuid,
'30ac4f00-202e-6307-d839-4f389e49d47g'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Ajaw'::gamification_system.maya_rank,
NULL,
5, -- rank_progress_percentage (5% hacia Nacom)
1,
0,
1000,
100,
0,
NULL,
'/badges/ranks/ajaw.png',
gamilit.now_mexico() - INTERVAL '3 days',
NULL,
true,
jsonb_build_object(
'demo_rank', true,
'rank_tier', 1,
'rank_name_es', 'Ajaw',
'role', 'parent'
),
gamilit.now_mexico() - INTERVAL '3 days',
gamilit.now_mexico()
)
ON CONFLICT (id) DO UPDATE SET
current_rank = EXCLUDED.current_rank,
rank_progress_percentage = EXCLUDED.rank_progress_percentage,
modules_completed_for_rank = EXCLUDED.modules_completed_for_rank,
xp_earned_for_rank = EXCLUDED.xp_earned_for_rank,
is_current = EXCLUDED.is_current,
rank_metadata = EXCLUDED.rank_metadata,
updated_at = gamilit.now_mexico();
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
ranks_count INTEGER;
ajaw_count INTEGER;
nacom_count INTEGER;
ahkin_count INTEGER;
halach_count INTEGER;
kukulkan_count INTEGER;
BEGIN
SELECT COUNT(*) INTO ranks_count
FROM gamification_system.user_ranks
WHERE rank_metadata->>'demo_rank' = 'true'
AND is_current = true;
SELECT COUNT(*) INTO ajaw_count
FROM gamification_system.user_ranks
WHERE current_rank = 'Ajaw' AND is_current = true;
SELECT COUNT(*) INTO nacom_count
FROM gamification_system.user_ranks
WHERE current_rank = 'Nacom' AND is_current = true;
SELECT COUNT(*) INTO ahkin_count
FROM gamification_system.user_ranks
WHERE current_rank = 'Ah K''in' AND is_current = true;
SELECT COUNT(*) INTO halach_count
FROM gamification_system.user_ranks
WHERE current_rank = 'Halach Uinic' AND is_current = true;
SELECT COUNT(*) INTO kukulkan_count
FROM gamification_system.user_ranks
WHERE current_rank = 'K''uk''ulkan' AND is_current = true;
RAISE NOTICE '========================================';
RAISE NOTICE 'USER RANKS DEMO CREADOS EXITOSAMENTE';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total user ranks: %', ranks_count;
RAISE NOTICE ' - Ajaw: %', ajaw_count;
RAISE NOTICE ' - Nacom: %', nacom_count;
RAISE NOTICE ' - Ah K''in: %', ahkin_count;
RAISE NOTICE ' - Halach Uinic: %', halach_count;
RAISE NOTICE ' - K''uk''ulkan: %', kukulkan_count;
RAISE NOTICE '========================================';
IF ranks_count = 10 THEN
RAISE NOTICE ' Todos los user ranks demo fueron creados correctamente';
ELSE
RAISE WARNING '  Se esperaban 10 user ranks, se crearon %', ranks_count;
END IF;
END $$;
-- =====================================================
-- Listado de ranks
-- =====================================================
DO $$
DECLARE
rank_record RECORD;
BEGIN
RAISE NOTICE '';
RAISE NOTICE 'Listado de user ranks demo:';
RAISE NOTICE '========================================';
FOR rank_record IN
SELECT
p.display_name,
p.role,
ur.current_rank,
ur.previous_rank,
ur.rank_progress_percentage,
ur.xp_earned_for_rank,
ur.modules_completed_for_rank
FROM gamification_system.user_ranks ur
JOIN auth_management.profiles p ON p.id = ur.user_id
WHERE ur.rank_metadata->>'demo_rank' = 'true'
AND ur.is_current = true
ORDER BY
CASE ur.current_rank
WHEN 'K''uk''ulkan' THEN 5
WHEN 'Halach Uinic' THEN 4
WHEN 'Ah K''in' THEN 3
WHEN 'Nacom' THEN 2
WHEN 'Ajaw' THEN 1
END DESC,
ur.rank_progress_percentage DESC
LOOP
RAISE NOTICE ' - % [%]', rank_record.display_name, rank_record.role;
RAISE NOTICE ' Rango Actual: % | Anterior: %',
rank_record.current_rank,
COALESCE(rank_record.previous_rank::text, 'N/A');
RAISE NOTICE ' Progreso: %%% | XP: % | Módulos: %',
rank_record.rank_progress_percentage,
rank_record.xp_earned_for_rank,
rank_record.modules_completed_for_rank;
RAISE NOTICE '';
END LOOP;
RAISE NOTICE '========================================';
END $$;

View File

@ -0,0 +1,895 @@
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Seed: ML Coins Transactions (Production Demo Data)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Description: Transacciones de ML Coins para demostraci<63>n del sistema de econom<6F>a
-- Environment: production
-- Dependencies:
-- - auth.users (01-demo-users.sql)
-- - auth_management.profiles (03-profiles.sql)
-- - gamification_system.user_stats (05-user_stats.sql)
-- Execution Order: 7
-- Created: 2025-01-11
-- Version: 1.0.0
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
SET search_path TO gamification_system, public;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 1: Ana Garc<72>a (275 ML Coins actuales, 450 ganados, 175 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Welcome bonus (100 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0001-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'welcome_bonus'::gamification_system.transaction_type, 100,
0, 100, 'Bono de bienvenida al registrarte en GAMILIT',
'profile', '01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
jsonb_build_object('demo_transaction', true, 'category', 'welcome'),
gamilit.now_mexico() - INTERVAL '12 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Ejercicio 1 completado (15 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0002-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_exercise'::gamification_system.transaction_type, 15,
100, 115, 'ML Coins ganados por completar ejercicio de comprensi<73>n literal',
'exercise', 'ex-001'::uuid,
jsonb_build_object('demo_transaction', true, 'exercise_score', 85, 'module', 'M<EFBFBD>DULO 1'),
gamilit.now_mexico() - INTERVAL '11 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Achievement: Primeros Pasos (50 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0003-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_achievement'::gamification_system.transaction_type, 50,
115, 165, 'ML Coins ganados por logro: Primeros Pasos',
'achievement', '90000001-0001-0000-0000-000000000001'::uuid,
jsonb_build_object('demo_transaction', true, 'achievement_name', 'Primeros Pasos'),
gamilit.now_mexico() - INTERVAL '10 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Varios ejercicios completados (185 ML Coins en total)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0004-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_exercise'::gamification_system.transaction_type, 185,
165, 350, 'ML Coins acumulados por completar 14 ejercicios adicionales',
'exercise', NULL,
jsonb_build_object('demo_transaction', true, 'exercises_count', 14, 'module', 'M<EFBFBD>DULO 1'),
gamilit.now_mexico() - INTERVAL '8 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Lupa (30 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0005-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -30,
350, 320, 'Compra de comod<6F>n: Lupa',
'powerup', 'comodin-lupa'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Lupa'),
gamilit.now_mexico() - INTERVAL '7 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Achievement: Racha de 3 d<>as (50 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0006-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_achievement'::gamification_system.transaction_type, 50,
320, 370, 'ML Coins ganados por logro: Racha de 3 D<>as',
'achievement', '90000001-0006-0000-0000-000000000001'::uuid,
jsonb_build_object('demo_transaction', true, 'achievement_name', 'Racha de 3 D<>as'),
gamilit.now_mexico() - INTERVAL '5 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de hint (10 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0007-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_hint'::gamification_system.transaction_type, -10,
370, 360, 'Compra de pista para ejercicio',
'exercise', 'ex-015'::uuid,
jsonb_build_object('demo_transaction', true, 'hint_level', 1),
gamilit.now_mexico() - INTERVAL '4 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Bono diario de streak (25 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0008-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_streak'::gamification_system.transaction_type, 25,
360, 385, 'Bono por mantener racha diaria activa',
NULL, NULL,
jsonb_build_object('demo_transaction', true, 'streak_days', 3),
gamilit.now_mexico() - INTERVAL '3 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Br<42>jula (25 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0009-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -25,
385, 360, 'Compra de comod<6F>n: Br<42>jula',
'powerup', 'comodin-brujula'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Br<EFBFBD>jula'),
gamilit.now_mexico() - INTERVAL '2 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Achievement: Lector Principiante (50 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0010-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_achievement'::gamification_system.transaction_type, 50,
360, 410, 'ML Coins ganados por logro: Lector Principiante',
'achievement', '90000001-0002-0000-0000-000000000001'::uuid,
jsonb_build_object('demo_transaction', true, 'achievement_name', 'Lector Principiante'),
gamilit.now_mexico() - INTERVAL '1 day'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de retry de ejercicio (15 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0011-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_retry'::gamification_system.transaction_type, -15,
410, 395, 'Compra de reintento para ejercicio',
'exercise', 'ex-020'::uuid,
jsonb_build_object('demo_transaction', true, 'retry_number', 1),
gamilit.now_mexico() - INTERVAL '12 hours'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Bono diario (20 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0012-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_daily'::gamification_system.transaction_type, 20,
395, 415, 'Bono diario por iniciar sesi<73>n',
NULL, NULL,
jsonb_build_object('demo_transaction', true, 'consecutive_days', 3),
gamilit.now_mexico() - INTERVAL '6 hours'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de retry adicional (15 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0013-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_retry'::gamification_system.transaction_type, -15,
415, 400, 'Compra de segundo reintento para ejercicio',
'exercise', 'ex-022'::uuid,
jsonb_build_object('demo_transaction', true, 'retry_number', 1),
gamilit.now_mexico() - INTERVAL '4 hours'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Diccionario (25 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0014-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -25,
400, 375, 'Compra de comod<6F>n: Diccionario Contextual',
'powerup', 'comodin-diccionario'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Diccionario Contextual'),
gamilit.now_mexico() - INTERVAL '2 hours'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de hint adicional (10 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0015-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_hint'::gamification_system.transaction_type, -10,
375, 365, 'Compra de pista adicional para ejercicio',
'exercise', 'ex-023'::uuid,
jsonb_build_object('demo_transaction', true, 'hint_level', 2),
gamilit.now_mexico() - INTERVAL '1 hour'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Ajuste de balance para cuadrar (90 ML Coins adicionales de ejercicios)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0016-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_bonus'::gamification_system.transaction_type, 90,
365, 455, 'Bonos acumulados por racha y ejercicios perfectos',
NULL, NULL,
jsonb_build_object('demo_transaction', true, 'bonus_type', 'perfect_scores'),
gamilit.now_mexico() - INTERVAL '30 minutes'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de hint adicional (10 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0017-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_hint'::gamification_system.transaction_type, -10,
455, 445, 'Compra de pista para ejercicio complejo',
'exercise', 'ex-024'::uuid,
jsonb_build_object('demo_transaction', true, 'hint_level', 1),
gamilit.now_mexico() - INTERVAL '15 minutes'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Resaltador (20 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0018-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -20,
445, 425, 'Compra de comod<6F>n: Resaltador',
'powerup', 'comodin-resaltador'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Resaltador'),
gamilit.now_mexico() - INTERVAL '10 minutes'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Bono adicional de racha (50 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0019-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_streak'::gamification_system.transaction_type, 50,
425, 475, 'Bono especial por racha consecutiva de 3 d<>as',
NULL, NULL,
jsonb_build_object('demo_transaction', true, 'streak_days', 3, 'bonus_type', 'milestone'),
gamilit.now_mexico() - INTERVAL '5 minutes'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Organizador (50 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0020-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -50,
475, 425, 'Compra de comod<6F>n: Organizador de Ideas',
'powerup', 'comodin-organizador'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Organizador de Ideas'),
gamilit.now_mexico() - INTERVAL '2 minutes'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Mapa Mental (50 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0021-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -50,
425, 375, 'Compra de comod<6F>n: Mapa Mental',
'powerup', 'comodin-mapa-mental'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Mapa Mental'),
gamilit.now_mexico() - INTERVAL '1 minute'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Ajuste final (balance -100 para llegar a 275)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000001-0022-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'admin_adjustment'::gamification_system.transaction_type, -100,
375, 275, 'Ajuste administrativo de balance (correcci<63>n de sistema)',
NULL, NULL,
jsonb_build_object('demo_transaction', true, 'reason', 'balance_correction'),
gamilit.now_mexico()
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 2: Carlos Ram<61>rez (150 ML Coins actuales, 200 ganados, 50 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Welcome bonus (100 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000002-0001-0000-0000-000000000002'::uuid,
'02bc5f00-192e-5397-c909-3f279d49c26f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'welcome_bonus'::gamification_system.transaction_type, 100,
0, 100, 'Bono de bienvenida al registrarte en GAMILIT',
'profile', '02bc5f00-192e-5397-c909-3f279d49c26f'::uuid,
jsonb_build_object('demo_transaction', true, 'category', 'welcome'),
gamilit.now_mexico() - INTERVAL '8 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Achievement: Primera Visita (50 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000002-0002-0000-0000-000000000002'::uuid,
'02bc5f00-192e-5397-c909-3f279d49c26f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_achievement'::gamification_system.transaction_type, 50,
100, 150, 'ML Coins ganados por logro: Primera Visita',
'achievement', '90000001-0020-0000-0000-000000000001'::uuid,
jsonb_build_object('demo_transaction', true, 'achievement_name', 'Primera Visita'),
gamilit.now_mexico() - INTERVAL '8 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Ejercicios completados (50 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000002-0003-0000-0000-000000000002'::uuid,
'02bc5f00-192e-5397-c909-3f279d49c26f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_exercise'::gamification_system.transaction_type, 50,
150, 200, 'ML Coins ganados por completar 5 ejercicios',
'exercise', NULL,
jsonb_build_object('demo_transaction', true, 'exercises_count', 5, 'module', 'M<EFBFBD>DULO 1'),
gamilit.now_mexico() - INTERVAL '5 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de hint (10 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000002-0004-0000-0000-000000000002'::uuid,
'02bc5f00-192e-5397-c909-3f279d49c26f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_hint'::gamification_system.transaction_type, -10,
200, 190, 'Compra de pista para ejercicio',
'exercise', 'ex-005'::uuid,
jsonb_build_object('demo_transaction', true, 'hint_level', 1),
gamilit.now_mexico() - INTERVAL '4 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Lupa (30 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000002-0005-0000-0000-000000000002'::uuid,
'02bc5f00-192e-5397-c909-3f279d49c26f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -30,
190, 160, 'Compra de comod<6F>n: Lupa',
'powerup', 'comodin-lupa'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Lupa'),
gamilit.now_mexico() - INTERVAL '3 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de hint adicional (10 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000002-0006-0000-0000-000000000002'::uuid,
'02bc5f00-192e-5397-c909-3f279d49c26f'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_hint'::gamification_system.transaction_type, -10,
160, 150, 'Compra de pista adicional para ejercicio',
'exercise', 'ex-006'::uuid,
jsonb_build_object('demo_transaction', true, 'hint_level', 2),
gamilit.now_mexico() - INTERVAL '1 day'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 3: Mar<61>a Fernanda (425 ML Coins, 500 ganados, 75 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Welcome bonus (100 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000003-0001-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'welcome_bonus'::gamification_system.transaction_type, 100,
0, 100, 'Bono de bienvenida al registrarte en GAMILIT',
'profile', '03cd6000-282e-6487-d899-40369e49d070'::uuid,
jsonb_build_object('demo_transaction', true, 'category', 'welcome'),
gamilit.now_mexico() - INTERVAL '15 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Ejercicios M<>dulo 1 (250 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000003-0002-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_exercise'::gamification_system.transaction_type, 250,
100, 350, 'ML Coins ganados por completar 25 ejercicios del M<>dulo 1',
'exercise', NULL,
jsonb_build_object('demo_transaction', true, 'exercises_count', 25, 'module', 'M<EFBFBD>DULO 1'),
gamilit.now_mexico() - INTERVAL '12 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Lupa (30 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000003-0003-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -30,
350, 320, 'Compra de comod<6F>n: Lupa',
'powerup', 'comodin-lupa'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Lupa'),
gamilit.now_mexico() - INTERVAL '11 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Achievement: M<>dulo 1 Completado (100 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000003-0004-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_module'::gamification_system.transaction_type, 100,
320, 420, 'ML Coins ganados por completar M<>dulo 1',
'module', 'modulo-01-comprension-literal'::uuid,
jsonb_build_object('demo_transaction', true, 'module_name', 'M<EFBFBD>DULO 1'),
gamilit.now_mexico() - INTERVAL '10 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Achievement: Racha de 7 d<>as (50 ML Coins)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000003-0005-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'earned_achievement'::gamification_system.transaction_type, 50,
420, 470, 'ML Coins ganados por logro: Racha de 7 D<>as',
'achievement', '90000001-0007-0000-0000-000000000001'::uuid,
jsonb_build_object('demo_transaction', true, 'achievement_name', 'Racha de 7 D<>as'),
gamilit.now_mexico() - INTERVAL '7 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de comod<6F>n: Diccionario (25 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000003-0006-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_powerup'::gamification_system.transaction_type, -25,
470, 445, 'Compra de comod<6F>n: Diccionario Contextual',
'powerup', 'comodin-diccionario'::uuid,
jsonb_build_object('demo_transaction', true, 'powerup_name', 'Diccionario Contextual'),
gamilit.now_mexico() - INTERVAL '6 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de hint (10 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000003-0007-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_hint'::gamification_system.transaction_type, -10,
445, 435, 'Compra de pista para ejercicio del M<>dulo 2',
'exercise', 'ex-026'::uuid,
jsonb_build_object('demo_transaction', true, 'hint_level', 1),
gamilit.now_mexico() - INTERVAL '5 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- Compra de hint adicional (10 ML Coins gastados)
INSERT INTO gamification_system.ml_coins_transactions (
id, user_id, tenant_id, transaction_type, amount,
balance_before, balance_after, description,
related_entity_type, related_entity_id,
metadata, created_at
) VALUES (
'd0000003-0008-0000-0000-000000000003'::uuid,
'03cd6000-282e-6487-d899-40369e49d070'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'spent_hint'::gamification_system.transaction_type, -10,
435, 425, 'Compra de pista adicional para ejercicio del M<>dulo 2',
'exercise', 'ex-027'::uuid,
jsonb_build_object('demo_transaction', true, 'hint_level', 2),
gamilit.now_mexico() - INTERVAL '2 days'
) ON CONFLICT (id) DO UPDATE SET
amount = EXCLUDED.amount,
balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Continuaci<63>n con transacciones m<>s compactas para el resto de usuarios...
-- ESTUDIANTE 4: Luis Miguel (300 ML Coins, 450 ganados, 150 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.ml_coins_transactions
(id, user_id, tenant_id, transaction_type, amount, balance_before, balance_after, description, related_entity_type, related_entity_id, metadata, created_at)
VALUES
('d0000004-0001-0000-0000-000000000004'::uuid, '04de7f00-382e-7497-e919-5h479f49e38h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'welcome_bonus'::gamification_system.transaction_type, 100, 0, 100, 'Bono de bienvenida al registrarte en GAMILIT', 'profile', '04de7f00-382e-7497-e919-5h479f49e38h'::uuid, jsonb_build_object('demo_transaction', true), gamilit.now_mexico() - INTERVAL '14 days'),
('d0000004-0002-0000-0000-000000000004'::uuid, '04de7f00-382e-7497-e919-5h479f49e38h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_exercise'::gamification_system.transaction_type, 200, 100, 300, 'ML Coins por completar 20 ejercicios', 'exercise', NULL, jsonb_build_object('demo_transaction', true, 'exercises_count', 20), gamilit.now_mexico() - INTERVAL '10 days'),
('d0000004-0003-0000-0000-000000000004'::uuid, '04de7f00-382e-7497-e919-5h479f49e38h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_achievement'::gamification_system.transaction_type, 100, 300, 400, 'ML Coins por achievements (Primeros Pasos, Lector Principiante)', 'achievement', NULL, jsonb_build_object('demo_transaction', true, 'achievements_count', 2), gamilit.now_mexico() - INTERVAL '8 days'),
('d0000004-0004-0000-0000-000000000004'::uuid, '04de7f00-382e-7497-e919-5h479f49e38h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_streak'::gamification_system.transaction_type, 50, 400, 450, 'Bonos por racha de 4 d<>as', NULL, NULL, jsonb_build_object('demo_transaction', true, 'streak_days', 4), gamilit.now_mexico() - INTERVAL '4 days'),
('d0000004-0005-0000-0000-000000000004'::uuid, '04de7f00-382e-7497-e919-5h479f49e38h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_powerup'::gamification_system.transaction_type, -80, 450, 370, 'Compra de comodines (Lupa, Br<42>jula, Diccionario)', 'powerup', NULL, jsonb_build_object('demo_transaction', true, 'powerups_count', 3), gamilit.now_mexico() - INTERVAL '3 days'),
('d0000004-0006-0000-0000-000000000004'::uuid, '04de7f00-382e-7497-e919-5h479f49e38h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_hint'::gamification_system.transaction_type, -40, 370, 330, 'Compra de 4 hints', 'exercise', NULL, jsonb_build_object('demo_transaction', true, 'hints_count', 4), gamilit.now_mexico() - INTERVAL '2 days'),
('d0000004-0007-0000-0000-000000000004'::uuid, '04de7f00-382e-7497-e919-5h479f49e38h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_retry'::gamification_system.transaction_type, -30, 330, 300, 'Compra de 2 reintentos', 'exercise', NULL, jsonb_build_object('demo_transaction', true, 'retries_count', 2), gamilit.now_mexico() - INTERVAL '1 day')
ON CONFLICT (id) DO UPDATE SET amount = EXCLUDED.amount, balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 5: Sof<6F>a Mart<72>nez (650 ML Coins, 800 ganados, 150 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.ml_coins_transactions
(id, user_id, tenant_id, transaction_type, amount, balance_before, balance_after, description, related_entity_type, related_entity_id, metadata, created_at)
VALUES
('d0000005-0001-0000-0000-000000000005'::uuid, '05ef8f00-482e-8587-f929-6i589g49f49i'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'welcome_bonus'::gamification_system.transaction_type, 100, 0, 100, 'Bono de bienvenida al registrarte en GAMILIT', 'profile', '05ef8f00-482e-8587-f929-6i589g49f49i'::uuid, jsonb_build_object('demo_transaction', true), gamilit.now_mexico() - INTERVAL '20 days'),
('d0000005-0002-0000-0000-000000000005'::uuid, '05ef8f00-482e-8587-f929-6i589g49f49i'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_exercise'::gamification_system.transaction_type, 500, 100, 600, 'ML Coins por completar 50 ejercicios (M<>dulos 1 y 2)', 'exercise', NULL, jsonb_build_object('demo_transaction', true, 'exercises_count', 50), gamilit.now_mexico() - INTERVAL '15 days'),
('d0000005-0003-0000-0000-000000000005'::uuid, '05ef8f00-482e-8587-f929-6i589g49f49i'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_module'::gamification_system.transaction_type, 200, 600, 800, 'ML Coins por completar 2 m<>dulos (M<>dulo 1 y 2)', 'module', NULL, jsonb_build_object('demo_transaction', true, 'modules_count', 2), gamilit.now_mexico() - INTERVAL '12 days'),
('d0000005-0004-0000-0000-000000000005'::uuid, '05ef8f00-482e-8587-f929-6i589g49f49i'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_powerup'::gamification_system.transaction_type, -120, 800, 680, 'Compra de comodines avanzados', 'powerup', NULL, jsonb_build_object('demo_transaction', true, 'powerups_count', 4), gamilit.now_mexico() - INTERVAL '8 days'),
('d0000005-0005-0000-0000-000000000005'::uuid, '05ef8f00-482e-8587-f929-6i589g49f49i'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_hint'::gamification_system.transaction_type, -30, 680, 650, 'Compra de 3 hints para M<>dulo 3', 'exercise', NULL, jsonb_build_object('demo_transaction', true, 'hints_count', 3), gamilit.now_mexico() - INTERVAL '3 days')
ON CONFLICT (id) DO UPDATE SET amount = EXCLUDED.amount, balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- PROFESOR 1: Juan P<>rez (1000 ML Coins, 1200 ganados, 200 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.ml_coins_transactions
(id, user_id, tenant_id, transaction_type, amount, balance_before, balance_after, description, related_entity_type, related_entity_id, metadata, created_at)
VALUES
('d0000006-0001-0000-0000-000000000006'::uuid, '10ac4f00-092e-4297-b909-2e179c49b15e'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'welcome_bonus'::gamification_system.transaction_type, 100, 0, 100, 'Bono de bienvenida - Profesor', 'profile', '10ac4f00-092e-4297-b909-2e179c49b15e'::uuid, jsonb_build_object('demo_transaction', true), gamilit.now_mexico() - INTERVAL '30 days'),
('d0000006-0002-0000-0000-000000000006'::uuid, '10ac4f00-092e-4297-b909-2e179c49b15e'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_bonus'::gamification_system.transaction_type, 600, 100, 700, 'Bonos por actividades de profesor (creaci<63>n de contenido, evaluaciones)', NULL, NULL, jsonb_build_object('demo_transaction', true, 'bonus_type', 'teacher_activities'), gamilit.now_mexico() - INTERVAL '20 days'),
('d0000006-0003-0000-0000-000000000006'::uuid, '10ac4f00-092e-4297-b909-2e179c49b15e'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_achievement'::gamification_system.transaction_type, 500, 700, 1200, 'ML Coins por achievements de profesor', 'achievement', NULL, jsonb_build_object('demo_transaction', true, 'achievements_count', 5), gamilit.now_mexico() - INTERVAL '15 days'),
('d0000006-0004-0000-0000-000000000006'::uuid, '10ac4f00-092e-4297-b909-2e179c49b15e'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_powerup'::gamification_system.transaction_type, -200, 1200, 1000, 'Compra de herramientas premium para ense<73>anza', 'powerup', NULL, jsonb_build_object('demo_transaction', true, 'tools_purchased', 4), gamilit.now_mexico() - INTERVAL '5 days')
ON CONFLICT (id) DO UPDATE SET amount = EXCLUDED.amount, balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- PROFESOR 2: Laura Mart<72>nez (950 ML Coins, 1150 ganados, 200 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.ml_coins_transactions
(id, user_id, tenant_id, transaction_type, amount, balance_before, balance_after, description, related_entity_type, related_entity_id, metadata, created_at)
VALUES
('d0000007-0001-0000-0000-000000000007'::uuid, '11bc5f00-1a2e-5397-c919-3f289d49c26f'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'welcome_bonus'::gamification_system.transaction_type, 100, 0, 100, 'Bono de bienvenida - Profesora', 'profile', '11bc5f00-1a2e-5397-c919-3f289d49c26f'::uuid, jsonb_build_object('demo_transaction', true), gamilit.now_mexico() - INTERVAL '28 days'),
('d0000007-0002-0000-0000-000000000007'::uuid, '11bc5f00-1a2e-5397-c919-3f289d49c26f'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_bonus'::gamification_system.transaction_type, 550, 100, 650, 'Bonos por actividades de profesora', NULL, NULL, jsonb_build_object('demo_transaction', true, 'bonus_type', 'teacher_activities'), gamilit.now_mexico() - INTERVAL '18 days'),
('d0000007-0003-0000-0000-000000000007'::uuid, '11bc5f00-1a2e-5397-c919-3f289d49c26f'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_achievement'::gamification_system.transaction_type, 500, 650, 1150, 'ML Coins por achievements de profesora', 'achievement', NULL, jsonb_build_object('demo_transaction', true, 'achievements_count', 5), gamilit.now_mexico() - INTERVAL '12 days'),
('d0000007-0004-0000-0000-000000000007'::uuid, '11bc5f00-1a2e-5397-c919-3f289d49c26f'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_powerup'::gamification_system.transaction_type, -200, 1150, 950, 'Compra de herramientas premium para ense<73>anza', 'powerup', NULL, jsonb_build_object('demo_transaction', true, 'tools_purchased', 4), gamilit.now_mexico() - INTERVAL '4 days')
ON CONFLICT (id) DO UPDATE SET amount = EXCLUDED.amount, balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ADMIN: Sistema Admin (5000 ML Coins, 5500 ganados, 500 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.ml_coins_transactions
(id, user_id, tenant_id, transaction_type, amount, balance_before, balance_after, description, related_entity_type, related_entity_id, metadata, created_at)
VALUES
('d0000008-0001-0000-0000-000000000008'::uuid, '20ac4f00-0a2e-6397-d929-4g399e49d37g'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'welcome_bonus'::gamification_system.transaction_type, 100, 0, 100, 'Bono de bienvenida - Admin', 'profile', '20ac4f00-0a2e-6397-d929-4g399e49d37g'::uuid, jsonb_build_object('demo_transaction', true), gamilit.now_mexico() - INTERVAL '60 days'),
('d0000008-0002-0000-0000-000000000008'::uuid, '20ac4f00-0a2e-6397-d929-4g399e49d37g'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_bonus'::gamification_system.transaction_type, 5400, 100, 5500, 'Bonos acumulados por administraci<63>n del sistema', NULL, NULL, jsonb_build_object('demo_transaction', true, 'bonus_type', 'admin_activities'), gamilit.now_mexico() - INTERVAL '30 days'),
('d0000008-0003-0000-0000-000000000008'::uuid, '20ac4f00-0a2e-6397-d929-4g399e49d37g'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_powerup'::gamification_system.transaction_type, -500, 5500, 5000, 'Compra de herramientas de administraci<63>n premium', 'powerup', NULL, jsonb_build_object('demo_transaction', true, 'admin_tools', true), gamilit.now_mexico() - INTERVAL '10 days')
ON CONFLICT (id) DO UPDATE SET amount = EXCLUDED.amount, balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- DIRECTOR: Roberto Director (2500 ML Coins, 2800 ganados, 300 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.ml_coins_transactions
(id, user_id, tenant_id, transaction_type, amount, balance_before, balance_after, description, related_entity_type, related_entity_id, metadata, created_at)
VALUES
('d0000009-0001-0000-0000-000000000009'::uuid, '21bc5f00-1b2e-7497-e939-5h4a9f49e48h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'welcome_bonus'::gamification_system.transaction_type, 100, 0, 100, 'Bono de bienvenida - Director', 'profile', '21bc5f00-1b2e-7497-e939-5h4a9f49e48h'::uuid, jsonb_build_object('demo_transaction', true), gamilit.now_mexico() - INTERVAL '45 days'),
('d0000009-0002-0000-0000-000000000009'::uuid, '21bc5f00-1b2e-7497-e939-5h4a9f49e48h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'earned_bonus'::gamification_system.transaction_type, 2700, 100, 2800, 'Bonos acumulados por gesti<74>n directiva', NULL, NULL, jsonb_build_object('demo_transaction', true, 'bonus_type', 'management_activities'), gamilit.now_mexico() - INTERVAL '25 days'),
('d0000009-0003-0000-0000-000000000009'::uuid, '21bc5f00-1b2e-7497-e939-5h4a9f49e48h'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'spent_powerup'::gamification_system.transaction_type, -300, 2800, 2500, 'Compra de herramientas de gesti<74>n', 'powerup', NULL, jsonb_build_object('demo_transaction', true, 'management_tools', true), gamilit.now_mexico() - INTERVAL '8 days')
ON CONFLICT (id) DO UPDATE SET amount = EXCLUDED.amount, balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- PADRE: Carmen Madre (100 ML Coins, 100 ganados, 0 gastados)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.ml_coins_transactions
(id, user_id, tenant_id, transaction_type, amount, balance_before, balance_after, description, related_entity_type, related_entity_id, metadata, created_at)
VALUES
('d0000010-0001-0000-0000-000000000010'::uuid, '30cd6f00-2c2e-8587-f949-6i5b9g49f59i'::uuid, 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, 'welcome_bonus'::gamification_system.transaction_type, 100, 0, 100, 'Bono de bienvenida - Padre/Madre', 'profile', '30cd6f00-2c2e-8587-f949-6i5b9g49f59i'::uuid, jsonb_build_object('demo_transaction', true), gamilit.now_mexico() - INTERVAL '5 days')
ON CONFLICT (id) DO UPDATE SET amount = EXCLUDED.amount, balance_after = EXCLUDED.balance_after;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- VERIFICACI<43>N DE TRANSACCIONES
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
DO $$
DECLARE
v_transaction_count INTEGER;
v_total_earned INTEGER;
v_total_spent INTEGER;
v_net_balance INTEGER;
BEGIN
-- Contar transacciones insertadas
SELECT COUNT(*) INTO v_transaction_count
FROM gamification_system.ml_coins_transactions
WHERE metadata->>'demo_transaction' = 'true';
-- Calcular totales ganados
SELECT COALESCE(SUM(amount), 0) INTO v_total_earned
FROM gamification_system.ml_coins_transactions
WHERE metadata->>'demo_transaction' = 'true'
AND amount > 0;
-- Calcular totales gastados
SELECT COALESCE(SUM(ABS(amount)), 0) INTO v_total_spent
FROM gamification_system.ml_coins_transactions
WHERE metadata->>'demo_transaction' = 'true'
AND amount < 0;
-- Balance neto
v_net_balance := v_total_earned - v_total_spent;
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
RAISE NOTICE 'ML Coins Transactions - Verificaci<63>n de Seeds';
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
RAISE NOTICE 'Total de transacciones insertadas: %', v_transaction_count;
RAISE NOTICE 'Total ML Coins ganados: % ML Coins', v_total_earned;
RAISE NOTICE 'Total ML Coins gastados: % ML Coins', v_total_spent;
RAISE NOTICE 'Balance neto: % ML Coins', v_net_balance;
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
-- Verificar que tenemos transacciones
IF v_transaction_count = 0 THEN
RAISE WARNING 'No se insertaron transacciones demo';
ELSIF v_transaction_count < 40 THEN
RAISE WARNING 'Se esperaban al menos 40 transacciones, se insertaron %', v_transaction_count;
ELSE
RAISE NOTICE ' Seeds de transacciones ML Coins insertados correctamente';
END IF;
END $$;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- LISTADO DE TRANSACCIONES INSERTADAS (para debugging)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
DO $$
DECLARE
v_user_record RECORD;
BEGIN
RAISE NOTICE '';
RAISE NOTICE 'Resumen de transacciones por usuario:';
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
FOR v_user_record IN (
SELECT
u.email,
p.display_name,
COUNT(t.id) as transaction_count,
COALESCE(SUM(CASE WHEN t.amount > 0 THEN t.amount ELSE 0 END), 0) as total_earned,
COALESCE(SUM(CASE WHEN t.amount < 0 THEN ABS(t.amount) ELSE 0 END), 0) as total_spent,
MAX(t.balance_after) as current_balance
FROM auth.users u
JOIN auth_management.profiles p ON p.user_id = u.id
LEFT JOIN gamification_system.ml_coins_transactions t ON t.user_id = u.id
WHERE t.metadata->>'demo_transaction' = 'true'
GROUP BY u.email, p.display_name
ORDER BY u.email
) LOOP
RAISE NOTICE '% (%): % transacciones | Ganados: % | Gastados: % | Balance: %',
v_user_record.display_name,
v_user_record.email,
v_user_record.transaction_count,
v_user_record.total_earned,
v_user_record.total_spent,
v_user_record.current_balance;
END LOOP;
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
END $$;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- FIN DEL SEED
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP

View File

@ -0,0 +1,434 @@
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Seed: User Achievements (Production Demo Data)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Description: Asociaciones de achievements desbloqueados por usuarios demo
-- Environment: production
-- Dependencies:
-- - auth.users (01-demo-users.sql)
-- - auth_management.profiles (03-profiles.sql)
-- - gamification_system.achievements (04-achievements.sql)
-- - gamification_system.user_stats (05-user_stats.sql)
-- Execution Order: 8
-- Created: 2025-01-11
-- Version: 1.0.0
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
SET search_path TO gamification_system, public;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 1: Ana Garc<72>a (3 achievements)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Primera Visita (completado)
INSERT INTO gamification_system.user_achievements (
id, user_id, achievement_id, progress, max_progress,
is_completed, completion_percentage, completed_at,
notified, viewed, rewards_claimed, rewards_received,
progress_data, milestones_reached, metadata,
started_at, created_at
) VALUES (
'e0000001-0001-0000-0000-000000000001'::uuid,
'2f5a9846-3393-40b2-9e87-0f29238c383f'::uuid,
'90000007-0000-0000-0000-000000000001'::uuid,
1, 1, true, 100.00,
gamilit.now_mexico() - INTERVAL '12 days',
true, true, true,
jsonb_build_object(
'xp', 50,
'ml_coins', 25,
'badge_url', '/badges/achievements/primera-visita.png'
),
jsonb_build_object('first_login', true),
ARRAY['first_login'],
jsonb_build_object('demo_achievement', true, 'category', 'special'),
gamilit.now_mexico() - INTERVAL '12 days',
gamilit.now_mexico() - INTERVAL '12 days'
) ON CONFLICT (user_id, achievement_id) DO UPDATE SET
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- Primeros Pasos (completado)
INSERT INTO gamification_system.user_achievements (
id, user_id, achievement_id, progress, max_progress,
is_completed, completion_percentage, completed_at,
notified, viewed, rewards_claimed, rewards_received,
progress_data, milestones_reached, metadata,
started_at, created_at
) VALUES (
'e0000001-0002-0000-0000-000000000001'::uuid,
'2f5a9846-3393-40b2-9e87-0f29238c383f'::uuid,
'90000001-0000-0000-0000-000000000001'::uuid,
1, 1, true, 100.00,
gamilit.now_mexico() - INTERVAL '10 days',
true, true, true,
jsonb_build_object(
'xp', 100,
'ml_coins', 50,
'badge_url', '/badges/achievements/primeros-pasos.png'
),
jsonb_build_object('exercises_completed', 1),
ARRAY['first_exercise'],
jsonb_build_object('demo_achievement', true, 'category', 'progress'),
gamilit.now_mexico() - INTERVAL '11 days',
gamilit.now_mexico() - INTERVAL '10 days'
) ON CONFLICT (user_id, achievement_id) DO UPDATE SET
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- Racha de 3 D<>as (completado)
INSERT INTO gamification_system.user_achievements (
id, user_id, achievement_id, progress, max_progress,
is_completed, completion_percentage, completed_at,
notified, viewed, rewards_claimed, rewards_received,
progress_data, milestones_reached, metadata,
started_at, created_at
) VALUES (
'e0000001-0003-0000-0000-000000000001'::uuid,
'2f5a9846-3393-40b2-9e87-0f29238c383f'::uuid,
'90000002-0000-0000-0000-000000000001'::uuid,
3, 3, true, 100.00,
gamilit.now_mexico() - INTERVAL '5 days',
true, true, true,
jsonb_build_object(
'xp', 150,
'ml_coins', 50,
'badge_url', '/badges/achievements/racha-3-dias.png'
),
jsonb_build_object('streak_days', 3),
ARRAY['day_1', 'day_2', 'day_3'],
jsonb_build_object('demo_achievement', true, 'category', 'streak'),
gamilit.now_mexico() - INTERVAL '7 days',
gamilit.now_mexico() - INTERVAL '5 days'
) ON CONFLICT (user_id, achievement_id) DO UPDATE SET
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- Lector Principiante (en progreso 60%)
INSERT INTO gamification_system.user_achievements (
id, user_id, achievement_id, progress, max_progress,
is_completed, completion_percentage, completed_at,
notified, viewed, rewards_claimed, rewards_received,
progress_data, milestones_reached, metadata,
started_at, created_at
) VALUES (
'e0000001-0004-0000-0000-000000000001'::uuid,
'2f5a9846-3393-40b2-9e87-0f29238c383f'::uuid,
'90000001-0000-0000-0000-000000000002'::uuid,
15, 25, false, 60.00, NULL,
false, false, false, '{}'::jsonb,
jsonb_build_object('exercises_completed', 15, 'target', 25),
ARRAY['milestone_10'],
jsonb_build_object('demo_achievement', true, 'category', 'progress', 'status', 'in_progress'),
gamilit.now_mexico() - INTERVAL '10 days',
gamilit.now_mexico() - INTERVAL '10 days'
) ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 2: Carlos Ram<61>rez (1 achievement)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Primera Visita (completado)
INSERT INTO gamification_system.user_achievements (
id, user_id, achievement_id, progress, max_progress,
is_completed, completion_percentage, completed_at,
notified, viewed, rewards_claimed, rewards_received,
progress_data, milestones_reached, metadata,
started_at, created_at
) VALUES (
'e0000002-0001-0000-0000-000000000002'::uuid,
'7a6a973e-83f7-4374-a9fc-54258138115f'::uuid,
'90000007-0000-0000-0000-000000000001'::uuid,
1, 1, true, 100.00,
gamilit.now_mexico() - INTERVAL '8 days',
true, true, true,
jsonb_build_object(
'xp', 50,
'ml_coins', 25,
'badge_url', '/badges/achievements/primera-visita.png'
),
jsonb_build_object('first_login', true),
ARRAY['first_login'],
jsonb_build_object('demo_achievement', true, 'category', 'special'),
gamilit.now_mexico() - INTERVAL '8 days',
gamilit.now_mexico() - INTERVAL '8 days'
) ON CONFLICT (user_id, achievement_id) DO UPDATE SET
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- Primeros Pasos (en progreso 20%)
INSERT INTO gamification_system.user_achievements (
id, user_id, achievement_id, progress, max_progress,
is_completed, completion_percentage, completed_at,
notified, viewed, rewards_claimed, rewards_received,
progress_data, milestones_reached, metadata,
started_at, created_at
) VALUES (
'e0000002-0002-0000-0000-000000000002'::uuid,
'7a6a973e-83f7-4374-a9fc-54258138115f'::uuid,
'90000001-0000-0000-0000-000000000001'::uuid,
5, 25, false, 20.00, NULL,
false, false, false, '{}'::jsonb,
jsonb_build_object('exercises_completed', 5, 'target', 25),
ARRAY[]::text[],
jsonb_build_object('demo_achievement', true, 'category', 'progress', 'status', 'in_progress'),
gamilit.now_mexico() - INTERVAL '8 days',
gamilit.now_mexico() - INTERVAL '8 days'
) ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 3: Mar<61>a Fernanda (5+ achievements - m<>dulo 1 completado)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.user_achievements
(id, user_id, achievement_id, progress, max_progress, is_completed, completion_percentage, completed_at, notified, viewed, rewards_claimed, rewards_received, progress_data, milestones_reached, metadata, started_at, created_at)
VALUES
-- Primera Visita
('e0000003-0001-0000-0000-000000000003'::uuid, '00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid, '90000007-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '15 days', true, true, true, jsonb_build_object('xp', 50, 'ml_coins', 25), jsonb_build_object('first_login', true), ARRAY['first_login'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '15 days', gamilit.now_mexico() - INTERVAL '15 days'),
-- Primeros Pasos
('e0000003-0002-0000-0000-000000000003'::uuid, '00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid, '90000001-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '14 days', true, true, true, jsonb_build_object('xp', 100, 'ml_coins', 50), jsonb_build_object('exercises_completed', 1), ARRAY['first_exercise'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '14 days', gamilit.now_mexico() - INTERVAL '14 days'),
-- Lector Principiante
('e0000003-0003-0000-0000-000000000003'::uuid, '00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid, '90000001-0000-0000-0000-000000000002'::uuid, 25, 25, true, 100.00, gamilit.now_mexico() - INTERVAL '12 days', true, true, true, jsonb_build_object('xp', 200, 'ml_coins', 75), jsonb_build_object('exercises_completed', 25), ARRAY['milestone_10', 'milestone_20', 'milestone_25'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '13 days', gamilit.now_mexico() - INTERVAL '12 days'),
-- Racha de 7 D<>as
('e0000003-0004-0000-0000-000000000003'::uuid, '00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid, '90000002-0000-0000-0000-000000000002'::uuid, 7, 7, true, 100.00, gamilit.now_mexico() - INTERVAL '7 days', true, true, true, jsonb_build_object('xp', 300, 'ml_coins', 100), jsonb_build_object('streak_days', 7), ARRAY['day_3', 'day_5', 'day_7'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '10 days', gamilit.now_mexico() - INTERVAL '7 days'),
-- M<>dulo 1 Completado
('e0000003-0005-0000-0000-000000000003'::uuid, '00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid, '90000003-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '10 days', true, true, true, jsonb_build_object('xp', 500, 'ml_coins', 150, 'certificate_url', '/certificates/modules/modulo-1.pdf'), jsonb_build_object('module_completed', 'modulo-01', 'score', 88), ARRAY['module_1_completed'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '12 days', gamilit.now_mexico() - INTERVAL '10 days'),
-- Lector Experimentado (en progreso 40% por M<>dulo 2)
('e0000003-0006-0000-0000-000000000003'::uuid, '00c742d9-e5f7-4666-9597-5a8ca54d5478'::uuid, '90000001-0000-0000-0000-000000000003'::uuid, 35, 100, false, 35.00, NULL, false, false, false, '{}'::jsonb, jsonb_build_object('exercises_completed', 35, 'target', 100), ARRAY['milestone_25'], jsonb_build_object('demo_achievement', true, 'status', 'in_progress'), gamilit.now_mexico() - INTERVAL '12 days', gamilit.now_mexico() - INTERVAL '10 days')
ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 4: Luis Miguel (2 achievements)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.user_achievements
(id, user_id, achievement_id, progress, max_progress, is_completed, completion_percentage, completed_at, notified, viewed, rewards_claimed, rewards_received, progress_data, milestones_reached, metadata, started_at, created_at)
VALUES
-- Primera Visita
('e0000004-0001-0000-0000-000000000004'::uuid, '33306a65-a3b1-41d5-a49d-47989957b822'::uuid, '90000007-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '14 days', true, true, true, jsonb_build_object('xp', 50, 'ml_coins', 25), jsonb_build_object('first_login', true), ARRAY['first_login'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '14 days', gamilit.now_mexico() - INTERVAL '14 days'),
-- Primeros Pasos
('e0000004-0002-0000-0000-000000000004'::uuid, '33306a65-a3b1-41d5-a49d-47989957b822'::uuid, '90000001-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '13 days', true, true, true, jsonb_build_object('xp', 100, 'ml_coins', 50), jsonb_build_object('exercises_completed', 1), ARRAY['first_exercise'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '13 days', gamilit.now_mexico() - INTERVAL '13 days'),
-- Lector Principiante (en progreso 80%)
('e0000004-0003-0000-0000-000000000004'::uuid, '33306a65-a3b1-41d5-a49d-47989957b822'::uuid, '90000001-0000-0000-0000-000000000002'::uuid, 20, 25, false, 80.00, NULL, false, false, false, '{}'::jsonb, jsonb_build_object('exercises_completed', 20, 'target', 25), ARRAY['milestone_10', 'milestone_20'], jsonb_build_object('demo_achievement', true, 'status', 'in_progress'), gamilit.now_mexico() - INTERVAL '12 days', gamilit.now_mexico() - INTERVAL '12 days')
ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 5: Sof<6F>a Mart<72>nez (8+ achievements - 2 m<>dulos completados, mastery)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.user_achievements
(id, user_id, achievement_id, progress, max_progress, is_completed, completion_percentage, completed_at, notified, viewed, rewards_claimed, rewards_received, progress_data, milestones_reached, metadata, started_at, created_at)
VALUES
-- Primera Visita
('e0000005-0001-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000007-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '20 days', true, true, true, jsonb_build_object('xp', 50, 'ml_coins', 25), jsonb_build_object('first_login', true), ARRAY['first_login'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '20 days', gamilit.now_mexico() - INTERVAL '20 days'),
-- Primeros Pasos
('e0000005-0002-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000001-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '19 days', true, true, true, jsonb_build_object('xp', 100, 'ml_coins', 50), jsonb_build_object('exercises_completed', 1), ARRAY['first_exercise'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '19 days', gamilit.now_mexico() - INTERVAL '19 days'),
-- Lector Principiante
('e0000005-0003-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000001-0000-0000-0000-000000000002'::uuid, 25, 25, true, 100.00, gamilit.now_mexico() - INTERVAL '18 days', true, true, true, jsonb_build_object('xp', 200, 'ml_coins', 75), jsonb_build_object('exercises_completed', 25), ARRAY['milestone_10', 'milestone_20', 'milestone_25'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '19 days', gamilit.now_mexico() - INTERVAL '18 days'),
-- Lector Experimentado
('e0000005-0004-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000001-0000-0000-0000-000000000003'::uuid, 50, 100, true, 100.00, gamilit.now_mexico() - INTERVAL '15 days', true, true, true, jsonb_build_object('xp', 400, 'ml_coins', 125), jsonb_build_object('exercises_completed', 50), ARRAY['milestone_25', 'milestone_50', 'milestone_75', 'milestone_100'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '18 days', gamilit.now_mexico() - INTERVAL '15 days'),
-- Racha de 7 D<>as
('e0000005-0005-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000002-0000-0000-0000-000000000002'::uuid, 7, 7, true, 100.00, gamilit.now_mexico() - INTERVAL '14 days', true, true, true, jsonb_build_object('xp', 300, 'ml_coins', 100), jsonb_build_object('streak_days', 7), ARRAY['day_3', 'day_5', 'day_7'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '16 days', gamilit.now_mexico() - INTERVAL '14 days'),
-- M<>dulo 1 Completado
('e0000005-0006-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000003-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '16 days', true, true, true, jsonb_build_object('xp', 500, 'ml_coins', 150, 'certificate_url', '/certificates/modules/modulo-1.pdf'), jsonb_build_object('module_completed', 'modulo-01', 'score', 96), ARRAY['module_1_completed'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '18 days', gamilit.now_mexico() - INTERVAL '16 days'),
-- M<>dulo 2 Completado
('e0000005-0007-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000003-0000-0000-0000-000000000002'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '12 days', true, true, true, jsonb_build_object('xp', 500, 'ml_coins', 150, 'certificate_url', '/certificates/modules/modulo-2.pdf'), jsonb_build_object('module_completed', 'modulo-02', 'score', 90), ARRAY['module_2_completed'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '14 days', gamilit.now_mexico() - INTERVAL '12 days'),
-- Perfeccionista
('e0000005-0008-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000004-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '16 days', true, true, true, jsonb_build_object('xp', 750, 'ml_coins', 250), jsonb_build_object('perfect_score_module', 'modulo-01'), ARRAY['perfect_module'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '16 days', gamilit.now_mexico() - INTERVAL '16 days'),
-- Explorador Curioso (completado)
('e0000005-0009-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000005-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '18 days', true, true, true, jsonb_build_object('xp', 100, 'ml_coins', 50), jsonb_build_object('modules_explored', 3), ARRAY['explore_module_1', 'explore_module_2', 'explore_module_3'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '18 days', gamilit.now_mexico() - INTERVAL '18 days'),
-- Lector Experto (en progreso 55%)
('e0000005-0010-0000-0000-000000000005'::uuid, 'cccccccc-cccc-cccc-cccc-cccccccccccc'::uuid, '90000001-0000-0000-0000-000000000004'::uuid, 55, 100, false, 55.00, NULL, false, false, false, '{}'::jsonb, jsonb_build_object('exercises_completed', 55, 'target', 200), ARRAY['milestone_25', 'milestone_50'], jsonb_build_object('demo_achievement', true, 'status', 'in_progress'), gamilit.now_mexico() - INTERVAL '15 days', gamilit.now_mexico() - INTERVAL '12 days')
ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- PROFESOR 1: Juan P<>rez (5 achievements de profesor)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.user_achievements
(id, user_id, achievement_id, progress, max_progress, is_completed, completion_percentage, completed_at, notified, viewed, rewards_claimed, rewards_received, progress_data, milestones_reached, metadata, started_at, created_at)
VALUES
-- Primera Visita
('e0000006-0001-0000-0000-000000000006'::uuid, 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid, '90000007-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '30 days', true, true, true, jsonb_build_object('xp', 50, 'ml_coins', 25), jsonb_build_object('first_login', true), ARRAY['first_login'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '30 days', gamilit.now_mexico() - INTERVAL '30 days'),
-- Racha de 7 D<>as
('e0000006-0002-0000-0000-000000000006'::uuid, 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid, '90000002-0000-0000-0000-000000000002'::uuid, 7, 7, true, 100.00, gamilit.now_mexico() - INTERVAL '22 days', true, true, true, jsonb_build_object('xp', 300, 'ml_coins', 100), jsonb_build_object('streak_days', 7), ARRAY['day_3', 'day_5', 'day_7'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '25 days', gamilit.now_mexico() - INTERVAL '22 days'),
-- Racha de 30 D<>as (en progreso 50%)
('e0000006-0003-0000-0000-000000000006'::uuid, 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid, '90000002-0000-0000-0000-000000000003'::uuid, 15, 30, false, 50.00, NULL, false, false, false, '{}'::jsonb, jsonb_build_object('streak_days', 15, 'target', 30), ARRAY['day_7', 'day_14'], jsonb_build_object('demo_achievement', true, 'status', 'in_progress'), gamilit.now_mexico() - INTERVAL '30 days', gamilit.now_mexico() - INTERVAL '15 days'),
-- Compa<70>ero de Aula
('e0000006-0004-0000-0000-000000000006'::uuid, 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid, '90000006-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '28 days', true, true, true, jsonb_build_object('xp', 200, 'ml_coins', 75), jsonb_build_object('classroom_joined', true), ARRAY['join_classroom'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '28 days', gamilit.now_mexico() - INTERVAL '28 days'),
-- Estudiante Colaborativo
('e0000006-0005-0000-0000-000000000006'::uuid, 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid, '90000006-0000-0000-0000-000000000002'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '25 days', true, true, true, jsonb_build_object('xp', 300, 'ml_coins', 100), jsonb_build_object('collaborations', 10), ARRAY['collab_5', 'collab_10'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '26 days', gamilit.now_mexico() - INTERVAL '25 days')
ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- PROFESOR 2: Laura Mart<72>nez (5 achievements de profesora)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.user_achievements
(id, user_id, achievement_id, progress, max_progress, is_completed, completion_percentage, completed_at, notified, viewed, rewards_claimed, rewards_received, progress_data, milestones_reached, metadata, started_at, created_at)
VALUES
-- Primera Visita
('e0000007-0001-0000-0000-000000000007'::uuid, '9951ad75-e9cb-47b3-b478-6bb860ee2530'::uuid, '90000007-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '28 days', true, true, true, jsonb_build_object('xp', 50, 'ml_coins', 25), jsonb_build_object('first_login', true), ARRAY['first_login'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '28 days', gamilit.now_mexico() - INTERVAL '28 days'),
-- Racha de 7 D<>as
('e0000007-0002-0000-0000-000000000007'::uuid, '9951ad75-e9cb-47b3-b478-6bb860ee2530'::uuid, '90000002-0000-0000-0000-000000000002'::uuid, 7, 7, true, 100.00, gamilit.now_mexico() - INTERVAL '20 days', true, true, true, jsonb_build_object('xp', 300, 'ml_coins', 100), jsonb_build_object('streak_days', 7), ARRAY['day_3', 'day_5', 'day_7'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '23 days', gamilit.now_mexico() - INTERVAL '20 days'),
-- Racha de 30 D<>as (en progreso 40%)
('e0000007-0003-0000-0000-000000000007'::uuid, '9951ad75-e9cb-47b3-b478-6bb860ee2530'::uuid, '90000002-0000-0000-0000-000000000003'::uuid, 12, 30, false, 40.00, NULL, false, false, false, '{}'::jsonb, jsonb_build_object('streak_days', 12, 'target', 30), ARRAY['day_7'], jsonb_build_object('demo_achievement', true, 'status', 'in_progress'), gamilit.now_mexico() - INTERVAL '28 days', gamilit.now_mexico() - INTERVAL '16 days'),
-- Compa<70>ero de Aula
('e0000007-0004-0000-0000-000000000007'::uuid, '9951ad75-e9cb-47b3-b478-6bb860ee2530'::uuid, '90000006-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '26 days', true, true, true, jsonb_build_object('xp', 200, 'ml_coins', 75), jsonb_build_object('classroom_joined', true), ARRAY['join_classroom'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '26 days', gamilit.now_mexico() - INTERVAL '26 days'),
-- Estudiante Colaborativo
('e0000007-0005-0000-0000-000000000007'::uuid, '9951ad75-e9cb-47b3-b478-6bb860ee2530'::uuid, '90000006-0000-0000-0000-000000000002'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '23 days', true, true, true, jsonb_build_object('xp', 300, 'ml_coins', 100), jsonb_build_object('collaborations', 10), ARRAY['collab_5', 'collab_10'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '24 days', gamilit.now_mexico() - INTERVAL '23 days')
ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ADMIN: Sistema Admin (10+ achievements - usuario avanzado)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.user_achievements
(id, user_id, achievement_id, progress, max_progress, is_completed, completion_percentage, completed_at, notified, viewed, rewards_claimed, rewards_received, progress_data, milestones_reached, metadata, started_at, created_at)
VALUES
-- Primera Visita
('e0000008-0001-0000-0000-000000000008'::uuid, 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid, '90000007-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '60 days', true, true, true, jsonb_build_object('xp', 50, 'ml_coins', 25), jsonb_build_object('first_login', true), ARRAY['first_login'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '60 days', gamilit.now_mexico() - INTERVAL '60 days'),
-- Racha de 30 D<>as
('e0000008-0002-0000-0000-000000000008'::uuid, 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid, '90000002-0000-0000-0000-000000000003'::uuid, 30, 30, true, 100.00, gamilit.now_mexico() - INTERVAL '30 days', true, true, true, jsonb_build_object('xp', 1000, 'ml_coins', 300), jsonb_build_object('streak_days', 30), ARRAY['day_7', 'day_14', 'day_21', 'day_30'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '60 days', gamilit.now_mexico() - INTERVAL '30 days'),
-- Maestro de la Lectura
('e0000008-0003-0000-0000-000000000008'::uuid, 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid, '90000001-0000-0000-0000-000000000005'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '35 days', true, true, true, jsonb_build_object('xp', 1500, 'ml_coins', 500, 'badge_url', '/badges/achievements/maestro-lectura.png'), jsonb_build_object('exercises_completed', 500), ARRAY['master_level'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '40 days', gamilit.now_mexico() - INTERVAL '35 days'),
-- Completista Total
('e0000008-0004-0000-0000-000000000008'::uuid, 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid, '90000003-0000-0000-0000-000000000004'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '32 days', true, true, true, jsonb_build_object('xp', 2000, 'ml_coins', 750, 'certificate_url', '/certificates/all-modules-completed.pdf'), jsonb_build_object('all_modules_completed', true), ARRAY['all_modules'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '35 days', gamilit.now_mexico() - INTERVAL '32 days')
ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- DIRECTOR: Roberto Director (6 achievements)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.user_achievements
(id, user_id, achievement_id, progress, max_progress, is_completed, completion_percentage, completed_at, notified, viewed, rewards_claimed, rewards_received, progress_data, milestones_reached, metadata, started_at, created_at)
VALUES
-- Primera Visita
('e0000009-0001-0000-0000-000000000009'::uuid, '735235f5-260a-4c9b-913c-14a1efd083ea'::uuid, '90000007-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '45 days', true, true, true, jsonb_build_object('xp', 50, 'ml_coins', 25), jsonb_build_object('first_login', true), ARRAY['first_login'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '45 days', gamilit.now_mexico() - INTERVAL '45 days'),
-- Racha de 30 D<>as (en progreso 67%)
('e0000009-0002-0000-0000-000000000009'::uuid, '735235f5-260a-4c9b-913c-14a1efd083ea'::uuid, '90000002-0000-0000-0000-000000000003'::uuid, 20, 30, false, 66.67, NULL, false, false, false, '{}'::jsonb, jsonb_build_object('streak_days', 20, 'target', 30), ARRAY['day_7', 'day_14'], jsonb_build_object('demo_achievement', true, 'status', 'in_progress'), gamilit.now_mexico() - INTERVAL '45 days', gamilit.now_mexico() - INTERVAL '25 days'),
-- Compa<70>ero de Aula
('e0000009-0003-0000-0000-000000000009'::uuid, '735235f5-260a-4c9b-913c-14a1efd083ea'::uuid, '90000006-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '40 days', true, true, true, jsonb_build_object('xp', 200, 'ml_coins', 75), jsonb_build_object('classroom_joined', true), ARRAY['join_classroom'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '40 days', gamilit.now_mexico() - INTERVAL '40 days')
ON CONFLICT (user_id, achievement_id) DO UPDATE SET
progress = EXCLUDED.progress,
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- PADRE: Carmen Madre (1 achievement)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.user_achievements
(id, user_id, achievement_id, progress, max_progress, is_completed, completion_percentage, completed_at, notified, viewed, rewards_claimed, rewards_received, progress_data, milestones_reached, metadata, started_at, created_at)
VALUES
-- Primera Visita
('e0000010-0001-0000-0000-000000000010'::uuid, '5e738038-1743-4aa9-b222-30171300ea9d'::uuid, '90000007-0000-0000-0000-000000000001'::uuid, 1, 1, true, 100.00, gamilit.now_mexico() - INTERVAL '5 days', true, false, false, jsonb_build_object('xp', 50, 'ml_coins', 25), jsonb_build_object('first_login', true), ARRAY['first_login'], jsonb_build_object('demo_achievement', true), gamilit.now_mexico() - INTERVAL '5 days', gamilit.now_mexico() - INTERVAL '5 days')
ON CONFLICT (user_id, achievement_id) DO UPDATE SET
is_completed = EXCLUDED.is_completed,
completion_percentage = EXCLUDED.completion_percentage;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- VERIFICACI<43>N DE USER ACHIEVEMENTS
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
DO $$
DECLARE
v_achievement_count INTEGER;
v_completed_count INTEGER;
v_in_progress_count INTEGER;
BEGIN
-- Contar user achievements insertados
SELECT COUNT(*) INTO v_achievement_count
FROM gamification_system.user_achievements
WHERE metadata->>'demo_achievement' = 'true';
-- Contar completados
SELECT COUNT(*) INTO v_completed_count
FROM gamification_system.user_achievements
WHERE metadata->>'demo_achievement' = 'true'
AND is_completed = true;
-- Contar en progreso
SELECT COUNT(*) INTO v_in_progress_count
FROM gamification_system.user_achievements
WHERE metadata->>'demo_achievement' = 'true'
AND is_completed = false;
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
RAISE NOTICE 'User Achievements - Verificaci<63>n de Seeds';
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
RAISE NOTICE 'Total de user achievements insertados: %', v_achievement_count;
RAISE NOTICE 'Achievements completados: %', v_completed_count;
RAISE NOTICE 'Achievements en progreso: %', v_in_progress_count;
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
-- Verificar que tenemos achievements
IF v_achievement_count = 0 THEN
RAISE WARNING 'No se insertaron user achievements demo';
ELSIF v_achievement_count < 35 THEN
RAISE WARNING 'Se esperaban al menos 35 user achievements, se insertaron %', v_achievement_count;
ELSE
RAISE NOTICE ' Seeds de user achievements insertados correctamente';
END IF;
END $$;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- LISTADO DE USER ACHIEVEMENTS INSERTADOS (para debugging)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
DO $$
DECLARE
v_user_record RECORD;
BEGIN
RAISE NOTICE '';
RAISE NOTICE 'Resumen de achievements por usuario:';
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
FOR v_user_record IN (
SELECT
u.email,
p.display_name,
COUNT(ua.id) as total_achievements,
COUNT(CASE WHEN ua.is_completed THEN 1 END) as completed,
COUNT(CASE WHEN NOT ua.is_completed THEN 1 END) as in_progress
FROM auth.users u
JOIN auth_management.profiles p ON p.user_id = u.id
LEFT JOIN gamification_system.user_achievements ua ON ua.user_id = p.id
WHERE ua.metadata->>'demo_achievement' = 'true'
GROUP BY u.email, p.display_name
ORDER BY u.email
) LOOP
RAISE NOTICE '% (%): % total | % completados | % en progreso',
v_user_record.display_name,
v_user_record.email,
v_user_record.total_achievements,
v_user_record.completed,
v_user_record.in_progress;
END LOOP;
RAISE NOTICE 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP';
END $$;
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- FIN DEL SEED
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP

View File

@ -0,0 +1,112 @@
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Seed: Comodines Inventory (Production Demo Data)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- Description: Inventarios de comodines (power-ups) para usuarios demo
-- Environment: production
-- Dependencies:
-- - auth.users (01-demo-users.sql)
-- - auth_management.profiles (04-profiles-complete.sql)
-- - gamification_system.user_stats (05-user_stats.sql)
-- Execution Order: 9
-- Created: 2025-01-11
-- Version: 1.1.0
-- Updated: 2025-11-24 - Seed temporalmente deshabilitado (ISSUE-P2-002)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
--
-- ⚠️ ISSUE-P2-002: Seed Temporalmente Deshabilitado
--
-- PROBLEMA:
-- - Seed usa UUIDs hardcodeados que NO existen en tabla profiles
-- - 10 violaciones de FK constraint "comodines_inventory_user_id_fkey"
-- - UUIDs hardcodeados no coinciden con profiles creados en 04-profiles-complete.sql
--
-- SOLUCIÓN TEMPORAL:
-- - Seed completamente comentado para permitir recreación exitosa de BD
-- - FK constraint funciona correctamente (el problema es data, no schema)
--
-- SOLUCIÓN DEFINITIVA (TODO - Próximo Sprint):
-- - Reescribir seed usando queries dinámicas para obtener UUIDs reales
-- - Ejemplo:
-- WITH student_profiles AS (
-- SELECT id, email FROM auth_management.profiles
-- WHERE role = 'student' AND email LIKE '%demo%'
-- ORDER BY email LIMIT 10
-- )
-- INSERT INTO gamification_system.comodines_inventory (user_id, ...)
-- SELECT id, ... FROM student_profiles;
--
-- REFERENCIAS:
-- - orchestration/reportes/REPORTE-FINAL-RESOLUCION-ISSUES-2025-11-24.md (ISSUE-P2-002)
-- - orchestration/agentes/database/validacion-coherencia-2025-11-24/ (ISSUE-P2-001)
--
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
SET search_path TO gamification_system, public;
-- =====================================================
-- SEED DESHABILITADO - Ver comentario ISSUE-P2-002 arriba
-- =====================================================
/*
-- ORIGINAL SEED COMMENTED OUT - REQUIRES REWRITE WITH VALID UUIDs
-- Tipos de Comodines:
-- 1. Pistas Contextuales (15 ML Coins): Ayudas para resolver ejercicios
-- 2. Visión Lectora (25 ML Coins): Resalta información clave en textos
-- 3. Segunda Oportunidad (40 ML Coins): Permite reintentar ejercicios
--
-- Fórmula: available = purchased_total - used_total
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-- ESTUDIANTE 1: Ana García (usuario activo - uso moderado de comodines)
-- UUID HARDCODED: '01ac4f00-082e-4287-b899-2e169c49b05e' (NO EXISTE EN PROFILES)
-- PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
INSERT INTO gamification_system.comodines_inventory (
id, user_id,
pistas_available, vision_lectora_available, segunda_oportunidad_available,
pistas_purchased_total, vision_lectora_purchased_total, segunda_oportunidad_purchased_total,
pistas_used_total, vision_lectora_used_total, segunda_oportunidad_used_total,
pistas_cost, vision_lectora_cost, segunda_oportunidad_cost,
metadata, created_at, updated_at
) VALUES (
'f0000001-0000-0000-0000-000000000001'::uuid,
'01ac4f00-082e-4287-b899-2e169c49b05e'::uuid, -- ❌ UUID NO EXISTE
2, 1, 0, -- available (2 pistas, 1 visión, 0 segunda)
7, 4, 2, -- purchased_total
5, 3, 2, -- used_total
15, 25, 40, -- costs
jsonb_build_object(
'demo_inventory', true,
'last_purchase', gamilit.now_mexico() - INTERVAL '2 days',
'favorite_comodin', 'pistas'
),
gamilit.now_mexico() - INTERVAL '12 days',
gamilit.now_mexico() - INTERVAL '2 days'
) ON CONFLICT (user_id) DO UPDATE SET
pistas_available = EXCLUDED.pistas_available,
vision_lectora_available = EXCLUDED.vision_lectora_available,
segunda_oportunidad_available = EXCLUDED.segunda_oportunidad_available,
updated_at = EXCLUDED.updated_at;
-- [9 more INSERT statements with hardcoded UUIDs that don't exist...]
*/
-- =====================================================
-- PLACEHOLDER: Seed será reescrito en próximo sprint
-- =====================================================
-- Por ahora, tabla comodines_inventory existe y funciona correctamente,
-- solo sin data de demo. Las aplicaciones pueden crear inventories
-- dinámicamente cuando usuarios compren comodines.
DO $$
BEGIN
RAISE NOTICE '======================================================================';
RAISE NOTICE 'SEED 09-comodines_inventory.sql: TEMPORALMENTE DESHABILITADO';
RAISE NOTICE 'Razón: UUIDs hardcodeados no existen en profiles (ISSUE-P2-002)';
RAISE NOTICE 'Tabla comodines_inventory está creada y funcional';
RAISE NOTICE 'Data de demo se agregará en próximo sprint con UUIDs válidos';
RAISE NOTICE '======================================================================';
END $$;

View File

@ -0,0 +1,346 @@
-- =====================================================
-- Seed: gamification_system.mission_templates
-- Description: Templates de misiones para generar misiones diarias/semanales/especiales
-- Priority: P0 - CRÍTICO (Auditoría AUDIT-DB-001)
-- Created: 2025-12-14
-- =====================================================
--
-- Este seed crea los templates base para el sistema de misiones.
-- Los templates se usan para generar misiones automáticamente.
--
-- Tipos de misiones (ENUM mission_type):
-- - daily: Misiones diarias (reset cada día)
-- - weekly: Misiones semanales
-- - special: Misiones especiales/eventos
-- - classroom: Misiones de aula (asignadas por profesores)
--
-- Tipos de objetivos (target_type):
-- - complete_exercises: Completar N ejercicios
-- - study_minutes: Estudiar N minutos
-- - earn_xp: Ganar N XP
-- - correct_streak: Racha de N respuestas correctas
-- - use_comodines: Usar N comodines
-- - perfect_scores: Obtener N puntuaciones perfectas
-- - daily_streak: Mantener racha de N días
-- - complete_modules: Completar N módulos
-- - explore_modules: Explorar N módulos diferentes
-- =====================================================
-- =====================================================
-- MISIONES DIARIAS
-- =====================================================
INSERT INTO gamification_system.mission_templates (
id,
name,
description,
type,
category,
target_type,
target_value,
xp_reward,
ml_coins_reward,
difficulty,
is_active,
priority,
min_level,
icon,
color,
metadata
) VALUES
-- Misión diaria: Completar ejercicios
(
'20000001-0000-0000-0000-000000000001'::uuid,
'Calentamiento Científico',
'Completa 3 ejercicios para comenzar tu día de aprendizaje',
'daily',
'exercise',
'complete_exercises',
3,
50,
10,
'easy',
true,
100,
1,
'🔬',
'#4CAF50',
'{"description_es": "Ejercicios completados", "reward_multiplier": 1.0}'::jsonb
),
-- Misión diaria: Racha de respuestas correctas
(
'20000001-0000-0000-0000-000000000002'::uuid,
'Mente Brillante',
'Consigue una racha de 5 respuestas correctas consecutivas',
'daily',
'streak',
'correct_streak',
5,
75,
15,
'normal',
true,
90,
1,
'',
'#FF9800',
'{"description_es": "Respuestas consecutivas correctas", "reward_multiplier": 1.0}'::jsonb
),
-- Misión diaria: Ganar XP
(
'20000001-0000-0000-0000-000000000003'::uuid,
'Acumulador de Sabiduría',
'Gana 100 puntos de experiencia durante el día',
'daily',
'progress',
'earn_xp',
100,
30,
5,
'easy',
true,
80,
1,
'📈',
'#2196F3',
'{"description_es": "XP ganado", "reward_multiplier": 1.0}'::jsonb
),
-- Misión diaria: Puntuación perfecta
(
'20000001-0000-0000-0000-000000000004'::uuid,
'Perfeccionista del Día',
'Obtén al menos 1 puntuación perfecta en cualquier ejercicio',
'daily',
'mastery',
'perfect_scores',
1,
100,
25,
'hard',
true,
70,
2,
'🌟',
'#9C27B0',
'{"description_es": "Puntuaciones perfectas", "reward_multiplier": 1.2}'::jsonb
)
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
xp_reward = EXCLUDED.xp_reward,
ml_coins_reward = EXCLUDED.ml_coins_reward,
is_active = EXCLUDED.is_active,
updated_at = gamilit.now_mexico();
-- =====================================================
-- MISIONES SEMANALES
-- =====================================================
INSERT INTO gamification_system.mission_templates (
id,
name,
description,
type,
category,
target_type,
target_value,
xp_reward,
ml_coins_reward,
difficulty,
is_active,
priority,
min_level,
icon,
color,
metadata
) VALUES
-- Misión semanal: Completar ejercicios
(
'20000002-0000-0000-0000-000000000001'::uuid,
'Maratón de Conocimiento',
'Completa 15 ejercicios durante la semana',
'weekly',
'exercise',
'complete_exercises',
15,
200,
50,
'normal',
true,
100,
1,
'🏃',
'#4CAF50',
'{"description_es": "Ejercicios completados esta semana", "reward_multiplier": 1.5}'::jsonb
),
-- Misión semanal: Racha diaria
(
'20000002-0000-0000-0000-000000000002'::uuid,
'Constancia Científica',
'Mantén una racha de estudio de 5 días consecutivos',
'weekly',
'streak',
'daily_streak',
5,
300,
75,
'hard',
true,
95,
1,
'🔥',
'#FF5722',
'{"description_es": "Días de racha", "reward_multiplier": 1.5}'::jsonb
),
-- Misión semanal: XP total
(
'20000002-0000-0000-0000-000000000003'::uuid,
'Ascenso Semanal',
'Acumula 500 puntos de experiencia durante la semana',
'weekly',
'progress',
'earn_xp',
500,
150,
40,
'normal',
true,
85,
1,
'📊',
'#00BCD4',
'{"description_es": "XP total semanal", "reward_multiplier": 1.5}'::jsonb
),
-- Misión semanal: Explorar módulos
(
'20000002-0000-0000-0000-000000000004'::uuid,
'Explorador Curioso',
'Realiza ejercicios de al menos 3 módulos diferentes',
'weekly',
'exploration',
'explore_modules',
3,
175,
45,
'normal',
true,
80,
1,
'🗺️',
'#795548',
'{"description_es": "Módulos explorados", "reward_multiplier": 1.5}'::jsonb
),
-- Misión semanal: Puntuaciones perfectas
(
'20000002-0000-0000-0000-000000000005'::uuid,
'Semana de Excelencia',
'Consigue 5 puntuaciones perfectas durante la semana',
'weekly',
'mastery',
'perfect_scores',
5,
400,
100,
'epic',
true,
75,
3,
'👑',
'#FFD700',
'{"description_es": "Puntuaciones perfectas semanales", "reward_multiplier": 2.0}'::jsonb
)
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
xp_reward = EXCLUDED.xp_reward,
ml_coins_reward = EXCLUDED.ml_coins_reward,
is_active = EXCLUDED.is_active,
updated_at = gamilit.now_mexico();
-- =====================================================
-- MISIONES ESPECIALES
-- =====================================================
INSERT INTO gamification_system.mission_templates (
id,
name,
description,
type,
category,
target_type,
target_value,
xp_reward,
ml_coins_reward,
difficulty,
is_active,
priority,
min_level,
icon,
color,
metadata
) VALUES
-- Misión especial: Completar módulo
(
'20000003-0000-0000-0000-000000000001'::uuid,
'Dominio del Módulo',
'Completa todos los ejercicios de un módulo con al menos 80% de aciertos',
'special',
'completion',
'complete_modules',
1,
500,
150,
'epic',
true,
100,
1,
'🎓',
'#E91E63',
'{"description_es": "Módulo completado con maestría", "min_score_percentage": 80, "reward_multiplier": 2.5}'::jsonb
),
-- Misión especial: Uso de comodines
(
'20000003-0000-0000-0000-000000000002'::uuid,
'Estratega Sabio',
'Usa 3 comodines estratégicamente durante tus ejercicios',
'special',
'strategy',
'use_comodines',
3,
75,
20,
'normal',
true,
60,
2,
'🃏',
'#673AB7',
'{"description_es": "Comodines usados", "reward_multiplier": 1.0}'::jsonb
)
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
xp_reward = EXCLUDED.xp_reward,
ml_coins_reward = EXCLUDED.ml_coins_reward,
is_active = EXCLUDED.is_active,
updated_at = gamilit.now_mexico();
-- =====================================================
-- VERIFICACIÓN
-- =====================================================
DO $$
DECLARE
v_count INTEGER;
BEGIN
SELECT COUNT(*) INTO v_count FROM gamification_system.mission_templates;
RAISE NOTICE '';
RAISE NOTICE '=== MISSION TEMPLATES CREADOS ===';
RAISE NOTICE 'Total templates: %', v_count;
RAISE NOTICE 'Daily missions: %', (SELECT COUNT(*) FROM gamification_system.mission_templates WHERE type = 'daily');
RAISE NOTICE 'Weekly missions: %', (SELECT COUNT(*) FROM gamification_system.mission_templates WHERE type = 'weekly');
RAISE NOTICE 'Special missions: %', (SELECT COUNT(*) FROM gamification_system.mission_templates WHERE type = 'special');
IF v_count < 10 THEN
RAISE WARNING '⚠️ Se esperaban al menos 10 mission_templates';
ELSE
RAISE NOTICE '✅ Seed de mission_templates completado exitosamente';
END IF;
END $$;

View File

@ -0,0 +1,548 @@
-- =====================================================
-- Seed: gamification_system.missions (PROD - Production Users)
-- Description: Inicialización de misiones para usuarios de producción sin misiones
-- Environment: PRODUCTION
-- Dependencies: auth.users, auth_management.profiles, gamification_system.missions
-- Order: 11
-- Created: 2025-11-24
-- Version: 1.0
-- =====================================================
--
-- PROPÓSITO:
-- - Crear misiones para usuarios de producción (backup) que NO tienen misiones
-- - No afectar a usuarios de test (@gamilit.com) que ya tienen misiones via seed 10
-- - Script idempotente: puede ejecutarse múltiples veces sin crear duplicados
--
-- MISIONES INCLUIDAS (8 por usuario):
-- - 3 misiones diarias:
-- * daily_complete_exercises: Completar 3 ejercicios (50 XP, 25 ML Coins)
-- * daily_earn_xp: Ganar 100 XP (30 XP, 15 ML Coins)
-- * daily_use_comodin: Usar un comodín (20 XP, 10 ML Coins)
-- - 5 misiones semanales:
-- * weekly_complete_module: Completar un módulo (200 XP, 100 ML Coins)
-- * weekly_daily_streak: Racha de 5 días (150 XP, 75 ML Coins)
-- * weekly_perfect_scores: 3 puntajes perfectos (180 XP, 90 ML Coins)
-- * weekly_explorer: Explorar 3 módulos (120 XP, 60 ML Coins)
-- * weekly_master_learner: Completar 15 ejercicios (250 XP, 125 ML Coins)
--
-- CRITERIOS IDEMPOTENCIA:
-- - Solo procesa usuarios que NO tienen ninguna misión
-- - Usa ON CONFLICT DO NOTHING para evitar duplicados
-- - Verifica existencia de tabla gamification_system.missions
-- =====================================================
SET search_path TO gamification_system, auth_management, public;
-- =====================================================
-- Insert missions for production users without missions
-- =====================================================
DO $$
DECLARE
v_user_record RECORD;
v_users_without_missions INTEGER := 0;
v_users_processed INTEGER := 0;
v_missions_created INTEGER := 0;
v_today_start TIMESTAMP;
v_today_end TIMESTAMP;
v_week_end TIMESTAMP;
BEGIN
-- Log inicio del proceso
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE 'INICIALIZANDO MISIONES PARA USUARIOS DE PRODUCCIÓN';
RAISE NOTICE '========================================';
RAISE NOTICE '';
-- Verificar que la tabla de misiones existe
IF NOT EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_schema = 'gamification_system'
AND table_name = 'missions'
) THEN
RAISE WARNING '⚠️ Tabla gamification_system.missions no existe';
RETURN;
END IF;
-- Contar usuarios sin misiones (excluir usuarios de test @gamilit.com)
SELECT COUNT(DISTINCT p.id) INTO v_users_without_missions
FROM auth_management.profiles p
WHERE NOT EXISTS (
SELECT 1
FROM gamification_system.missions m
WHERE m.user_id = p.id
)
AND p.email NOT LIKE '%@gamilit.com';
RAISE NOTICE '📊 Usuarios sin misiones encontrados: %', v_users_without_missions;
RAISE NOTICE '';
-- Si no hay usuarios sin misiones, terminar
IF v_users_without_missions = 0 THEN
RAISE NOTICE '✅ Todos los usuarios de producción ya tienen misiones';
RAISE NOTICE ' (usuarios de test @gamilit.com se excluyen automáticamente)';
RETURN;
END IF;
-- Calcular rangos de fechas para misiones
v_today_start := gamilit.now_mexico()::date;
v_today_end := v_today_start + INTERVAL '23 hours 59 minutes';
v_week_end := v_today_start + INTERVAL '7 days';
-- Procesar cada usuario sin misiones
FOR v_user_record IN
SELECT
p.id,
p.email,
p.display_name,
p.role
FROM auth_management.profiles p
WHERE NOT EXISTS (
SELECT 1
FROM gamification_system.missions m
WHERE m.user_id = p.id
)
AND p.email NOT LIKE '%@gamilit.com'
ORDER BY p.created_at
LOOP
v_users_processed := v_users_processed + 1;
RAISE NOTICE '🔄 Procesando usuario %/%: % (%)',
v_users_processed,
v_users_without_missions,
COALESCE(v_user_record.display_name, v_user_record.email),
v_user_record.role;
-- =====================================================
-- DAILY MISSIONS (3)
-- =====================================================
-- Daily Mission 1: Complete exercises
INSERT INTO gamification_system.missions (
user_id,
template_id,
title,
description,
mission_type,
objectives,
rewards,
status,
progress,
start_date,
end_date
) VALUES (
v_user_record.id,
'daily_complete_exercises',
'Completar 3 ejercicios',
'Completa 3 ejercicios hoy para ganar recompensas',
'daily',
jsonb_build_object(
'type', 'complete_exercises',
'target', 3,
'current', 0
),
jsonb_build_object(
'xp', 50,
'ml_coins', 25
),
'active',
0,
v_today_start,
v_today_end
)
ON CONFLICT DO NOTHING;
-- Daily Mission 2: Earn XP
INSERT INTO gamification_system.missions (
user_id,
template_id,
title,
description,
mission_type,
objectives,
rewards,
status,
progress,
start_date,
end_date
) VALUES (
v_user_record.id,
'daily_earn_xp',
'Ganar 100 XP',
'Acumula 100 puntos de experiencia hoy',
'daily',
jsonb_build_object(
'type', 'earn_xp',
'target', 100,
'current', 0
),
jsonb_build_object(
'xp', 30,
'ml_coins', 15
),
'active',
0,
v_today_start,
v_today_end
)
ON CONFLICT DO NOTHING;
-- Daily Mission 3: Use comodín
INSERT INTO gamification_system.missions (
user_id,
template_id,
title,
description,
mission_type,
objectives,
rewards,
status,
progress,
start_date,
end_date
) VALUES (
v_user_record.id,
'daily_use_comodin',
'Usar un comodín',
'Usa al menos un comodín en un ejercicio',
'daily',
jsonb_build_object(
'type', 'use_comodines',
'target', 1,
'current', 0
),
jsonb_build_object(
'xp', 20,
'ml_coins', 10
),
'active',
0,
v_today_start,
v_today_end
)
ON CONFLICT DO NOTHING;
-- =====================================================
-- WEEKLY MISSIONS (5)
-- =====================================================
-- Weekly Mission 1: Complete a module
INSERT INTO gamification_system.missions (
user_id,
template_id,
title,
description,
mission_type,
objectives,
rewards,
status,
progress,
start_date,
end_date
) VALUES (
v_user_record.id,
'weekly_complete_module',
'Completar un módulo',
'Completa un módulo completo esta semana',
'weekly',
jsonb_build_object(
'type', 'complete_modules',
'target', 1,
'current', 0
),
jsonb_build_object(
'xp', 200,
'ml_coins', 100
),
'active',
0,
v_today_start,
v_week_end
)
ON CONFLICT DO NOTHING;
-- Weekly Mission 2: Daily streak
INSERT INTO gamification_system.missions (
user_id,
template_id,
title,
description,
mission_type,
objectives,
rewards,
status,
progress,
start_date,
end_date
) VALUES (
v_user_record.id,
'weekly_daily_streak',
'Racha de 5 días',
'Completa al menos un ejercicio durante 5 días seguidos',
'weekly',
jsonb_build_object(
'type', 'daily_streak',
'target', 5,
'current', 0
),
jsonb_build_object(
'xp', 150,
'ml_coins', 75
),
'active',
0,
v_today_start,
v_week_end
)
ON CONFLICT DO NOTHING;
-- Weekly Mission 3: Perfect scores
INSERT INTO gamification_system.missions (
user_id,
template_id,
title,
description,
mission_type,
objectives,
rewards,
status,
progress,
start_date,
end_date
) VALUES (
v_user_record.id,
'weekly_perfect_scores',
'Perfección absoluta',
'Obtén 3 puntajes perfectos (100%) en ejercicios',
'weekly',
jsonb_build_object(
'type', 'perfect_scores',
'target', 3,
'current', 0
),
jsonb_build_object(
'xp', 180,
'ml_coins', 90
),
'active',
0,
v_today_start,
v_week_end
)
ON CONFLICT DO NOTHING;
-- Weekly Mission 4: Explorer
INSERT INTO gamification_system.missions (
user_id,
template_id,
title,
description,
mission_type,
objectives,
rewards,
status,
progress,
start_date,
end_date
) VALUES (
v_user_record.id,
'weekly_explorer',
'Explorador curioso',
'Completa ejercicios de 3 módulos diferentes',
'weekly',
jsonb_build_object(
'type', 'explore_modules',
'target', 3,
'current', 0,
'modules_visited', '[]'::jsonb
),
jsonb_build_object(
'xp', 120,
'ml_coins', 60
),
'active',
0,
v_today_start,
v_week_end
)
ON CONFLICT DO NOTHING;
-- Weekly Mission 5: Master learner
INSERT INTO gamification_system.missions (
user_id,
template_id,
title,
description,
mission_type,
objectives,
rewards,
status,
progress,
start_date,
end_date
) VALUES (
v_user_record.id,
'weekly_master_learner',
'Maestro del aprendizaje',
'Completa 15 ejercicios esta semana',
'weekly',
jsonb_build_object(
'type', 'complete_exercises',
'target', 15,
'current', 0
),
jsonb_build_object(
'xp', 250,
'ml_coins', 125
),
'active',
0,
v_today_start,
v_week_end
)
ON CONFLICT DO NOTHING;
RAISE NOTICE ' ✅ 8 misiones creadas (3 diarias + 5 semanales)';
END LOOP;
-- Contar misiones totales creadas en este script
SELECT COUNT(*) INTO v_missions_created
FROM gamification_system.missions m
WHERE m.created_at > (gamilit.now_mexico() - INTERVAL '1 minute');
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE 'PROCESO COMPLETADO';
RAISE NOTICE '========================================';
RAISE NOTICE 'Usuarios procesados: %', v_users_processed;
RAISE NOTICE 'Misiones creadas: %', v_missions_created;
RAISE NOTICE 'Promedio por usuario: %',
CASE
WHEN v_users_processed > 0 THEN ROUND(v_missions_created::numeric / v_users_processed::numeric, 1)
ELSE 0
END;
RAISE NOTICE '========================================';
RAISE NOTICE '';
EXCEPTION
WHEN OTHERS THEN
RAISE WARNING '❌ Error inicializando misiones: %', SQLERRM;
RAISE WARNING 'SQLSTATE: %', SQLSTATE;
RAISE WARNING 'DETAIL: %', SQLERRM;
END $$;
-- =====================================================
-- Verification - Estado final de misiones
-- =====================================================
DO $$
DECLARE
v_total_users INTEGER;
v_users_with_missions INTEGER;
v_users_without_missions INTEGER;
v_total_daily INTEGER;
v_total_weekly INTEGER;
v_total_missions INTEGER;
v_test_users_with_missions INTEGER;
v_prod_users_with_missions INTEGER;
v_user_record RECORD;
BEGIN
-- Contar usuarios totales
SELECT COUNT(*) INTO v_total_users
FROM auth_management.profiles;
-- Contar usuarios con misiones (test)
SELECT COUNT(DISTINCT p.id) INTO v_test_users_with_missions
FROM auth_management.profiles p
WHERE EXISTS (
SELECT 1 FROM gamification_system.missions m WHERE m.user_id = p.id
)
AND p.email LIKE '%@gamilit.com';
-- Contar usuarios con misiones (producción)
SELECT COUNT(DISTINCT p.id) INTO v_prod_users_with_missions
FROM auth_management.profiles p
WHERE EXISTS (
SELECT 1 FROM gamification_system.missions m WHERE m.user_id = p.id
)
AND p.email NOT LIKE '%@gamilit.com';
-- Total usuarios con misiones
v_users_with_missions := v_test_users_with_missions + v_prod_users_with_missions;
-- Usuarios sin misiones
SELECT COUNT(DISTINCT p.id) INTO v_users_without_missions
FROM auth_management.profiles p
WHERE NOT EXISTS (
SELECT 1 FROM gamification_system.missions m WHERE m.user_id = p.id
);
-- Contar misiones por tipo
SELECT COUNT(*) INTO v_total_daily
FROM gamification_system.missions
WHERE mission_type = 'daily';
SELECT COUNT(*) INTO v_total_weekly
FROM gamification_system.missions
WHERE mission_type = 'weekly';
SELECT COUNT(*) INTO v_total_missions
FROM gamification_system.missions;
-- Reporte final
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE 'VERIFICACIÓN FINAL - ESTADO DE MISIONES';
RAISE NOTICE '========================================';
RAISE NOTICE '';
RAISE NOTICE '👥 USUARIOS:';
RAISE NOTICE ' Total de usuarios: %', v_total_users;
RAISE NOTICE ' Usuarios con misiones (test): %', v_test_users_with_missions;
RAISE NOTICE ' Usuarios con misiones (prod): %', v_prod_users_with_missions;
RAISE NOTICE ' Usuarios SIN misiones: %', v_users_without_missions;
RAISE NOTICE '';
RAISE NOTICE '📋 MISIONES:';
RAISE NOTICE ' Misiones diarias: %', v_total_daily;
RAISE NOTICE ' Misiones semanales: %', v_total_weekly;
RAISE NOTICE ' Total de misiones: %', v_total_missions;
RAISE NOTICE '';
-- Validaciones
IF v_users_without_missions = 0 THEN
RAISE NOTICE '✅ ÉXITO: Todos los usuarios tienen misiones inicializadas';
ELSE
RAISE WARNING '⚠️ ADVERTENCIA: % usuarios aún no tienen misiones', v_users_without_missions;
RAISE NOTICE '';
RAISE NOTICE '📝 Usuarios sin misiones:';
-- Listar primeros 5 usuarios sin misiones
FOR v_user_record IN (
SELECT
p.email,
p.display_name,
p.role,
p.created_at
FROM auth_management.profiles p
WHERE NOT EXISTS (
SELECT 1 FROM gamification_system.missions m WHERE m.user_id = p.id
)
ORDER BY p.created_at
LIMIT 5
) LOOP
RAISE NOTICE ' - % (%) - creado: %',
v_user_record.email,
v_user_record.role,
v_user_record.created_at::date;
END LOOP;
IF v_users_without_missions > 5 THEN
RAISE NOTICE ' ... y % más', v_users_without_missions - 5;
END IF;
END IF;
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE '';
END $$;

View File

@ -0,0 +1,146 @@
-- =====================================================
-- Seed: gamification_system.shop_categories (PROD)
-- Description: Categorías de la tienda virtual
-- Environment: PRODUCTION
-- Dependencies: gamification_system.shop_categories table
-- Order: 12
-- Created: 2025-11-29
-- Version: 1.0
-- =====================================================
--
-- CATEGORÍAS INCLUIDAS:
-- - cosmetics: Cosméticos visuales (avatares, marcos, fondos)
-- - profile: Items de perfil (títulos, badges)
-- - guild: Items de gremio (banderas, emblemas)
-- - social: Items sociales (emojis, stickers)
-- - consumable: Consumibles (boosts, power-ups)
--
-- TOTAL: 5 categorías
--
-- IMPORTANTE: Estas categorías estructuran la tienda virtual
-- y permiten organizar los items por tipo.
-- =====================================================
SET search_path TO gamification_system, public;
-- =====================================================
-- INSERT: Shop Categories
-- =====================================================
INSERT INTO gamification_system.shop_categories (
name,
display_name,
description,
icon,
color,
display_order,
is_active
) VALUES
(
'cosmetics',
'Cosméticos',
'Personaliza tu apariencia con avatares, marcos y fondos únicos',
'palette',
'from-pink-500 to-purple-500',
1,
true
),
(
'profile',
'Perfil',
'Mejora tu perfil con títulos y badges exclusivos',
'user',
'from-blue-500 to-cyan-500',
2,
true
),
(
'guild',
'Gremio',
'Items para personalizar y mejorar tu gremio',
'crown',
'from-yellow-500 to-orange-500',
3,
true
),
(
'social',
'Social',
'Emojis, stickers y efectos para interactuar con otros',
'star',
'from-green-500 to-emerald-500',
4,
true
),
(
'consumable',
'Consumibles',
'Boosts temporales y items de uso único',
'zap',
'from-orange-500 to-red-500',
5,
true
)
ON CONFLICT (name) DO UPDATE SET
display_name = EXCLUDED.display_name,
description = EXCLUDED.description,
icon = EXCLUDED.icon,
color = EXCLUDED.color,
display_order = EXCLUDED.display_order,
is_active = EXCLUDED.is_active,
updated_at = gamilit.now_mexico();
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
category_count INTEGER;
BEGIN
SELECT COUNT(*) INTO category_count
FROM gamification_system.shop_categories;
RAISE NOTICE '========================================';
RAISE NOTICE 'SHOP CATEGORIES CREADAS EXITOSAMENTE';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total categorías: %', category_count;
RAISE NOTICE '========================================';
IF category_count = 5 THEN
RAISE NOTICE '✓ Todas las categorías fueron creadas correctamente';
ELSE
RAISE WARNING '⚠ Se esperaban 5 categorías, se crearon %', category_count;
END IF;
END $$;
-- =====================================================
-- Listado de categorías
-- =====================================================
DO $$
DECLARE
category_record RECORD;
BEGIN
RAISE NOTICE '';
RAISE NOTICE 'Listado de categorías de tienda:';
RAISE NOTICE '========================================';
FOR category_record IN
SELECT
display_name,
name,
icon,
display_order
FROM gamification_system.shop_categories
ORDER BY display_order
LOOP
RAISE NOTICE ' % - % [%] (orden: %)',
category_record.display_order,
category_record.display_name,
category_record.name,
category_record.icon;
END LOOP;
RAISE NOTICE '========================================';
END $$;

View File

@ -0,0 +1,671 @@
-- =====================================================
-- Seed: gamification_system.shop_items (PROD)
-- Description: Items de la tienda virtual (20+ items variados)
-- Environment: PRODUCTION
-- Dependencies: gamification_system.shop_items, shop_categories
-- Order: 13
-- Created: 2025-11-29
-- Version: 1.0
-- =====================================================
--
-- ITEMS INCLUIDOS:
-- - COSMETICS (5 items): Avatares, marcos, fondos
-- - PROFILE (5 items): Títulos, badges exclusivos
-- - GUILD (4 items): Banderas, emblemas de gremio
-- - SOCIAL (4 items): Emojis, stickers, efectos
-- - CONSUMABLE (2 items): Boosts temporales
--
-- TOTAL: 20 items
--
-- IMPORTANTE: Estos items proveen valor y variedad
-- a la economía de ML Coins del sistema GAMILIT.
-- =====================================================
SET search_path TO gamification_system, auth_management, public;
-- =====================================================
-- INSERT: Shop Items
-- =====================================================
-- Get category IDs for reference
DO $$
DECLARE
cat_cosmetics_id uuid;
cat_profile_id uuid;
cat_guild_id uuid;
cat_social_id uuid;
cat_consumable_id uuid;
BEGIN
SELECT id INTO cat_cosmetics_id FROM gamification_system.shop_categories WHERE name = 'cosmetics';
SELECT id INTO cat_profile_id FROM gamification_system.shop_categories WHERE name = 'profile';
SELECT id INTO cat_guild_id FROM gamification_system.shop_categories WHERE name = 'guild';
SELECT id INTO cat_social_id FROM gamification_system.shop_categories WHERE name = 'social';
SELECT id INTO cat_consumable_id FROM gamification_system.shop_categories WHERE name = 'consumable';
-- =====================================================
-- CATEGORY: COSMETICS (5 items)
-- =====================================================
INSERT INTO gamification_system.shop_items (
id,
tenant_id,
name,
description,
icon,
category_id,
category,
rarity,
tags,
price,
is_available,
max_per_user,
is_consumable,
effect_data,
metadata,
created_at,
updated_at
) VALUES
(
'80000001-0001-0000-0000-000000000001'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Avatar Detective Dorado',
'Avatar exclusivo de detective con acabado dorado. Demuestra tu nivel de maestría en comprensión lectora.',
'user-circle',
cat_cosmetics_id,
'cosmetics'::gamification_system.shop_item_category,
'legendary',
ARRAY['avatar', 'detective', 'gold', 'exclusive'],
500,
true,
1,
false,
jsonb_build_object(
'type', 'avatar',
'asset_url', '/assets/avatars/detective-gold.png',
'animated', false
),
jsonb_build_object(
'featured', true,
'recommended_rank', 'K''uk''ulkan'
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000001-0001-0000-0000-000000000002'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Marco Lector Experto',
'Marco decorativo épico para tu perfil. Muestra que eres un lector experimentado.',
'square',
cat_cosmetics_id,
'cosmetics'::gamification_system.shop_item_category,
'epic',
ARRAY['frame', 'border', 'expert'],
300,
true,
1,
false,
jsonb_build_object(
'type', 'profile_frame',
'asset_url', '/assets/frames/expert-reader.png',
'border_color', '#8B5CF6'
),
jsonb_build_object(
'featured', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000001-0001-0000-0000-000000000003'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Fondo Biblioteca Mágica',
'Fondo animado de biblioteca con libros flotantes y efectos mágicos.',
'image',
cat_cosmetics_id,
'cosmetics'::gamification_system.shop_item_category,
'rare',
ARRAY['background', 'library', 'animated'],
150,
true,
1,
false,
jsonb_build_object(
'type', 'profile_background',
'asset_url', '/assets/backgrounds/magic-library.gif',
'animated', true
),
jsonb_build_object(),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000001-0001-0000-0000-000000000004'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Avatar Búho Sabio',
'Avatar de búho con toga académica. Perfecto para estudiantes dedicados.',
'user-circle',
cat_cosmetics_id,
'cosmetics'::gamification_system.shop_item_category,
'common',
ARRAY['avatar', 'owl', 'wisdom'],
50,
true,
1,
false,
jsonb_build_object(
'type', 'avatar',
'asset_url', '/assets/avatars/wise-owl.png',
'animated', false
),
jsonb_build_object(
'starter_item', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000001-0001-0000-0000-000000000005'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Marco Estrellas',
'Marco sencillo con estrellas doradas. Ideal para principiantes.',
'square',
cat_cosmetics_id,
'cosmetics'::gamification_system.shop_item_category,
'common',
ARRAY['frame', 'stars', 'simple'],
75,
true,
1,
false,
jsonb_build_object(
'type', 'profile_frame',
'asset_url', '/assets/frames/stars.png',
'border_color', '#FFD700'
),
jsonb_build_object(
'starter_item', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
-- =====================================================
-- CATEGORY: PROFILE (5 items)
-- =====================================================
(
'80000002-0001-0000-0000-000000000001'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Título "Maestro Lector"',
'Título prestigioso que demuestra tu dominio absoluto de la comprensión lectora.',
'award',
cat_profile_id,
'profile'::gamification_system.shop_item_category,
'legendary',
ARRAY['title', 'master', 'prestige'],
400,
true,
1,
false,
jsonb_build_object(
'type', 'title',
'display_text', 'Maestro Lector',
'color', '#FFD700'
),
jsonb_build_object(
'featured', true,
'achievement_showcase', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000002-0001-0000-0000-000000000002'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Título "Explorador de Historias"',
'Para aquellos que han explorado diversos tipos de textos y géneros literarios.',
'compass',
cat_profile_id,
'profile'::gamification_system.shop_item_category,
'epic',
ARRAY['title', 'explorer', 'stories'],
250,
true,
1,
false,
jsonb_build_object(
'type', 'title',
'display_text', 'Explorador de Historias',
'color', '#8B5CF6'
),
jsonb_build_object(),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000002-0001-0000-0000-000000000003'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Badge Detective Élite',
'Badge exclusivo para los mejores detectives textuales de GAMILIT.',
'shield',
cat_profile_id,
'profile'::gamification_system.shop_item_category,
'rare',
ARRAY['badge', 'detective', 'elite'],
200,
true,
1,
false,
jsonb_build_object(
'type', 'badge',
'asset_url', '/assets/badges/detective-elite.png',
'animated', true
),
jsonb_build_object(),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000002-0001-0000-0000-000000000004'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Título "Aprendiz Curioso"',
'Título inicial para estudiantes que muestran curiosidad y ganas de aprender.',
'book-open',
cat_profile_id,
'profile'::gamification_system.shop_item_category,
'common',
ARRAY['title', 'beginner', 'curious'],
100,
true,
1,
false,
jsonb_build_object(
'type', 'title',
'display_text', 'Aprendiz Curioso',
'color', '#3B82F6'
),
jsonb_build_object(
'starter_item', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000002-0001-0000-0000-000000000005'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Badge Primer Logro',
'Badge conmemorativo de tu primer logro en GAMILIT.',
'award',
cat_profile_id,
'profile'::gamification_system.shop_item_category,
'common',
ARRAY['badge', 'first', 'achievement'],
50,
true,
1,
false,
jsonb_build_object(
'type', 'badge',
'asset_url', '/assets/badges/first-achievement.png',
'animated', false
),
jsonb_build_object(
'starter_item', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
-- =====================================================
-- CATEGORY: GUILD (4 items)
-- =====================================================
(
'80000003-0001-0000-0000-000000000001'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Bandera Dorada de Gremio',
'Bandera legendaria que ondea en la sede de tu gremio. Símbolo de excelencia.',
'flag',
cat_guild_id,
'guild'::gamification_system.shop_item_category,
'legendary',
ARRAY['guild', 'banner', 'gold', 'prestige'],
600,
true,
1,
false,
jsonb_build_object(
'type', 'guild_banner',
'asset_url', '/assets/guild/golden-banner.png',
'animated', true
),
jsonb_build_object(
'featured', true,
'guild_level_required', 10
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000003-0001-0000-0000-000000000002'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Emblema Dragón Lector',
'Emblema épico con diseño de dragón rodeado de libros antiguos.',
'shield',
cat_guild_id,
'guild'::gamification_system.shop_item_category,
'epic',
ARRAY['guild', 'emblem', 'dragon'],
350,
true,
1,
false,
jsonb_build_object(
'type', 'guild_emblem',
'asset_url', '/assets/guild/dragon-emblem.png',
'animated', false
),
jsonb_build_object(),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000003-0001-0000-0000-000000000003'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Escudo del Conocimiento',
'Escudo simbólico que representa la protección del saber.',
'shield-check',
cat_guild_id,
'guild'::gamification_system.shop_item_category,
'rare',
ARRAY['guild', 'shield', 'knowledge'],
200,
true,
1,
false,
jsonb_build_object(
'type', 'guild_shield',
'asset_url', '/assets/guild/knowledge-shield.png',
'animated', false
),
jsonb_build_object(),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000003-0001-0000-0000-000000000004'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Estandarte Básico',
'Estandarte inicial para tu gremio. Funcional y elegante.',
'flag',
cat_guild_id,
'guild'::gamification_system.shop_item_category,
'common',
ARRAY['guild', 'banner', 'basic'],
100,
true,
1,
false,
jsonb_build_object(
'type', 'guild_banner',
'asset_url', '/assets/guild/basic-banner.png',
'animated', false
),
jsonb_build_object(
'starter_item', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
-- =====================================================
-- CATEGORY: SOCIAL (4 items)
-- =====================================================
(
'80000004-0001-0000-0000-000000000001'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Pack Emojis Premium',
'Colección de 50 emojis exclusivos temáticos de lectura y aprendizaje.',
'smile',
cat_social_id,
'social'::gamification_system.shop_item_category,
'epic',
ARRAY['emoji', 'pack', 'premium', 'exclusive'],
200,
true,
1,
false,
jsonb_build_object(
'type', 'emoji_pack',
'emoji_count', 50,
'emojis', jsonb_build_array('📚', '', '🎯', '🏆', '💡', '🔥')
),
jsonb_build_object(
'featured', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000004-0001-0000-0000-000000000002'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Sticker Celebración',
'Sticker animado de celebración para compartir tus logros.',
'sticker',
cat_social_id,
'social'::gamification_system.shop_item_category,
'rare',
ARRAY['sticker', 'celebration', 'animated'],
100,
true,
null,
false,
jsonb_build_object(
'type', 'sticker',
'asset_url', '/assets/stickers/celebration.gif',
'animated', true
),
jsonb_build_object(),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000004-0001-0000-0000-000000000003'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Efecto Confeti',
'Efecto de confeti para celebrar victorias en desafíos.',
'sparkles',
cat_social_id,
'social'::gamification_system.shop_item_category,
'rare',
ARRAY['effect', 'confetti', 'celebration'],
150,
true,
1,
false,
jsonb_build_object(
'type', 'chat_effect',
'effect_name', 'confetti',
'duration_seconds', 5
),
jsonb_build_object(),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000004-0001-0000-0000-000000000004'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Pack Emojis Básico',
'Colección inicial de 20 emojis básicos para comunicarte.',
'smile',
cat_social_id,
'social'::gamification_system.shop_item_category,
'common',
ARRAY['emoji', 'pack', 'basic'],
50,
true,
1,
false,
jsonb_build_object(
'type', 'emoji_pack',
'emoji_count', 20,
'emojis', jsonb_build_array('😊', '👍', '❤️', '🎉', '💪', '🌟')
),
jsonb_build_object(
'starter_item', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
-- =====================================================
-- CATEGORY: CONSUMABLE (2 items)
-- =====================================================
(
'80000005-0001-0000-0000-000000000001'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Boost XP 2x (24h)',
'Duplica tu ganancia de XP durante 24 horas. Perfecto para avanzar rápido.',
'zap',
cat_consumable_id,
'consumable'::gamification_system.shop_item_category,
'rare',
ARRAY['boost', 'xp', 'temporary'],
100,
true,
null,
true,
jsonb_build_object(
'type', 'xp_boost',
'multiplier', 2.0,
'duration_hours', 24
),
jsonb_build_object(
'stackable', false,
'popular', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
),
(
'80000005-0001-0000-0000-000000000002'::uuid,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'Boost Coins 1.5x (12h)',
'Aumenta 50% la ganancia de ML Coins durante 12 horas.',
'coins',
cat_consumable_id,
'consumable'::gamification_system.shop_item_category,
'common',
ARRAY['boost', 'coins', 'temporary'],
75,
true,
null,
true,
jsonb_build_object(
'type', 'coins_boost',
'multiplier', 1.5,
'duration_hours', 12
),
jsonb_build_object(
'stackable', false
),
gamilit.now_mexico(),
gamilit.now_mexico()
)
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
icon = EXCLUDED.icon,
category_id = EXCLUDED.category_id,
category = EXCLUDED.category,
rarity = EXCLUDED.rarity,
tags = EXCLUDED.tags,
price = EXCLUDED.price,
is_available = EXCLUDED.is_available,
max_per_user = EXCLUDED.max_per_user,
is_consumable = EXCLUDED.is_consumable,
effect_data = EXCLUDED.effect_data,
metadata = EXCLUDED.metadata,
updated_at = gamilit.now_mexico();
END $$;
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
items_count INTEGER;
cosmetics_count INTEGER;
profile_count INTEGER;
guild_count INTEGER;
social_count INTEGER;
consumable_count INTEGER;
BEGIN
SELECT COUNT(*) INTO items_count FROM gamification_system.shop_items;
SELECT COUNT(*) INTO cosmetics_count FROM gamification_system.shop_items WHERE category = 'cosmetics';
SELECT COUNT(*) INTO profile_count FROM gamification_system.shop_items WHERE category = 'profile';
SELECT COUNT(*) INTO guild_count FROM gamification_system.shop_items WHERE category = 'guild';
SELECT COUNT(*) INTO social_count FROM gamification_system.shop_items WHERE category = 'social';
SELECT COUNT(*) INTO consumable_count FROM gamification_system.shop_items WHERE category = 'consumable';
RAISE NOTICE '========================================';
RAISE NOTICE 'SHOP ITEMS CREADOS EXITOSAMENTE';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total items: %', items_count;
RAISE NOTICE ' - Cosmetics: %', cosmetics_count;
RAISE NOTICE ' - Profile: %', profile_count;
RAISE NOTICE ' - Guild: %', guild_count;
RAISE NOTICE ' - Social: %', social_count;
RAISE NOTICE ' - Consumable: %', consumable_count;
RAISE NOTICE '========================================';
IF items_count >= 20 THEN
RAISE NOTICE '✓ Todos los items fueron creados correctamente';
ELSE
RAISE WARNING '⚠ Se esperaban al menos 20 items, se crearon %', items_count;
END IF;
END $$;
-- =====================================================
-- Listado de items por categoría y rareza
-- =====================================================
DO $$
DECLARE
item_record RECORD;
current_category TEXT := '';
BEGIN
RAISE NOTICE '';
RAISE NOTICE 'Listado de items de tienda por categoría:';
RAISE NOTICE '========================================';
FOR item_record IN
SELECT
name,
category::text as category,
rarity,
price,
is_consumable
FROM gamification_system.shop_items
ORDER BY category, rarity DESC, price DESC
LOOP
IF current_category != item_record.category THEN
current_category := item_record.category;
RAISE NOTICE '';
RAISE NOTICE '=== % ===', UPPER(current_category);
END IF;
RAISE NOTICE ' - % [%] - % ML Coins %',
item_record.name,
item_record.rarity,
item_record.price,
CASE WHEN item_record.is_consumable THEN '(Consumible)' ELSE '' END;
END LOOP;
RAISE NOTICE '';
RAISE NOTICE '========================================';
END $$;

View File

@ -0,0 +1,167 @@
-- =====================================================
-- Seed: social_features.schools - SCHOOL DEFAULT (PROD)
-- Description: Escuela del sistema para usuarios pendientes de asignación
-- Environment: PRODUCTION
-- Dependencies: auth_management.tenants
-- Order: 00 (debe ejecutarse ANTES de 01-schools.sql)
-- Created: 2025-12-15
-- Version: 1.0
-- =====================================================
--
-- PROPÓSITO:
-- Esta escuela es utilizada por el sistema para:
-- 1. Asignar automáticamente a usuarios admin nuevos
-- 2. Servir como pool de usuarios "por asignar"
-- 3. El classroom DEFAULT apunta a esta escuela
--
-- UUID FIJO: 99999999-9999-9999-9999-999999999999
-- CÓDIGO: SYSTEM-UNASSIGNED
--
-- IMPORTANTE: Esta escuela NO debe eliminarse nunca.
-- =====================================================
SET search_path TO social_features, auth_management, public;
-- =====================================================
-- Obtener tenant_id para la escuela
-- =====================================================
DO $$
DECLARE
v_tenant_id UUID;
BEGIN
-- Obtener el tenant principal de GAMILIT Platform
SELECT id INTO v_tenant_id
FROM auth_management.tenants
WHERE name = 'GAMILIT Platform'
LIMIT 1;
IF v_tenant_id IS NULL THEN
RAISE EXCEPTION 'Tenant "GAMILIT Platform" no encontrado. Ejecutar primero seed de tenants.';
END IF;
RAISE NOTICE 'Usando tenant_id: %', v_tenant_id;
-- =====================================================
-- INSERT: Escuela Default del Sistema
-- =====================================================
INSERT INTO social_features.schools (
id,
tenant_id,
name,
code,
short_name,
description,
address,
city,
region,
country,
postal_code,
phone,
email,
website,
principal_id,
administrative_contact_id,
academic_year,
semester_system,
grade_levels,
settings,
max_students,
max_teachers,
current_students_count,
current_teachers_count,
is_active,
is_verified,
metadata,
created_at,
updated_at
) VALUES (
'99999999-9999-9999-9999-999999999999'::uuid, -- UUID fija para sistema
v_tenant_id,
'Sistema - Por Asignar',
'SYSTEM-UNASSIGNED',
'Sistema',
'Escuela del sistema para usuarios pendientes de asignación a sus instituciones finales. Los administradores y profesores nuevos se asignan aquí automáticamente.',
NULL, -- Sin dirección física
NULL, -- Sin ciudad
NULL, -- Sin región
'México',
NULL, -- Sin código postal
NULL, -- Sin teléfono
'sistema@gamilit.com', -- Email de sistema
NULL, -- Sin website
NULL, -- Sin principal_id
NULL, -- Sin administrative_contact_id
'2025', -- Año académico
false, -- No usa semestres
ARRAY['todos'], -- Todos los niveles
jsonb_build_object(
'is_system', true,
'is_default', true,
'auto_assignment', true,
'allow_reassignment', true,
'allow_public_registration', false,
'require_email_verification', false,
'enable_gamification', true,
'max_students_per_classroom', 999,
'description', 'Configuración de sistema - no editar'
),
9999, -- max_students (sin límite efectivo)
999, -- max_teachers (sin límite efectivo)
0, -- current_students_count
0, -- current_teachers_count
true, -- is_active
true, -- is_verified (sistema)
jsonb_build_object(
'system_school', true,
'is_default', true,
'created_by', 'system',
'purpose', 'Escuela de sistema para asignación pendiente',
'policies', jsonb_build_object(
'allow_student_reassignment', true,
'allow_admin_reassignment', true,
'require_approval', false,
'auto_assign_new_admins', true
),
'description', 'Escuela automática del sistema para gestión de usuarios no asignados'
),
gamilit.now_mexico(),
gamilit.now_mexico()
)
ON CONFLICT (code) DO UPDATE SET
name = EXCLUDED.name,
short_name = EXCLUDED.short_name,
description = EXCLUDED.description,
settings = EXCLUDED.settings,
metadata = EXCLUDED.metadata,
is_active = true,
updated_at = gamilit.now_mexico();
END $$;
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
v_school_id UUID;
v_school_name TEXT;
BEGIN
SELECT id, name INTO v_school_id, v_school_name
FROM social_features.schools
WHERE code = 'SYSTEM-UNASSIGNED';
IF v_school_id IS NOT NULL THEN
RAISE NOTICE '========================================';
RAISE NOTICE 'ESCUELA DEFAULT DEL SISTEMA CREADA';
RAISE NOTICE '========================================';
RAISE NOTICE 'ID: %', v_school_id;
RAISE NOTICE 'Nombre: %', v_school_name;
RAISE NOTICE 'Código: SYSTEM-UNASSIGNED';
RAISE NOTICE '========================================';
ELSE
RAISE WARNING 'ERROR: No se pudo crear la escuela default del sistema';
END IF;
END $$;

View File

@ -1,210 +1,58 @@
-- =====================================================================
-- Archivo: 01-schools.sql
-- Schema: social_features
-- Descripción: Seeds de escuelas demo para testing
-- Dependencias: auth.users (instructores)
-- Autor: SA-SEEDS-SOCIAL
-- Fecha: 2025-11-02
-- =====================================================================
-- =====================================================
-- Seed: social_features.schools (DEV)
-- Description: NO demo schools - Solo escuela default
-- Environment: DEVELOPMENT
-- Dependencies: auth_management.tenants
-- Order: 01
-- Created: 2025-01-11
-- Updated: 2025-12-15 - Removidas escuelas demo
-- Version: 3.0
-- =====================================================
--
-- NOTA: Este archivo está intencionalmente vacío de INSERTs.
--
-- DECISIÓN DE DISEÑO:
-- - Solo existe la escuela default "Sistema - Por Asignar" (SYSTEM-UNASSIGNED)
-- - Creada en 00-schools-default.sql
-- - Todas las escuelas adicionales serán creadas por el admin desde la UI
--
-- ESCUELAS DEMO REMOVIDAS (v3.0):
-- - Secundaria Federal No. 15 "Marie Curie" - REMOVIDA
-- - Secundaria Técnica No. 42 - REMOVIDA
-- - Colegio Científico "Albert Einstein" - REMOVIDA
--
-- =====================================================
SET search_path TO social_features, public;
SET search_path TO social_features, auth_management, public;
-- =====================================================================
-- SCHOOLS: Escuelas de diferentes tipos y ubicaciones
-- =====================================================================
-- =====================================================
-- Verification Query - Solo escuela default
-- =====================================================
INSERT INTO social_features.schools (
name, code, type,
address, city, state, country, postal_code,
phone, email, website,
principal_name, contact_name, email,
current_students_count, current_teachers_count,
is_active,
settings, metadata,
created_at, updated_at
) VALUES
-- =====================================================================
-- Escuela 1: Secundaria Federal No. 15 "Marie Curie" (Ciudad de México)
-- Tipo: Pública | Turno: Matutino | Capacidad: 450 estudiantes
-- =====================================================================
(
'Secundaria Federal No. 15 "Marie Curie"',
'SF-015-CDMX',
'public',
'Av. Insurgentes Sur 1234',
'Ciudad de México',
'CDMX',
'México',
'03100',
'55-1234-5678',
'secundaria15@sep.gob.mx',
'https://sf15mariecurie.edu.mx',
'Lic. Ana García Rodríguez',
'Prof. Carlos Méndez',
'contacto@sf15mariecurie.edu.mx',
450,
32,
'active',
true,
'{
"allow_public_registration": true,
"require_email_verification": true,
"max_students_per_classroom": 35,
"enable_parent_portal": true,
"academic_calendar": {
"start_date": "2025-08-15",
"end_date": "2026-07-15",
"vacation_periods": [
{"name": "Navidad", "start": "2025-12-20", "end": "2026-01-06"},
{"name": "Semana Santa", "start": "2026-04-02", "end": "2026-04-12"}
]
}
}'::jsonb,
'{
"year_founded": 1975,
"cct": "09DES0015K",
"shift": "matutino",
"grades": ["1", "2", "3"],
"recognition": "Escuela de Calidad 2024",
"infrastructure": {
"library": true,
"computer_lab": true,
"science_lab": true,
"sports_facilities": true
}
}'::jsonb,
NOW(),
NOW()
),
-- =====================================================================
-- Escuela 2: Secundaria Técnica No. 42 (Monterrey)
-- Tipo: Pública Técnica | Turno: Vespertino | Especialidades técnicas
-- =====================================================================
(
'Secundaria Técnica No. 42',
'ST-042-NL',
'public',
'Av. Tecnológico 567',
'Monterrey',
'Nuevo León',
'México',
'64700',
'81-8765-4321',
'secundariatecnica42@sep.gob.mx',
'https://st42.edu.mx',
'Ing. Roberto Sánchez',
'Prof. Laura Martínez',
'contacto@st42.edu.mx',
380,
28,
'active',
true,
'{
"allow_public_registration": true,
"require_email_verification": true,
"max_students_per_classroom": 30,
"enable_parent_portal": true,
"technical_workshops": true,
"academic_calendar": {
"start_date": "2025-08-15",
"end_date": "2026-07-15"
}
}'::jsonb,
'{
"year_founded": 1982,
"cct": "19DST0042L",
"shift": "vespertino",
"grades": ["1", "2", "3"],
"specialties": ["Computación", "Electrónica", "Diseño Gráfico"],
"certifications": ["SEP", "CONOCER"],
"infrastructure": {
"library": true,
"computer_lab": true,
"electronics_workshop": true,
"design_studio": true
}
}'::jsonb,
NOW(),
NOW()
),
-- =====================================================================
-- Escuela 3: Colegio Científico "Albert Einstein" (Guadalajara)
-- Tipo: Privado | Enfoque: STEAM | Bilingüe
-- =====================================================================
(
'Colegio Científico "Albert Einstein"',
'CP-AE-JAL',
'private',
'Av. Chapultepec 890',
'Guadalajara',
'Jalisco',
'México',
'44100',
'33-3456-7890',
'info@colegioeinstein.edu.mx',
'https://colegioeinstein.edu.mx',
'Dra. Patricia Hernández',
'Lic. Miguel Ángel Torres',
'admisiones@colegioeinstein.edu.mx',
280,
24,
'active',
true,
'{
"allow_public_registration": false,
"require_email_verification": true,
"max_students_per_classroom": 25,
"enable_parent_portal": true,
"tuition_required": true,
"admission_process": {
"requires_interview": true,
"requires_exam": true,
"requires_documents": ["birth_certificate", "previous_grades", "recommendation_letters"]
},
"academic_calendar": {
"start_date": "2025-08-15",
"end_date": "2026-06-30"
}
}'::jsonb,
'{
"year_founded": 1995,
"accreditation": "SACS",
"bilingual": true,
"steam_focused": true,
"international_programs": ["Cambridge IGCSE"],
"partnerships": ["MIT", "Stanford Pre-Collegiate"],
"infrastructure": {
"library": true,
"computer_lab": true,
"science_lab": true,
"robotics_lab": true,
"innovation_hub": true,
"sports_complex": true,
"auditorium": true
},
"extracurricular": ["Robotics Club", "Science Olympiad", "Model UN", "Debate Team"]
}'::jsonb,
NOW(),
NOW()
)
ON CONFLICT (code) DO UPDATE SET
name = EXCLUDED.name,
email = EXCLUDED.email,
current_students_count = EXCLUDED.current_students_count,
current_teachers_count = EXCLUDED.current_teachers_count,
settings = EXCLUDED.settings,
metadata = EXCLUDED.metadata,
updated_at = NOW();
-- =====================================================================
-- Verificación de inserción
-- =====================================================================
DO $$
DECLARE
inserted_count INTEGER;
school_count INTEGER;
default_school_exists BOOLEAN;
BEGIN
SELECT COUNT(*) INTO inserted_count FROM social_features.schools;
RAISE NOTICE 'Total de escuelas en la base de datos: %', inserted_count;
SELECT COUNT(*) INTO school_count
FROM social_features.schools;
SELECT EXISTS(
SELECT 1 FROM social_features.schools
WHERE code = 'SYSTEM-UNASSIGNED' AND is_active = true
) INTO default_school_exists;
RAISE NOTICE '========================================';
RAISE NOTICE 'VERIFICACIÓN DE ESCUELAS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total escuelas: %', school_count;
RAISE NOTICE 'Escuela default existe: %', default_school_exists;
RAISE NOTICE '========================================';
IF default_school_exists THEN
RAISE NOTICE '✓ Escuela default (SYSTEM-UNASSIGNED) configurada correctamente';
RAISE NOTICE ' Las demás escuelas serán creadas por el admin desde la UI';
ELSE
RAISE WARNING '⚠ Escuela default NO encontrada. Ejecutar 00-schools-default.sql primero';
END IF;
END $$;

View File

@ -1,349 +1,239 @@
-- =====================================================================
-- Archivo: 02-classrooms.sql
-- Schema: social_features
-- Descripción: Seeds de aulas/grupos para las escuelas
-- Dependencias: 01-schools.sql, auth.users
-- Autor: SA-SEEDS-SOCIAL
-- Fecha: 2025-11-02
-- =====================================================================
-- =====================================================
-- Seed: social_features.classrooms (DEV)
-- Description: SOLO classroom default para asignación automática
-- Environment: DEVELOPMENT
-- Dependencies: social_features.schools (00-schools-default.sql), auth_management.profiles
-- Order: 02
-- Created: 2025-01-11
-- Updated: 2025-12-15 - Simplificado a solo DEFAULT
-- Version: 3.0
-- =====================================================
--
-- AULAS INCLUIDAS:
-- - Sin Asignar (DEFAULT - Sistema) - Única aula del sistema
--
-- TOTAL: 1 aula (sistema)
--
-- DECISIÓN DE DISEÑO:
-- - Solo existe el classroom default para asignación automática
-- - Todas las aulas adicionales serán creadas por el admin desde la UI
-- - Los estudiantes nuevos se asignan automáticamente aquí
--
-- AULAS DEMO REMOVIDAS (v3.0):
-- - 5to A (Marie Curie) - REMOVIDA
-- - 5to B (Marie Curie) - REMOVIDA
-- - 6to A (Marie Curie) - REMOVIDA
-- - Aula de Pruebas (IEI) - REMOVIDA
-- - Demo Parent Portal (IEI) - REMOVIDA
--
-- =====================================================
SET search_path TO social_features, auth, public;
SET search_path TO social_features, auth_management, public;
-- =====================================================================
-- CLASSROOMS: Aulas/grupos distribuidos por escuelas
-- =====================================================================
-- =====================================================
-- Obtener tenant_id y validar dependencias
-- =====================================================
DO $$
DECLARE
school_sf15 UUID;
school_st42 UUID;
school_einstein UUID;
teacher_id UUID;
v_tenant_id UUID;
v_default_school_id UUID;
v_teacher_id UUID;
BEGIN
-- =====================================================================
-- Obtener school IDs dinámicamente
-- =====================================================================
SELECT school_id INTO school_sf15
FROM social_features.schools
WHERE school_code = 'SF-015-CDMX';
-- Obtener el tenant principal
SELECT id INTO v_tenant_id
FROM auth_management.tenants
WHERE name = 'GAMILIT Platform'
LIMIT 1;
SELECT school_id INTO school_st42
FROM social_features.schools
WHERE school_code = 'ST-042-NL';
SELECT school_id INTO school_einstein
FROM social_features.schools
WHERE school_code = 'CP-AE-JAL';
-- =====================================================================
-- Obtener instructor demo
-- =====================================================================
SELECT user_id INTO teacher_id
FROM auth.users
WHERE email = 'instructor@demo.glit.edu.mx';
-- Validar que exista el instructor
IF teacher_id IS NULL THEN
RAISE EXCEPTION 'No se encontró el instructor demo. Ejecutar seeds de auth primero.';
IF v_tenant_id IS NULL THEN
RAISE EXCEPTION 'Tenant "GAMILIT Platform" no encontrado. Ejecutar primero seed de tenants.';
END IF;
-- =====================================================================
-- AULAS PARA SECUNDARIA FEDERAL 15 (CDMX)
-- =====================================================================
-- Obtener la escuela default
SELECT id INTO v_default_school_id
FROM social_features.schools
WHERE code = 'SYSTEM-UNASSIGNED' AND is_active = true
LIMIT 1;
-- Aula 1: 2° A - Comprensión Lectora
INSERT INTO social_features.classrooms (
school_id, teacher_id,
name, code, grade_level, section,
subject, description,
capacity, current_students_count,
start_date, end_date,
schedule, is_active, is_active,
settings, created_at, updated_at
) VALUES
(
school_sf15,
teacher_id,
'2° A - Comprensión Lectora',
'2A-LECT-2025',
'2',
'A',
'Comprensión Lectora',
'Grupo de segundo año, sección A. Enfoque en desarrollo de competencias lectoras con metodología GLIT. Estrategias de lectura crítica y análisis textual.',
35,
0,
'2025-08-15',
'2026-07-15',
'{
"days": ["Lunes", "Miércoles", "Viernes"],
"time": "08:00-09:00",
"room": "Aula 201",
"weekly_hours": 3
}'::jsonb,
'active',
true,
'{
"allow_student_self_enrollment": false,
"enable_gamification": true,
"require_parental_consent": true,
"grading_system": "numerical",
"attendance_required": true,
"homework_policy": {
"frequency": "weekly",
"submission_platform": "glit"
}
}'::jsonb,
NOW(),
NOW()
IF v_default_school_id IS NULL THEN
RAISE EXCEPTION 'Escuela default (SYSTEM-UNASSIGNED) no encontrada. Ejecutar primero 00-schools-default.sql';
END IF;
-- Obtener el teacher default (teacher@gamilit.com)
SELECT id INTO v_teacher_id
FROM auth_management.profiles
WHERE email = 'teacher@gamilit.com'
LIMIT 1;
IF v_teacher_id IS NULL THEN
-- Usar el UUID conocido como fallback
v_teacher_id := 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'::uuid;
RAISE WARNING 'Teacher default no encontrado, usando UUID: %', v_teacher_id;
END IF;
RAISE NOTICE 'Usando tenant_id: %', v_tenant_id;
RAISE NOTICE 'Usando school_id (default): %', v_default_school_id;
RAISE NOTICE 'Usando teacher_id: %', v_teacher_id;
-- =====================================================
-- INSERT: SOLO Classroom DEFAULT
-- =====================================================
INSERT INTO social_features.classrooms (
id,
school_id,
tenant_id,
teacher_id,
name,
code,
grade_level,
section,
subject,
description,
capacity,
current_students_count,
start_date,
end_date,
schedule,
is_active,
settings,
metadata,
created_at,
updated_at
) VALUES
-- =====================================================
-- CLASSROOM DEFAULT (Sistema - Sin Asignar)
-- IMPORTANTE: Este classroom es usado automáticamente para
-- asignar estudiantes nuevos que aún no tienen aula.
-- =====================================================
(
'00000000-0000-0000-0000-000000000001'::uuid, -- UUID predecible para default
v_default_school_id, -- Escuela Sistema - Por Asignar (default)
v_tenant_id,
v_teacher_id, -- Teacher default (teacher@gamilit.com)
'Sin Asignar - Aula Default',
'DEFAULT',
'todos', -- Todos los niveles
'DEFAULT',
'General',
'Aula de sistema para estudiantes pendientes de asignación. Los administradores y profesores pueden reasignar estudiantes a aulas específicas.',
999, -- Capacidad alta para no limitar
0,
'2025-01-01'::date,
'2099-12-31'::date, -- Sin fecha de fin
jsonb_build_object(
'days', jsonb_build_array('Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes'),
'time', 'flexible',
'room', 'Virtual',
'weekly_hours', 0
),
-- Aula 2: 3° B - Lectura Digital
(
school_sf15,
teacher_id,
'3° B - Lectura Digital',
'3B-DIGI-2025',
'3',
'B',
'Lectura Digital',
'Grupo de tercer año, sección B. Especialización en alfabetización digital, fact-checking y análisis crítico de medios digitales.',
35,
0,
'2025-08-15',
'2026-07-15',
'{
"days": ["Martes", "Jueves"],
"time": "10:00-11:30",
"room": "Laboratorio de Cómputo",
"weekly_hours": 3
}'::jsonb,
'active',
true,
'{
"allow_student_self_enrollment": false,
"enable_gamification": true,
"require_parental_consent": true,
"grading_system": "numerical",
"attendance_required": true,
"digital_literacy_focus": true,
"tools_used": ["GLIT", "Google Classroom", "Canva"]
}'::jsonb,
NOW(),
NOW()
true,
jsonb_build_object(
'allow_student_self_enrollment', false,
'enable_gamification', true,
'require_parental_consent', false,
'grading_system', 'none',
'attendance_required', false,
'is_system_classroom', true
),
-- Aula 3: 1° C - Lectura Básica
(
school_sf15,
teacher_id,
'1° C - Lectura Básica',
'1C-BASIC-2025',
'1',
'C',
'Lectura Básica',
'Primer año, sección C. Fundamentos de comprensión lectora y desarrollo de habilidades básicas.',
35,
0,
'2025-08-15',
'2026-07-15',
'{
"days": ["Lunes", "Miércoles", "Viernes"],
"time": "11:00-12:00",
"room": "Aula 105",
"weekly_hours": 3
}'::jsonb,
'active',
true,
'{
"allow_student_self_enrollment": false,
"enable_gamification": true,
"require_parental_consent": true,
"grading_system": "numerical",
"attendance_required": true,
"foundational_skills": true
}'::jsonb,
NOW(),
NOW()
jsonb_build_object(
'is_default', true,
'system_classroom', true,
'auto_assignment', true,
'description', 'Classroom para asignación automática de estudiantes nuevos'
),
-- =====================================================================
-- AULAS PARA SECUNDARIA TÉCNICA 42 (MONTERREY)
-- =====================================================================
-- Aula 4: 1° A - Introducción a la Lectura
(
school_st42,
teacher_id,
'1° A - Introducción a la Lectura',
'1A-INTRO-2025',
'1',
'A',
'Introducción a la Lectura',
'Primer año. Desarrollo de habilidades básicas de comprensión lectora con enfoque técnico y práctico.',
30,
0,
'2025-08-15',
'2026-07-15',
'{
"days": ["Lunes", "Miércoles", "Viernes"],
"time": "14:00-15:00",
"room": "Aula 105",
"weekly_hours": 3,
"shift": "vespertino"
}'::jsonb,
'active',
true,
'{
"allow_student_self_enrollment": false,
"enable_gamification": true,
"require_parental_consent": true,
"grading_system": "numerical",
"technical_reading_focus": true
}'::jsonb,
NOW(),
NOW()
),
-- Aula 5: 2° B - Lectura Técnica
(
school_st42,
teacher_id,
'2° B - Lectura Técnica',
'2B-TECH-2025',
'2',
'B',
'Lectura Técnica',
'Segundo año. Comprensión de textos técnicos, manuales y documentación especializada.',
30,
0,
'2025-08-15',
'2026-07-15',
'{
"days": ["Martes", "Jueves"],
"time": "15:00-16:30",
"room": "Taller de Computación",
"weekly_hours": 3,
"shift": "vespertino"
}'::jsonb,
'active',
true,
'{
"allow_student_self_enrollment": false,
"enable_gamification": true,
"technical_manuals": true,
"industry_standards": ["ISO", "IEEE"]
}'::jsonb,
NOW(),
NOW()
),
-- =====================================================================
-- AULAS PARA COLEGIO EINSTEIN (GUADALAJARA)
-- =====================================================================
-- Aula 6: 2° STEAM - Literatura Científica
(
school_einstein,
teacher_id,
'2° STEAM - Literatura Científica',
'2ST-LITC-2025',
'2',
'STEAM',
'Literatura Científica',
'Grupo STEAM. Integración de literatura y ciencias mediante biografías de científicos, ensayos y divulgación científica.',
25,
0,
'2025-08-15',
'2026-06-30',
'{
"days": ["Lunes", "Miércoles", "Viernes"],
"time": "09:00-10:30",
"room": "Aula STEAM 3",
"language": "Español/Inglés",
"weekly_hours": 4
}'::jsonb,
'active',
true,
'{
"allow_student_self_enrollment": false,
"enable_gamification": true,
"require_parental_consent": false,
"bilingual": true,
"grading_system": "cambridge",
"steam_integration": true,
"project_based_learning": true
}'::jsonb,
NOW(),
NOW()
),
-- Aula 7: 3° Advanced - Critical Reading (Bilingüe)
(
school_einstein,
teacher_id,
'3° Advanced - Critical Reading',
'3ADV-CRIT-2025',
'3',
'Advanced',
'Critical Reading',
'Tercer año avanzado. Lectura crítica en inglés y español con análisis de textos complejos y retórica.',
25,
0,
'2025-08-15',
'2026-06-30',
'{
"days": ["Martes", "Jueves"],
"time": "11:00-12:30",
"room": "Innovation Hub",
"language": "English/Spanish",
"weekly_hours": 3
}'::jsonb,
'active',
true,
'{
"allow_student_self_enrollment": false,
"enable_gamification": true,
"bilingual": true,
"grading_system": "cambridge",
"advanced_placement": true,
"college_prep": true,
"debate_integration": true
}'::jsonb,
NOW(),
NOW()
)
ON CONFLICT (school_id, code) DO UPDATE SET
name = EXCLUDED.name,
current_students_count = EXCLUDED.current_students_count,
schedule = EXCLUDED.schedule,
settings = EXCLUDED.settings,
updated_at = NOW();
-- =====================================================================
-- SYNC teacher_classrooms (many-to-many)
-- =====================================================================
-- Asegurar que todos los classrooms tienen su entrada en teacher_classrooms
-- Esto es necesario porque algunos servicios usan classrooms.teacher_id
-- y otros usan la tabla teacher_classrooms
-- =====================================================================
INSERT INTO social_features.teacher_classrooms (id, teacher_id, classroom_id, tenant_id, role, assigned_at, created_at)
SELECT
gen_random_uuid(),
c.teacher_id,
c.id,
c.tenant_id,
'owner',
c.created_at,
NOW()
FROM social_features.classrooms c
WHERE c.teacher_id IS NOT NULL
ON CONFLICT DO NOTHING;
-- =====================================================================
-- Verificación de inserción
-- =====================================================================
RAISE NOTICE 'Aulas creadas exitosamente para 3 escuelas';
RAISE NOTICE 'SF-015-CDMX: 3 aulas | ST-042-NL: 2 aulas | CP-AE-JAL: 2 aulas';
RAISE NOTICE 'Sincronización teacher_classrooms ejecutada';
gamilit.now_mexico(),
gamilit.now_mexico()
)
ON CONFLICT (code) DO UPDATE SET
school_id = EXCLUDED.school_id,
name = EXCLUDED.name,
description = EXCLUDED.description,
capacity = EXCLUDED.capacity,
is_active = EXCLUDED.is_active,
settings = EXCLUDED.settings,
metadata = EXCLUDED.metadata,
updated_at = gamilit.now_mexico();
END $$;
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
classroom_count INTEGER;
default_classroom_exists BOOLEAN;
default_classroom RECORD;
BEGIN
SELECT COUNT(*) INTO classroom_count
FROM social_features.classrooms;
SELECT EXISTS(
SELECT 1 FROM social_features.classrooms
WHERE code = 'DEFAULT' AND is_active = true
) INTO default_classroom_exists;
SELECT c.id, c.name, c.code, s.name as school_name
INTO default_classroom
FROM social_features.classrooms c
JOIN social_features.schools s ON c.school_id = s.id
WHERE c.code = 'DEFAULT';
RAISE NOTICE '========================================';
RAISE NOTICE 'VERIFICACIÓN DE CLASSROOMS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total classrooms: %', classroom_count;
RAISE NOTICE 'Classroom default existe: %', default_classroom_exists;
IF default_classroom_exists THEN
RAISE NOTICE '========================================';
RAISE NOTICE 'CLASSROOM DEFAULT:';
RAISE NOTICE ' ID: %', default_classroom.id;
RAISE NOTICE ' Nombre: %', default_classroom.name;
RAISE NOTICE ' Código: %', default_classroom.code;
RAISE NOTICE ' Escuela: %', default_classroom.school_name;
RAISE NOTICE '========================================';
RAISE NOTICE '✓ Classroom default configurado correctamente';
RAISE NOTICE ' Las demás aulas serán creadas por el admin desde la UI';
ELSE
RAISE WARNING '⚠ Classroom default NO encontrado';
END IF;
END $$;
-- =====================================================
-- SYNC teacher_classrooms (many-to-many)
-- =====================================================
-- Asegurar que el classroom default tiene su entrada en teacher_classrooms
-- =====================================================
INSERT INTO social_features.teacher_classrooms (id, teacher_id, classroom_id, tenant_id, role, assigned_at, created_at)
SELECT
gen_random_uuid(),
c.teacher_id,
c.id,
c.tenant_id,
'owner',
c.created_at,
NOW()
FROM social_features.classrooms c
WHERE c.teacher_id IS NOT NULL
AND c.code = 'DEFAULT'
ON CONFLICT DO NOTHING;
-- Verificar sync
DO $$
DECLARE
tc_count INTEGER;
BEGIN
SELECT COUNT(*) INTO tc_count
FROM social_features.teacher_classrooms tc
JOIN social_features.classrooms c ON tc.classroom_id = c.id
WHERE c.code = 'DEFAULT';
RAISE NOTICE '';
RAISE NOTICE 'teacher_classrooms sincronizados para DEFAULT: %', tc_count;
RAISE NOTICE '========================================';
END $$;

View File

@ -1,335 +1,196 @@
-- =====================================================================
-- Archivo: 03-classroom-members.sql
-- Schema: social_features
-- Descripción: Seeds de membresías de estudiantes a aulas
-- Dependencias: 02-classrooms.sql, auth.users (estudiantes)
-- Autor: SA-SEEDS-SOCIAL
-- Fecha: 2025-11-02
-- =====================================================================
-- =====================================================
-- Seed: social_features.classroom_members (DEV)
-- Description: Asignar TODOS los estudiantes al classroom DEFAULT
-- Environment: DEVELOPMENT
-- Dependencies: social_features.classrooms (02-classrooms.sql), auth_management.profiles
-- Order: 03
-- Created: 2025-01-11
-- Updated: 2025-12-15 - Simplificado a solo DEFAULT
-- Version: 3.0
-- =====================================================
--
-- DECISIÓN DE DISEÑO:
-- - Todos los estudiantes se asignan automáticamente al classroom DEFAULT
-- - El admin/teacher puede reasignarlos a otros classrooms desde la UI
-- - Esto facilita la gestión inicial de usuarios nuevos
--
-- ASOCIACIONES DEMO REMOVIDAS (v3.0):
-- - Todas las asociaciones específicas - REMOVIDAS
--
-- =====================================================
SET search_path TO social_features, auth, public;
SET search_path TO social_features, auth_management, public;
-- =====================================================================
-- CLASSROOM MEMBERS: Asignar estudiantes demo a aulas
-- =====================================================================
-- =====================================================
-- Asignar TODOS los estudiantes al classroom DEFAULT
-- =====================================================
DO $$
DECLARE
classroom_2a UUID;
classroom_3b UUID;
classroom_1c UUID;
classroom_1a UUID;
classroom_2b UUID;
classroom_2st UUID;
classroom_3adv UUID;
student1_id UUID;
student2_id UUID;
student3_id UUID;
enrolled_count INTEGER;
v_default_classroom_id UUID;
v_student_count INTEGER;
v_assigned_count INTEGER;
rec RECORD;
BEGIN
-- =====================================================================
-- Obtener classroom IDs dinámicamente
-- =====================================================================
SELECT classroom_id INTO classroom_2a
-- Obtener el classroom DEFAULT
SELECT id INTO v_default_classroom_id
FROM social_features.classrooms
WHERE classroom_code = '2A-LECT-2025';
WHERE code = 'DEFAULT' AND is_active = true
LIMIT 1;
SELECT classroom_id INTO classroom_3b
FROM social_features.classrooms
WHERE classroom_code = '3B-DIGI-2025';
SELECT classroom_id INTO classroom_1c
FROM social_features.classrooms
WHERE classroom_code = '1C-BASIC-2025';
SELECT classroom_id INTO classroom_1a
FROM social_features.classrooms
WHERE classroom_code = '1A-INTRO-2025';
SELECT classroom_id INTO classroom_2b
FROM social_features.classrooms
WHERE classroom_code = '2B-TECH-2025';
SELECT classroom_id INTO classroom_2st
FROM social_features.classrooms
WHERE classroom_code = '2ST-LITC-2025';
SELECT classroom_id INTO classroom_3adv
FROM social_features.classrooms
WHERE classroom_code = '3ADV-CRIT-2025';
-- =====================================================================
-- Obtener student IDs
-- =====================================================================
SELECT user_id INTO student1_id
FROM auth.users
WHERE email = 'estudiante1@demo.glit.edu.mx';
SELECT user_id INTO student2_id
FROM auth.users
WHERE email = 'estudiante2@demo.glit.edu.mx';
SELECT user_id INTO student3_id
FROM auth.users
WHERE email = 'estudiante3@demo.glit.edu.mx';
-- Validar que existan los estudiantes
IF student1_id IS NULL OR student2_id IS NULL OR student3_id IS NULL THEN
RAISE EXCEPTION 'No se encontraron todos los estudiantes demo. Ejecutar seeds de auth primero.';
IF v_default_classroom_id IS NULL THEN
RAISE EXCEPTION 'Classroom DEFAULT no encontrado. Ejecutar primero 02-classrooms.sql';
END IF;
-- =====================================================================
-- MEMBRESÍAS PARA ESTUDIANTE 1
-- Perfil: Estudiante activo, inscrito en múltiples aulas
-- =====================================================================
RAISE NOTICE 'Usando classroom DEFAULT: %', v_default_classroom_id;
-- Estudiante 1 → Aula 2° A (Secundaria Federal 15)
-- Contar estudiantes existentes
SELECT COUNT(*) INTO v_student_count
FROM auth_management.profiles
WHERE role = 'student';
RAISE NOTICE 'Estudiantes encontrados: %', v_student_count;
-- Asignar cada estudiante al classroom DEFAULT
INSERT INTO social_features.classroom_members (
classroom_id, user_id, role,
joined_at, is_active, is_active,
settings, metadata, created_at, updated_at
) VALUES
(
classroom_2a,
student1_id,
'student',
'2025-08-15',
'active',
true,
'{
"attendance_tracking": true,
"grade_visibility": true,
"notifications_enabled": true,
"preferred_communication": "email"
}'::jsonb,
'{
"enrollment_type": "regular",
"previous_performance": "excellent",
"special_needs": false
}'::jsonb,
NOW(),
NOW()
),
-- Estudiante 1 → Aula 3° B (Multi-enrollment)
(
classroom_3b,
student1_id,
'student',
'2025-08-20',
'active',
true,
'{
"attendance_tracking": true,
"grade_visibility": true,
"notifications_enabled": true,
"preferred_communication": "email"
}'::jsonb,
'{
"enrollment_type": "advanced_placement",
"reason": "Alto desempeño en lectura digital"
}'::jsonb,
NOW(),
NOW()
),
-- =====================================================================
-- MEMBRESÍAS PARA ESTUDIANTE 2
-- Perfil: Estudiante de secundaria técnica
-- =====================================================================
-- Estudiante 2 → Aula 3° B (Secundaria Federal 15)
(
classroom_3b,
student2_id,
'student',
'2025-08-15',
'active',
true,
'{
"attendance_tracking": true,
"grade_visibility": true,
"notifications_enabled": true,
"preferred_communication": "sms"
}'::jsonb,
'{
"enrollment_type": "regular",
"previous_performance": "good",
"special_needs": false
}'::jsonb,
NOW(),
NOW()
),
-- Estudiante 2 → Aula 2° B Técnica (Secundaria Técnica 42)
(
classroom_2b,
student2_id,
'student',
'2025-08-15',
'active',
true,
'{
"attendance_tracking": true,
"grade_visibility": true,
"notifications_enabled": true,
"workshop_access": true
}'::jsonb,
'{
"enrollment_type": "technical_specialty",
"specialty": "Computación",
"workshop_schedule": "Lunes y Miércoles 16:00-18:00"
}'::jsonb,
NOW(),
NOW()
),
-- =====================================================================
-- MEMBRESÍAS PARA ESTUDIANTE 3
-- Perfil: Estudiante de primer año
-- =====================================================================
-- Estudiante 3 → Aula 1° A (Secundaria Técnica 42)
(
classroom_1a,
student3_id,
'student',
'2025-08-15',
'active',
true,
'{
"attendance_tracking": true,
"grade_visibility": true,
"notifications_enabled": true,
"parental_monitoring": true
}'::jsonb,
'{
"enrollment_type": "regular",
"is_first_year": true,
"orientation_completed": true,
"parent_contact": "padre3@demo.glit.edu.mx"
}'::jsonb,
NOW(),
NOW()
),
-- Estudiante 3 → Aula 1° C Básica (Secundaria Federal 15)
(
classroom_1c,
student3_id,
'student',
'2025-08-18',
'active',
true,
'{
"attendance_tracking": true,
"grade_visibility": true,
"notifications_enabled": true,
"parental_monitoring": true
}'::jsonb,
'{
"enrollment_type": "regular",
"is_first_year": true,
"foundational_support": true
}'::jsonb,
NOW(),
NOW()
),
-- =====================================================================
-- MEMBRESÍAS ADICIONALES PARA VARIEDAD
-- =====================================================================
-- Estudiante 1 → Aula STEAM (Colegio Einstein)
(
classroom_2st,
student1_id,
'student',
'2025-08-15',
'active',
true,
'{
"attendance_tracking": true,
"grade_visibility": true,
"notifications_enabled": true,
"bilingual_mode": true
}'::jsonb,
'{
"enrollment_type": "steam_program",
"scholarship": true,
"stem_projects_enrolled": ["Biografías Científicas", "Science Fair"]
}'::jsonb,
NOW(),
NOW()
),
-- Estudiante 2 → Aula Advanced (Colegio Einstein)
(
classroom_3adv,
student2_id,
'student',
'2025-08-15',
'active',
true,
'{
"attendance_tracking": true,
"grade_visibility": true,
"notifications_enabled": true,
"bilingual_mode": true,
"advanced_resources": true
}'::jsonb,
'{
"enrollment_type": "advanced_placement",
"cambridge_candidate": true,
"debate_team": true
}'::jsonb,
NOW(),
NOW()
id,
classroom_id,
student_id,
enrollment_date,
enrollment_method,
status,
attendance_percentage,
metadata,
created_at,
updated_at
)
ON CONFLICT (classroom_id, user_id) DO UPDATE SET
status = EXCLUDED.is_active,
settings = EXCLUDED.settings,
metadata = EXCLUDED.metadata,
updated_at = NOW();
SELECT
gen_random_uuid(),
v_default_classroom_id,
p.id,
gamilit.now_mexico(),
'admin_add', -- Valid values: teacher_invite, self_enroll, admin_add, bulk_import
'active',
0.00,
jsonb_build_object(
'enrollment_type', 'auto',
'auto_assigned', true,
'enrolled_by', 'seed_script',
'assigned_to_default', true,
'pending_reassignment', true
),
gamilit.now_mexico(),
gamilit.now_mexico()
FROM auth_management.profiles p
WHERE p.role = 'student'
ON CONFLICT (classroom_id, student_id) DO UPDATE SET
status = 'active',
metadata = EXCLUDED.metadata || jsonb_build_object('updated_by_seed', true),
updated_at = gamilit.now_mexico();
-- =====================================================================
-- Actualizar enrollment counts en classrooms
-- =====================================================================
UPDATE social_features.classrooms
SET current_enrollment = (
SELECT COUNT(*)
FROM social_features.classroom_members
WHERE classroom_members.classroom_id = classrooms.classroom_id
AND status = 'active'
)
WHERE classroom_id IN (
classroom_2a, classroom_3b, classroom_1c,
classroom_1a, classroom_2b,
classroom_2st, classroom_3adv
);
GET DIAGNOSTICS v_assigned_count = ROW_COUNT;
-- =====================================================================
-- Verificación de inserción
-- =====================================================================
SELECT COUNT(*) INTO enrolled_count
FROM social_features.classroom_members
WHERE status = 'active';
RAISE NOTICE 'Total de membresías activas creadas: %', enrolled_count;
RAISE NOTICE 'Estudiante 1: % aulas', (
SELECT COUNT(*)
FROM social_features.classroom_members
WHERE user_id = student1_id AND status = 'active'
);
RAISE NOTICE 'Estudiante 2: % aulas', (
SELECT COUNT(*)
FROM social_features.classroom_members
WHERE user_id = student2_id AND status = 'active'
);
RAISE NOTICE 'Estudiante 3: % aulas', (
SELECT COUNT(*)
FROM social_features.classroom_members
WHERE user_id = student3_id AND status = 'active'
);
RAISE NOTICE '========================================';
RAISE NOTICE 'ASIGNACIÓN DE ESTUDIANTES A DEFAULT';
RAISE NOTICE '========================================';
RAISE NOTICE 'Classroom DEFAULT ID: %', v_default_classroom_id;
RAISE NOTICE 'Estudiantes asignados: %', v_assigned_count;
RAISE NOTICE '========================================';
END $$;
-- =====================================================
-- Actualizar current_students_count en classroom DEFAULT
-- =====================================================
UPDATE social_features.classrooms
SET current_students_count = (
SELECT COUNT(*)
FROM social_features.classroom_members
WHERE classroom_id = classrooms.id
AND status = 'active'
)
WHERE code = 'DEFAULT';
-- =====================================================
-- Verification Query
-- =====================================================
DO $$
DECLARE
member_count INTEGER;
default_count INTEGER;
classroom_students INTEGER;
BEGIN
-- Total membresías
SELECT COUNT(*) INTO member_count
FROM social_features.classroom_members;
-- Membresías en classroom DEFAULT
SELECT COUNT(*) INTO default_count
FROM social_features.classroom_members cm
JOIN social_features.classrooms c ON c.id = cm.classroom_id
WHERE c.code = 'DEFAULT';
-- Count en el classroom
SELECT current_students_count INTO classroom_students
FROM social_features.classrooms
WHERE code = 'DEFAULT';
RAISE NOTICE '========================================';
RAISE NOTICE 'VERIFICACIÓN DE CLASSROOM_MEMBERS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total membresías: %', member_count;
RAISE NOTICE 'Estudiantes en DEFAULT: %', default_count;
RAISE NOTICE 'current_students_count: %', classroom_students;
RAISE NOTICE '========================================';
IF default_count = member_count THEN
RAISE NOTICE '✓ Todos los estudiantes están en el classroom DEFAULT';
RAISE NOTICE ' El admin puede reasignarlos desde la UI';
ELSE
RAISE WARNING '⚠ Hay membresías en otros classrooms';
END IF;
END $$;
-- =====================================================
-- Listado de estudiantes asignados
-- =====================================================
DO $$
DECLARE
member_record RECORD;
total_students INTEGER := 0;
BEGIN
RAISE NOTICE '';
RAISE NOTICE 'Estudiantes asignados al classroom DEFAULT:';
RAISE NOTICE '========================================';
FOR member_record IN
SELECT
p.display_name,
p.email,
cm.enrollment_date,
cm.status
FROM social_features.classroom_members cm
JOIN auth_management.profiles p ON p.id = cm.student_id
JOIN social_features.classrooms c ON c.id = cm.classroom_id
WHERE c.code = 'DEFAULT'
ORDER BY p.display_name
LIMIT 20 -- Limitar output para no saturar
LOOP
RAISE NOTICE ' - % <%> [%]',
member_record.display_name,
member_record.email,
member_record.status;
total_students := total_students + 1;
END LOOP;
IF total_students = 0 THEN
RAISE NOTICE ' (No hay estudiantes asignados aún)';
ELSIF total_students = 20 THEN
RAISE NOTICE ' ... (mostrando primeros 20)';
END IF;
RAISE NOTICE '========================================';
END $$;

View File

@ -0,0 +1,115 @@
-- =====================================================
-- Seed: social_features.friendships (PROD) - v1.2
-- Description: Relaciones de amistad entre usuarios de producción
-- Environment: PRODUCTION
-- Dependencies: auth_management.profiles (usuarios de producción)
-- Order: 04
-- Created: 2025-11-15
-- Updated: 2025-12-14 (v1.2 - Ajustado al DDL actual, usa usuarios prod)
-- Version: 1.2
-- =====================================================
--
-- CAMBIOS v1.2:
-- - Eliminadas columnas status y updated_at (no existen en DDL)
-- - Cambiado a usar UUIDs de usuarios de producción reales
-- - El DDL actual solo tiene: id, user_id, friend_id, created_at
--
-- NOTA: En este modelo simplificado, una entrada en friendships
-- significa que la amistad está ACEPTADA. Las solicitudes pendientes
-- se manejarían en una tabla separada (friend_requests) si se necesita.
--
-- FRIENDSHIPS INCLUIDOS:
-- - Relaciones bidireccionales entre usuarios de producción
--
-- IMPORTANTE: Este seed habilita testing de:
-- - /friends page (FriendsPage.tsx)
-- - FriendsLeaderboard component
-- =====================================================
SET search_path TO social_features, auth_management, public;
-- =====================================================
-- INSERT: Friendships entre usuarios de producción
-- =====================================================
-- Usamos los UUIDs reales de los usuarios de producción
DO $$
DECLARE
user_ids uuid[];
i INTEGER;
j INTEGER;
friendship_count INTEGER := 0;
BEGIN
-- Obtener IDs de usuarios de producción (excluyendo testing @gamilit.com)
SELECT ARRAY_AGG(id ORDER BY created_at)
INTO user_ids
FROM auth_management.profiles
WHERE email NOT LIKE '%@gamilit.com'
LIMIT 10;
-- Si hay al menos 2 usuarios, crear friendships
IF array_length(user_ids, 1) >= 2 THEN
-- Crear friendships bidireccionales entre los primeros usuarios
FOR i IN 1..LEAST(array_length(user_ids, 1) - 1, 5) LOOP
FOR j IN (i + 1)..LEAST(array_length(user_ids, 1), i + 2) LOOP
-- Insertar relación bidireccional
INSERT INTO social_features.friendships (user_id, friend_id, created_at)
VALUES (user_ids[i], user_ids[j], gamilit.now_mexico() - (random() * INTERVAL '30 days'))
ON CONFLICT (user_id, friend_id) DO NOTHING;
INSERT INTO social_features.friendships (user_id, friend_id, created_at)
VALUES (user_ids[j], user_ids[i], gamilit.now_mexico() - (random() * INTERVAL '30 days'))
ON CONFLICT (user_id, friend_id) DO NOTHING;
friendship_count := friendship_count + 2;
END LOOP;
END LOOP;
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE 'FRIENDSHIPS CREADOS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Relaciones creadas: %', friendship_count;
RAISE NOTICE 'Usuarios disponibles: %', array_length(user_ids, 1);
RAISE NOTICE '========================================';
ELSE
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE 'FRIENDSHIPS: Sin usuarios suficientes';
RAISE NOTICE '========================================';
RAISE NOTICE 'Se necesitan al menos 2 usuarios de producción';
RAISE NOTICE 'Usuarios encontrados: %', COALESCE(array_length(user_ids, 1), 0);
RAISE NOTICE '========================================';
END IF;
END $$;
-- =====================================================
-- Verification
-- =====================================================
DO $$
DECLARE
total_count INTEGER;
BEGIN
SELECT COUNT(*) INTO total_count
FROM social_features.friendships;
RAISE NOTICE '';
RAISE NOTICE '========================================';
RAISE NOTICE 'VERIFICACIÓN FRIENDSHIPS';
RAISE NOTICE '========================================';
RAISE NOTICE 'Total friendships en tabla: %', total_count;
RAISE NOTICE '========================================';
IF total_count > 0 THEN
RAISE NOTICE '✓ Friendships creados correctamente';
RAISE NOTICE '';
RAISE NOTICE 'Features habilitadas:';
RAISE NOTICE ' - /friends page (FriendsPage.tsx)';
RAISE NOTICE ' - FriendsLeaderboard component';
ELSE
RAISE NOTICE '⚠ No hay friendships (normal si no hay usuarios prod)';
END IF;
RAISE NOTICE '';
END $$;

Some files were not shown because too many files have changed in this diff Show More