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
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:
parent
e360b88612
commit
608e1e2a2e
@ -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
|
||||
336
orchestration/INDICE-DIRECTIVAS-WORKSPACE.yml
Normal file
336
orchestration/INDICE-DIRECTIVAS-WORKSPACE.yml
Normal 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"
|
||||
268
orchestration/directivas/DIRECTIVA-CARGA-CONTEXTO.md
Normal file
268
orchestration/directivas/DIRECTIVA-CARGA-CONTEXTO.md
Normal 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
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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'),
|
||||
|
||||
@ -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: [
|
||||
|
||||
@ -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],
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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', {
|
||||
|
||||
@ -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' })
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 })
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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[];
|
||||
}
|
||||
|
||||
@ -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';
|
||||
*/
|
||||
|
||||
@ -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[];
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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[];
|
||||
}
|
||||
@ -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';
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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,14 +15,16 @@ export class CreatePurchaseDto {
|
||||
example: '550e8400-e29b-41d4-a716-446655440000',
|
||||
description: 'ID del usuario comprador',
|
||||
})
|
||||
@IsUUID()
|
||||
@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()
|
||||
@IsString({ message: 'item_id debe ser un string' })
|
||||
@Matches(UUID_REGEX, { message: 'item_id debe tener formato UUID válido' })
|
||||
item_id!: string;
|
||||
|
||||
@ApiProperty({
|
||||
|
||||
@ -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
|
||||
// =====================================================
|
||||
|
||||
@ -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%)
|
||||
|
||||
@ -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,69 +267,261 @@ 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>;
|
||||
|
||||
try {
|
||||
switch (type) {
|
||||
case 'progress':
|
||||
return (
|
||||
userStats.exercises_completed >= (cond.exercises_completed || 0) &&
|
||||
userStats.modules_completed >= (cond.modules_completed || 0)
|
||||
// =====================================================
|
||||
// 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;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// 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;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// 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;
|
||||
|
||||
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 'streak':
|
||||
return userStats.current_streak >= (cond.min_streak || 0);
|
||||
if (!result || result.length === 0) {
|
||||
this.logger.debug(`[module_completion] No progress found for module ${r.module_id}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// 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 >= (cond.min_level || 0);
|
||||
return userStats.level >= ((reqs as Record<string, number>).min_level || 0);
|
||||
|
||||
case 'score':
|
||||
return (
|
||||
(userStats.average_score || 0) >= (cond.min_average_score || 0) &&
|
||||
userStats.perfect_scores >= (cond.min_perfect_scores || 0)
|
||||
(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, cond.target_rank || '');
|
||||
return this.userReachedRank(userStats.current_rank, (reqs as Record<string, string>).target_rank || '');
|
||||
|
||||
case 'ml_coins':
|
||||
return userStats.ml_coins_earned_total >= (cond.min_coins_earned || 0);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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 },
|
||||
];
|
||||
|
||||
|
||||
@ -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',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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>,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
*
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
// 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))
|
||||
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 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,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ import {
|
||||
@Injectable()
|
||||
export class TeacherContentService {
|
||||
constructor(
|
||||
@InjectRepository(TeacherContent, 'content')
|
||||
@InjectRepository(TeacherContent, 'educational')
|
||||
private readonly contentRepo: Repository<TeacherContent>,
|
||||
|
||||
@InjectRepository(Profile, 'auth')
|
||||
|
||||
@ -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'),
|
||||
|
||||
@ -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
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
-- ============================================================================
|
||||
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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 $$;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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';
|
||||
@ -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 $$;
|
||||
@ -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)
|
||||
-- =====================================================
|
||||
@ -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
|
||||
-- ====================================================================
|
||||
-- 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.';
|
||||
|
||||
@ -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()';
|
||||
|
||||
@ -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()';
|
||||
|
||||
@ -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.';
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
-- =====================================================
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Schema: storage
|
||||
|
||||
Configuración de almacenamiento de Supabase
|
||||
Schema de configuración de almacenamiento (S3/Storage compatible)
|
||||
|
||||
## Estructura
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
-- =====================================================
|
||||
@ -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
|
||||
-- =====================================================
|
||||
@ -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
|
||||
-- =====================================================
|
||||
@ -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 $$;
|
||||
@ -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 $$;
|
||||
@ -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 $$;
|
||||
@ -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
|
||||
-- =====================================================
|
||||
@ -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": {
|
||||
"nodes": [
|
||||
{
|
||||
"id": "main-article",
|
||||
"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>..."
|
||||
],
|
||||
"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": [
|
||||
{
|
||||
"text": "radiactividad",
|
||||
"relevance": "high",
|
||||
"leadsTo": "Historia de la radiactividad"
|
||||
},
|
||||
{
|
||||
"text": "aislamiento",
|
||||
"relevance": "very high",
|
||||
"leadsTo": "Proceso de aislamiento del radio"
|
||||
}
|
||||
{ "targetId": "radiactividad", "label": "descubrimientos en radiactividad" },
|
||||
{ "targetId": "aislamiento", "label": "aislamiento de elementos radiactivos" },
|
||||
{ "targetId": "premios", "label": "reconocimientos y premios" }
|
||||
]
|
||||
},
|
||||
"optimalPath": ["mainArticle", "aislamiento", "proceso experimental"]
|
||||
{
|
||||
"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 $$;
|
||||
|
||||
@ -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;
|
||||
@ -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) │
|
||||
└─────────────────┘
|
||||
*/
|
||||
@ -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 $$;
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
-- =====================================================
|
||||
@ -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 $$;
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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 $$;
|
||||
@ -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 $$;
|
||||
@ -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 $$;
|
||||
@ -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 $$;
|
||||
@ -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 $$;
|
||||
@ -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 $$;
|
||||
@ -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 $$;
|
||||
|
||||
@ -1,331 +1,214 @@
|
||||
-- =====================================================================
|
||||
-- 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;
|
||||
|
||||
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
|
||||
-- =====================================================
|
||||
|
||||
-- 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
|
||||
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.
|
||||
-- =====================================================
|
||||
(
|
||||
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,
|
||||
'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-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()
|
||||
'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()
|
||||
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()
|
||||
gamilit.now_mexico(),
|
||||
gamilit.now_mexico()
|
||||
)
|
||||
ON CONFLICT (school_id, code) DO UPDATE SET
|
||||
ON CONFLICT (code) DO UPDATE SET
|
||||
school_id = EXCLUDED.school_id,
|
||||
name = EXCLUDED.name,
|
||||
current_students_count = EXCLUDED.current_students_count,
|
||||
schedule = EXCLUDED.schedule,
|
||||
description = EXCLUDED.description,
|
||||
capacity = EXCLUDED.capacity,
|
||||
is_active = EXCLUDED.is_active,
|
||||
settings = EXCLUDED.settings,
|
||||
updated_at = NOW();
|
||||
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 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
|
||||
-- =====================================================================
|
||||
-- =====================================================
|
||||
-- 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(),
|
||||
@ -337,13 +220,20 @@ BEGIN
|
||||
NOW()
|
||||
FROM social_features.classrooms c
|
||||
WHERE c.teacher_id IS NOT NULL
|
||||
AND c.code = 'DEFAULT'
|
||||
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';
|
||||
-- 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 $$;
|
||||
|
||||
@ -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 $$;
|
||||
|
||||
@ -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
Loading…
Reference in New Issue
Block a user