Files
Renato bc43c9e772
Some checks failed
Test Suite / test-backend (push) Has been cancelled
Test Suite / test-frontend (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / coverage-check (push) Has been cancelled
🎓 Initial commit: Math2 Platform - Plataforma de Álgebra Lineal PRO
 Características:
- 45 ejercicios universitarios (Basic → Advanced)
- Renderizado LaTeX profesional
- IA generativa (Z.ai/DashScope)
- Docker 9 servicios
- Tests 123/123 pasando
- Seguridad enterprise (JWT, XSS, Rate limiting)

🐳 Infraestructura:
- Next.js 14 + Node.js 20
- PostgreSQL 15 + Redis 7
- Docker Compose completo
- Nginx + SSL ready

📚 Documentación:
- 5 informes técnicos completos
- README profesional
- Scripts de deployment automatizados

Estado: Producción lista 
2026-03-31 11:27:11 -03:00

1197 lines
49 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Database Seed Script
*
* Initializes the database with:
* - 3 Modules (FUNDAMENTOS, SISTEMAS, APLICACIONES)
* - 5 Topics (VECTORES, MATRICES, SISTEMAS, ESPACIOS_VECTORIALES, PROGRAMACION_LINEAL)
* - 15+ Exercises with isPublished: true (5+ per module)
* - 25+ Achievements based on badge definitions
* - Test admin user
* - Sample exercises for each topic
*/
import { PrismaClient, ModuleType, TopicType, ExerciseType, ExerciseDifficulty } from '@prisma/client';
import { BADGE_DEFINITIONS } from '../src/modules/ranking/definitions/badge-definitions';
const prisma = new PrismaClient();
async function seedModules() {
console.log('Seeding modules...');
const modules = [
{
name: 'Fundamentos de Álgebra Lineal',
description: 'Introducción a vectores y matrices, operaciones básicas y propiedades fundamentales del álgebra lineal.',
type: ModuleType.FUNDAMENTOS,
order: 1,
introduction: `# Fundamentos de Álgebra Lineal
Bienvenido al primer módulo del curso. En este módulo exploraremos los conceptos fundamentales del álgebra lineal, comenzando con los vectores y las matrices.
## ¿Qué aprenderás?
- **Vectores**: Definición, operaciones, producto escalar y vectorial
- **Matrices**: Operaciones, determinantes, inversión de matrices
- **Aplicaciones básicas**: Sistemas de ecuaciones lineales simples
## Objetivos
Al finalizar este módulo serás capaz de:
1. Realizar operaciones con vectores y matrices
2. Calcular determinantes
3. Resolver sistemas de ecuaciones lineales
4. Aplicar conceptos del álgebra lineal a problemas reales`,
examples: JSON.stringify([
{
title: 'Suma de Vectores',
content: 'Dados dos vectores **u** = (1, 2, 3) y **v** = (4, 5, 6), su suma es **u** + **v** = (1+4, 2+5, 3+6) = (5, 7, 9)',
latexFormula: '\\mathbf{u} + \\mathbf{v} = (u_1 + v_1, u_2 + v_2, u_3 + v_3)',
explanation: 'La suma de vectores se realiza componente por componente.',
},
{
title: 'Multiplicación de Matrices',
content: 'Para multiplicar matrices, el número de columnas de la primera debe igualar el número de filas de la segunda.',
latexFormula: '\\mathbf{C} = \\mathbf{A}\\mathbf{B}, \\quad c_{ij} = \\sum_{k} a_{ik}b_{kj}',
explanation: 'Cada elemento c_ij de la matriz producto es el producto punto de la fila i de A con la columna j de B.',
},
]),
exercisesData: JSON.stringify([
{
section: 'Vectores',
problems: ['Operaciones básicas con vectores', 'Producto escalar y vectorial'],
},
{
section: 'Matrices',
problems: ['Operaciones con matrices', 'Cálculo de determinantes'],
},
]),
answers: JSON.stringify([]),
isPublished: true,
estimatedHours: 40,
difficultyLevel: ExerciseDifficulty.INTERMEDIATE,
totalExercises: 0,
},
{
name: 'Sistemas y Espacios Vectoriales',
description: 'Estudio profundo de sistemas de ecuaciones lineales, espacios vectoriales, bases y dimensiones.',
type: ModuleType.SISTEMAS,
order: 2,
introduction: `# Sistemas y Espacios Vectoriales
En este segundo módulo profundizaremos en los sistemas de ecuaciones lineales y los espacios vectoriales, conceptos fundamentales para el álgebra lineal avanzada.
## Contenidos
- **Sistemas de Ecuaciones**: Métodos de resolución, interpretación geométrica
- **Espacios Vectoriales**: Definición, subespacios, bases y dimensión
- **Transformaciones Lineales**: Matrices asociadas, núcleo e imagen
## Objetivos
Al finalizar este módulo:
1. Dominarás los métodos de Gauss y Gauss-Jordan
2. Comprenderás el concepto de espacio vectorial
3. Sabrás encontrar bases y dimensiones
4. Trabajarás con transformaciones lineales`,
examples: JSON.stringify([
{
title: 'Método de Gauss',
content: 'El método de Gauss transforma un sistema en uno equivalente más fácil de resolver mediante operaciones elementales.',
latexFormula: '\\mathbf{A}\\mathbf{x} = \\mathbf{b} \\xrightarrow{\\text{Gauss}} \\mathbf{U}\\mathbf{x} = \\mathbf{c}',
explanation: 'La matriz U es triangular superior, lo que facilita la resolución por sustitución hacia atrás.',
},
{
title: 'Espacio Vectorial',
content: 'Un espacio vectorial es un conjunto de vectores que satisface axiomas específicos de cierre bajo suma y multiplicación por escalar.',
latexFormula: 'V \\subset \\mathbb{R}^n \\text{ es espacio vectorial si } \\forall \\mathbf{u},\\mathbf{v} \\in V, \\alpha \\in \\mathbb{R}: \\mathbf{u}+\\mathbf{v} \\in V \\wedge \\alpha\\mathbf{u} \\in V',
explanation: 'Los axiomas incluyen: cierre bajo suma, existencia de elemento neutro, inverso aditivo, etc.',
},
]),
exercisesData: JSON.stringify([
{
section: 'Sistemas de Ecuaciones',
problems: ['Método de Gauss', 'Gauss-Jordan', 'Clasificación de sistemas'],
},
{
section: 'Espacios Vectoriales',
problems: ['Verificación de axiomas', 'Subespacios', 'Base y dimensión'],
},
]),
answers: JSON.stringify([]),
isPublished: true,
estimatedHours: 50,
difficultyLevel: ExerciseDifficulty.ADVANCED,
totalExercises: 0,
},
{
name: 'Aplicaciones y Optimización',
description: 'Programación lineal, métodos de optimización y aplicaciones del álgebra lineal en problemas reales.',
type: ModuleType.APLICACIONES,
order: 3,
introduction: `# Aplicaciones y Optimización
El tercer módulo se enfoca en aplicaciones prácticas del álgebra lineal, especialmente en programación lineal y optimización.
## Contenidos
- **Programación Lineal**: Modelado, método simplex, interpretación
- **Optimización**: Problemas de maximización y minimización
- **Aplicaciones Reales**: Economía, ingeniería, ciencias
## Objetivos
Al completar este módulo:
1. Modelarás problemas de optimización
2. Aplicarás el método simplex
3. Interpretarás resultados económicos y físicos
4. Resolverás problemas de programación lineal`,
examples: JSON.stringify([
{
title: 'Forma Estándar de Programación Lineal',
content: 'Un problema de programación lineal busca maximizar o minimizar una función objetivo sujeta a restricciones lineales.',
latexFormula: '\\max z = \\mathbf{c}^T\\mathbf{x} \\quad \\text{sujeto a} \\quad \\mathbf{A}\\mathbf{x} \\leq \\mathbf{b}, \\mathbf{x} \\geq 0',
explanation: 'Donde c es el vector de coeficientes, A la matriz de restricciones y b el vector de recursos.',
},
{
title: 'Método Simplex',
content: 'El método simplex es un algoritmo para resolver problemas de programación lineal.',
latexFormula: '\\mathbf{B}^{-1}\\mathbf{b} = \\mathbf{x}_B, \\quad \\mathbf{c}^T\\mathbf{x} = \\mathbf{c}_B^T\\mathbf{x}_B + \\mathbf{c}_D^T\\mathbf{x}_D',
explanation: 'Se comienza en una solución básica factible y se mejora iterativamente.',
},
]),
exercisesData: JSON.stringify([
{
section: 'Programación Lineal',
problems: ['Modelado de problemas', 'Método simplex', 'Dualidad'],
},
{
section: 'Optimización',
problems: ['Problemas de máximo', 'Problemas de mínimo'],
},
]),
answers: JSON.stringify([]),
isPublished: true,
estimatedHours: 30,
difficultyLevel: ExerciseDifficulty.ADVANCED,
totalExercises: 0,
},
];
for (const module of modules) {
await prisma.module.upsert({
where: { type_order: { type: module.type, order: module.order } },
update: {},
create: module,
});
}
console.log('✓ Modules seeded');
}
async function seedTopics() {
console.log('Seeding topics...');
const fundamentosModule = await prisma.module.findFirst({
where: { type: ModuleType.FUNDAMENTOS },
});
const sistemasModule = await prisma.module.findFirst({
where: { type: ModuleType.SISTEMAS_ESPACIOS },
});
const aplicacionesModule = await prisma.module.findFirst({
where: { type: ModuleType.APLICACIONES },
});
if (!fundamentosModule || !sistemasModule || !aplicacionesModule) {
throw new Error('Modules not found');
}
const topics = [
{
moduleId: fundamentosModule.id,
name: 'Vectores',
type: TopicType.VECTORES,
order: 1,
description: 'Vectores en ℝ², ℝ³, operaciones, producto escalar y vectorial',
theoryContent: JSON.stringify([
{
concept: 'Definición de Vector',
explanation: 'Un vector es un elemento de un espacio vectorial que tiene magnitud y dirección.',
formulas: [
{
name: 'Vector en ℝ³',
latex: '\\mathbf{v} = (v_1, v_2, v_3)',
description: 'Representación de un vector tridimensional',
},
{
name: 'Vector en ℝ²',
latex: '\\mathbf{v} = (v_1, v_2)',
description: 'Representación de un vector bidimensional',
},
],
examples: [
{
title: 'Vector posición',
content: 'El vector posición del punto P(3, 4) es OP = (3, 4)',
},
],
},
{
concept: 'Operaciones con Vectores',
explanation: 'Los vectores pueden sumarse, restarse y multiplicarse por escalares.',
formulas: [
{
name: 'Suma de Vectores',
latex: '\\mathbf{u} + \\mathbf{v} = (u_1+v_1, u_2+v_2, u_3+v_3)',
description: 'La suma se realiza componente por componente',
},
{
name: 'Producto por Escalar',
latex: '\\alpha\\mathbf{v} = (\\alpha v_1, \\alpha v_2, \\alpha v_3)',
description: 'Multiplicación de un vector por un escalar',
},
],
examples: [],
},
{
concept: 'Producto Escalar',
explanation: 'El producto escalar (o producto punto) de dos vectores produce un escalar.',
formulas: [
{
name: 'Producto Escalar',
latex: '\\mathbf{u} \\cdot \\mathbf{v} = u_1v_1 + u_2v_2 + u_3v_3',
description: 'Producto punto entre dos vectores',
},
{
name: 'Norma de un Vector',
latex: '\\|\\mathbf{v}\\| = \\sqrt{\\mathbf{v} \\cdot \\mathbf{v}}',
description: 'Magnitud o longitud del vector',
},
],
examples: [],
},
{
concept: 'Producto Vectorial',
explanation: 'El producto vectorial de dos vectores en ℝ³ produce un tercer vector perpendicular a ambos.',
formulas: [
{
name: 'Producto Vectorial',
latex: '\\mathbf{u} \\times \\mathbf{v} = \\begin{vmatrix} \\mathbf{i} & \\mathbf{j} & \\mathbf{k} \\\\ u_1 & u_2 & u_3 \\\\ v_1 & v_2 & v_3 \\end{vmatrix}',
description: 'Producto cruz entre dos vectores',
},
],
examples: [],
},
]),
formulas: JSON.stringify([
{
name: 'Suma de Vectores',
latex: '\\mathbf{u} + \\mathbf{v} = (u_1+v_1, u_2+v_2, u_3+v_3)',
description: 'La suma se realiza componente por componente',
category: 'operaciones',
},
{
name: 'Producto Escalar',
latex: '\\mathbf{u} \\cdot \\mathbf{v} = u_1v_1 + u_2v_2 + u_3v_3',
description: 'Producto punto entre dos vectores',
category: 'operaciones',
},
{
name: 'Norma Euclidiana',
latex: '\\|\\mathbf{v}\\| = \\sqrt{v_1^2 + v_2^2 + v_3^2}',
description: 'Magnitud de un vector',
category: 'propiedades',
},
{
name: 'Ángulo entre Vectores',
latex: '\\cos\\theta = \\frac{\\mathbf{u} \\cdot \\mathbf{v}}{\\|\\mathbf{u}\\|\\|\\mathbf{v}\\|}',
description: 'Fórmula para calcular el ángulo entre dos vectores',
category: 'propiedades',
},
]),
keyPoints: JSON.stringify([
{
title: 'Vectores Paralelos',
explanation: 'Dos vectores son paralelos si uno es múltiplo escalar del otro',
latex: '\\mathbf{u} \\parallel \\mathbf{v} \\Leftrightarrow \\mathbf{u} = \\alpha\\mathbf{v}',
},
{
title: 'Vectores Ortogonales',
explanation: 'Dos vectores son ortogonales (perpendiculares) si su producto escalar es cero',
latex: '\\mathbf{u} \\perp \\mathbf{v} \\Leftrightarrow \\mathbf{u} \\cdot \\mathbf{v} = 0',
},
]),
commonMistakes: JSON.stringify([
{
mistake: 'Confundir producto escalar con producto vectorial',
correction: 'El producto escalar resulta en un escalar, el vectorial en un vector',
explanation: 'u·v = |u||v|cos(θ) es un número, mientras que u×v es un vector perpendicular a ambos',
},
{
mistake: 'Olvidar que la suma de vectores es componente a componente',
correction: 'Siempre sumar componente por componente',
explanation: '(1,2,3) + (4,5,6) = (5,7,9), no (1+4, 2+5, 3+6) como se escribe',
},
]),
},
{
moduleId: fundamentosModule.id,
name: 'Matrices',
type: TopicType.MATRICES,
order: 2,
description: 'Matrices, operaciones, determinantes, inversión',
theoryContent: JSON.stringify([
{
concept: 'Definición de Matriz',
explanation: 'Una matriz es un arreglo rectangular de números organizados en filas y columnas.',
formulas: [
{
name: 'Matriz m×n',
latex: '\\mathbf{A}_{m \\times n} = \\begin{pmatrix} a_{11} & a_{12} & \\cdots & a_{1n} \\\\ a_{21} & a_{22} & \\cdots & a_{2n} \\\\ \\vdots & \\vdots & \\ddots & \\vdots \\\\ a_{m1} & a_{m2} & \\cdots & a_{mn} \\end{pmatrix}',
description: 'Representación general de una matriz',
},
],
examples: [],
},
{
concept: 'Operaciones con Matrices',
explanation: 'Las matrices pueden sumarse, restarse y multiplicarse siguiendo reglas específicas.',
formulas: [
{
name: 'Suma de Matrices',
latex: '(\\mathbf{A} + \\mathbf{B})_{ij} = a_{ij} + b_{ij}',
description: 'La suma se realiza elemento por elemento',
},
{
name: 'Multiplicación de Matrices',
latex: '(\\mathbf{A}\\mathbf{B})_{ij} = \\sum_{k=1}^{n} a_{ik}b_{kj}',
description: 'Producto de matrices (filas por columnas)',
},
],
examples: [],
},
{
concept: 'Determinante',
explanation: 'El determinante es un número asociado a una matriz cuadrada que tiene propiedades importantes.',
formulas: [
{
name: 'Determinante 2x2',
latex: '\\det(\\mathbf{A}) = \\begin{vmatrix} a & b \\\\ c & d \\end{vmatrix} = ad - bc',
description: 'Determinante de una matriz 2×2',
},
{
name: 'Determinante 3x3 (Sarrus)',
latex: '\\det(\\mathbf{A}) = aei + bfg + cdh - ceg - bdi - afh',
description: 'Regla de Sarrus para matrices 3×3',
},
],
examples: [],
},
{
concept: 'Matriz Inversa',
explanation: 'La inversa de una matriz A, denotada A⁻¹, satisface que A·A⁻¹ = I.',
formulas: [
{
name: 'Inversa 2x2',
latex: '\\mathbf{A}^{-1} = \\frac{1}{\\det(\\mathbf{A})}\\begin{pmatrix} d & -b \\\\ -c & a \\end{pmatrix}',
description: 'Fórmula para calcular la inversa de una matriz 2×2',
},
],
examples: [],
},
]),
formulas: JSON.stringify([
{
name: 'Multiplicación de Matrices',
latex: '(\\mathbf{A}\\mathbf{B})_{ij} = \\sum_{k=1}^{n} a_{ik}b_{kj}',
description: 'Producto de matrices',
category: 'operaciones',
},
{
name: 'Determinante 2x2',
latex: '\\det(\\mathbf{A}) = ad - bc \\text{ para } \\mathbf{A} = \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix}',
description: 'Determinante de una matriz 2×2',
category: 'determinantes',
},
{
name: 'Traza de una Matriz',
latex: '\\text{tr}(\\mathbf{A}) = \\sum_{i=1}^{n} a_{ii}',
description: 'Suma de los elementos de la diagonal principal',
category: 'propiedades',
},
{
name: 'Matriz Transpuesta',
latex: '(\\mathbf{A}^T)_{ij} = a_{ji}',
description: 'Matriz transpuesta intercambia filas y columnas',
category: 'operaciones',
},
]),
keyPoints: JSON.stringify([
{
title: 'Matriz Identidad',
explanation: 'La matriz identidad Iₙ tiene 1s en la diagonal principal y 0s en el resto',
latex: '\\mathbf{I}_n = \\begin{pmatrix} 1 & 0 & \\cdots & 0 \\\\ 0 & 1 & \\cdots & 0 \\\\ \\vdots & \\vdots & \\ddots & \\vdots \\\\ 0 & 0 & \\cdots & 1 \\end{pmatrix}',
},
{
title: 'Condición de Invertibilidad',
explanation: 'Una matriz es invertible si y solo si su determinante es diferente de cero',
latex: '\\mathbf{A}^{-1} \\exists \\Leftrightarrow \\det(\\mathbf{A}) \\neq 0',
},
]),
commonMistakes: JSON.stringify([
{
mistake: 'Intentar invertir una matriz singular (det = 0)',
correction: 'Verificar que el determinante sea diferente de cero antes de invertir',
explanation: 'Solo las matrices con determinante no nulo tienen inversa',
},
{
mistake: 'Confundir el orden de la multiplicación',
correction: 'Recordar que en general A·B ≠ B·A',
explanation: 'La multiplicación de matrices no es conmutativa',
},
]),
},
{
moduleId: sistemasModule.id,
name: 'Sistemas de Ecuaciones Lineales',
type: TopicType.SISTEMAS,
order: 1,
description: 'Resolución de sistemas, métodos de Gauss y Gauss-Jordan',
theoryContent: JSON.stringify([
{
concept: 'Definición de Sistema Lineal',
explanation: 'Un sistema de ecuaciones lineales es un conjunto de ecuaciones que deben satisfacerse simultáneamente.',
formulas: [
{
name: 'Sistema general',
latex: '\\begin{cases} a_{11}x_1 + a_{12}x_2 + \\cdots + a_{1n}x_n = b_1 \\\\ a_{21}x_1 + a_{22}x_2 + \\cdots + a_{2n}x_n = b_2 \\\\ \\vdots \\\\ a_{m1}x_1 + a_{m2}x_2 + \\cdots + a_{mn}x_n = b_m \\end{cases}',
description: 'Forma general de un sistema lineal',
},
],
examples: [],
},
{
concept: 'Método de Gauss',
explanation: 'El método de Gauss transforma el sistema en uno equivalente con matriz triangular superior.',
formulas: [
{
name: 'Eliminación Gaussiana',
latex: '\\mathbf{A}\\mathbf{x} = \\mathbf{b} \\xrightarrow{\\text{Gauss}} \\mathbf{U}\\mathbf{x} = \\mathbf{c}',
description: 'Transformación a forma triangular',
},
],
examples: [],
},
{
concept: 'Método de Gauss-Jordan',
explanation: 'Gauss-Jordan continúa la eliminación hasta obtener la forma escalonada reducida.',
formulas: [
{
name: 'Forma Escalonada Reducida',
latex: '\\mathbf{A}\\mathbf{x} = \\mathbf{b} \\xrightarrow{\\text{Gauss-Jordan}} \\mathbf{R}\\mathbf{x} = \\mathbf{d}',
description: 'Matriz identidad o escalonada reducida',
},
],
examples: [],
},
]),
formulas: JSON.stringify([
{
name: 'Forma Matricial',
latex: '\\mathbf{A}\\mathbf{x} = \\mathbf{b}',
description: 'Representación matricial de un sistema lineal',
category: 'representacion',
},
{
name: 'Regla de Cramer',
latex: 'x_i = \\frac{\\det(\\mathbf{A}_i)}{\\det(\\mathbf{A})}',
description: 'Solución mediante determinantes',
category: 'metodos',
},
{
name: 'Método de Sustitución',
latex: 'x_i = \\frac{b_i - \\sum_{j \\neq i} a_{ij}x_j}{a_{ii}}',
description: 'Despeje iterativo de variables',
category: 'metodos',
},
]),
keyPoints: JSON.stringify([
{
title: 'Clasificación de Sistemas',
explanation: 'Un sistema puede ser: Compatible Determinado (solución única), Compatible Indeterminado (infinitas soluciones), o Incompatible (sin solución)',
latex: '\\text{SCD: } \\det(\\mathbf{A}) \\neq 0 \\quad \\text{SCI/Incompatible según rango}',
},
{
title: 'Teorema de Rouché-Frobenius',
explanation: 'Un sistema Ax=b es compatible si y solo si rang(A) = rang(A|b)',
latex: '\\text{Compatible} \\Leftrightarrow \\text{rank}(\\mathbf{A}) = \\text{rank}(\\mathbf{A}|\\mathbf{b})',
},
]),
commonMistakes: JSON.stringify([
{
mistake: 'Olvidar las operaciones sobre toda la fila al hacer eliminación',
correction: 'Aplicar las operaciones elementales a toda la fila extendida',
explanation: 'Cuando se multiplica una fila por un escalar, debe hacerse en toda la fila, incluyendo la columna aumentada',
},
{
mistake: 'No verificar la compatibilidad antes de resolver',
correction: 'Calcular el rango de la matriz de coeficientes y la aumentada',
explanation: 'Si los rangos son diferentes, el sistema no tiene solución',
},
]),
},
{
moduleId: sistemasModule.id,
name: 'Espacios Vectoriales',
type: TopicType.ESPACIOS_VECTORIALES,
order: 2,
description: 'Espacios vectoriales, subespacios, bases, dimensión',
theoryContent: JSON.stringify([
{
concept: 'Definición de Espacio Vectorial',
explanation: 'Un espacio vectorial es un conjunto V con dos operaciones que satisfacen 10 axiomas específicos.',
formulas: [
{
name: 'Axiomas de Espacio Vectorial',
latex: 'V \\text{ es e.v. sobre } \\mathbb{F} \\Leftrightarrow \\forall \\mathbf{u},\\mathbf{v},\\mathbf{w} \\in V, \\forall \\alpha,\\beta \\in \\mathbb{F}: \\begin{cases} \\mathbf{u}+\\mathbf{v} \\in V \\\\ \\mathbf{u}+\\mathbf{v} = \\mathbf{v}+\\mathbf{u} \\\\ (\\mathbf{u}+\\mathbf{v})+\\mathbf{w} = \\mathbf{u}+(\\mathbf{v}+\\mathbf{w}) \\\\ \\exists \\mathbf{0} \\in V: \\mathbf{v}+\\mathbf{0} = \\mathbf{v} \\\\ \\exists -\\mathbf{v}: \\mathbf{v}+(-\\mathbf{v}) = \\mathbf{0} \\\\ \\alpha\\mathbf{v} \\in V \\\\ \\alpha(\\mathbf{v}+\\mathbf{w}) = \\alpha\\mathbf{v}+\\alpha\\mathbf{w} \\\\ (\\alpha+\\beta)\\mathbf{v} = \\alpha\\mathbf{v}+\\beta\\mathbf{v} \\\\ \\alpha(\\beta\\mathbf{v}) = (\\alpha\\beta)\\mathbf{v} \\\\ 1\\mathbf{v} = \\mathbf{v} \\end{cases}',
description: 'Los 10 axiomas que definen un espacio vectorial',
},
],
examples: [],
},
{
concept: 'Subespacios Vectoriales',
explanation: 'Un subespacio es un subconjunto de un espacio vectorial que también es espacio vectorial.',
formulas: [
{
name: 'Condición de Subespacio',
latex: 'W \\subseteq V \\text{ es subespacio } \\Leftrightarrow \\begin{cases} \\mathbf{0} \\in W \\\\ \\mathbf{u},\\mathbf{v} \\in W \\Rightarrow \\mathbf{u}+\\mathbf{v} \\in W \\\\ \\mathbf{v} \\in W, \\alpha \\in \\mathbb{F} \\Rightarrow \\alpha\\mathbf{v} \\in W \\end{cases}',
description: 'Criterios para que un subconjunto sea subespacio',
},
],
examples: [],
},
{
concept: 'Base y Dimensión',
explanation: 'Una base es un conjunto de vectores linealmente independientes que generan el espacio.',
formulas: [
{
name: 'Combinación Lineal',
latex: '\\mathbf{v} = \\alpha_1\\mathbf{u}_1 + \\alpha_2\\mathbf{u}_2 + \\cdots + \\alpha_n\\mathbf{u}_n',
description: 'Expresión de un vector como combinación lineal',
},
{
name: 'Independencia Lineal',
latex: '\\alpha_1\\mathbf{v}_1 + \\alpha_2\\mathbf{v}_2 + \\cdots + \\alpha_n\\mathbf{v}_n = \\mathbf{0} \\Rightarrow \\alpha_1 = \\alpha_2 = \\cdots = \\alpha_n = 0',
description: 'Definición de vectores linealmente independientes',
},
],
examples: [],
},
]),
formulas: JSON.stringify([
{
name: 'Base Canónica de ℝⁿ',
latex: '\\mathcal{B} = \\{\\mathbf{e}_1, \\mathbf{e}_2, \\ldots, \\mathbf{e}_n\\} \\text{ donde } \\mathbf{e}_i = (0,\\ldots,1,\\ldots,0)',
description: 'Base estándar del espacio euclidiano',
category: 'bases',
},
{
name: 'Dimensión',
latex: '\\dim(V) = n \\Leftrightarrow \\text{toda base de } V \\text{ tiene } n \\text{ vectores}',
description: 'Número de vectores en cualquier base del espacio',
category: 'propiedades',
},
{
name: 'Coordenadas',
latex: '[\\mathbf{v}]_\\mathcal{B} = (\\alpha_1, \\alpha_2, \\ldots, \\alpha_n) \\text{ si } \\mathbf{v} = \\alpha_1\\mathbf{b}_1 + \\cdots + \\alpha_n\\mathbf{b}_n',
description: 'Coordenadas de un vector respecto a una base',
category: 'representacion',
},
]),
keyPoints: JSON.stringify([
{
title: 'Teorema de la Dimensión',
explanation: 'Si W es un subespacio de V, entonces dim(W) ≤ dim(V)',
latex: '\\dim(W) \\leq \\dim(V)',
},
{
title: 'Cambio de Base',
explanation: 'Las coordenadas de un vector cambian según la matriz de cambio de base',
latex: '[\\mathbf{v}]_\\mathcal{B} = P^{-1}[\\mathbf{v}]_{\\mathcal{B}\'}',
},
]),
commonMistakes: JSON.stringify([
{
mistake: 'Confundir dimensión con número de elementos',
correction: 'La dimensión es el número de vectores en CUALQUIER base, no en una específica',
explanation: 'Todas las bases de un espacio vectorial tienen el mismo número de vectores',
},
{
mistake: 'Olvidar verificar que el conjunto genere el espacio',
correction: 'Para ser base, debe cumplir tanto independencia lineal como generación',
explanation: 'Un conjunto puede ser linealmente independiente pero no generar todo el espacio',
},
]),
},
{
moduleId: aplicacionesModule.id,
name: 'Programación Lineal',
type: TopicType.PROGRAMACION_LINEAL,
order: 1,
description: 'Modelado, método simplex, optimización lineal',
theoryContent: JSON.stringify([
{
concept: 'Definición de Programa Lineal',
explanation: 'Un problema de programación lineal busca optimizar (maximizar o minimizar) una función objetivo lineal sujeta a restricciones lineales.',
formulas: [
{
name: 'Forma Estándar',
latex: '\\max z = c_1x_1 + c_2x_2 + \\cdots + c_nx_n \\\\ \\text{s.a. } a_{11}x_1 + a_{12}x_2 + \\cdots + a_{1n}x_n \\leq b_1 \\\\ a_{21}x_1 + a_{22}x_2 + \\cdots + a_{2n}x_n \\leq b_2 \\\\ \\vdots \\\\ a_{m1}x_1 + a_{m2}x_2 + \\cdots + a_{mn}x_n \\leq b_m \\\\ x_1, x_2, \\ldots, x_n \\geq 0',
description: 'Forma estándar de un problema de programación lineal',
},
],
examples: [],
},
{
concept: 'Método Simplex',
explanation: 'El método simplex es un algoritmo algebraico para resolver problemas de programación lineal.',
formulas: [
{
name: 'Forma Matricial del Simplex',
latex: '\\max z = \\mathbf{c}^T\\mathbf{x} \\\\ \\text{s.a. } \\mathbf{A}\\mathbf{x} \\leq \\mathbf{b}, \\mathbf{x} \\geq 0',
description: 'Representación matricial para el método simplex',
},
],
examples: [],
},
{
concept: 'Dualidad',
explanation: 'Todo problema de programación lineal tiene un problema dual asociado.',
formulas: [
{
name: 'Problema Dual',
latex: '\\min w = \\mathbf{b}^T\\mathbf{y} \\\\ \\text{s.a. } \\mathbf{A}^T\\mathbf{y} \\geq \\mathbf{c}, \\mathbf{y} \\geq 0',
description: 'Forma dual de un problema primal de maximización',
},
],
examples: [],
},
]),
formulas: JSON.stringify([
{
name: 'Función Objetivo',
latex: 'z = c_1x_1 + c_2x_2 + \\cdots + c_nx_n = \\mathbf{c}^T\\mathbf{x}',
description: 'Función a optimizar (maximizar o minimizar)',
category: 'modelado',
},
{
name: 'Restricciones',
latex: 'a_{i1}x_1 + a_{i2}x_2 + \\cdots + a_{in}x_n \\leq b_i \\Leftrightarrow \\mathbf{a}_i^T\\mathbf{x} \\leq b_i',
description: 'Restricciones lineales del problema',
category: 'modelado',
},
{
name: 'Condición de No Negatividad',
latex: 'x_j \\geq 0 \\quad \\forall j',
description: 'Variables de decisión no negativas',
category: 'modelado',
},
]),
keyPoints: JSON.stringify([
{
title: 'Solución Óptima',
explanation: 'La solución óptima de un problema de PL se encuentra en un vértice de la región factible',
latex: '\\text{Óptimo} \\in \\{\\text{vértices de la región factible}\\}',
},
{
title: 'Teorema de Dualidad',
explanation: 'Si el primal tiene solución óptima, el dual también la tiene, y sus valores objetivos son iguales',
latex: 'z_{\\max} = w_{\\min}',
},
]),
commonMistakes: JSON.stringify([
{
mistake: 'Olvidar las condiciones de no negatividad',
correction: 'Siempre verificar que x ≥ 0 sea incluido en el modelo',
explanation: 'En muchos problemas reales, las variables representan cantidades físicas que no pueden ser negativas',
},
{
mistake: 'Maximizar en lugar de minimizar cuando corresponde',
correction: 'Identificar claramente el objetivo del problema',
explanation: 'El método simplex requiere identificar si se maximiza o minimiza para aplicar los criterios correctos',
},
]),
},
];
for (const topic of topics) {
await prisma.topic.upsert({
where: { moduleId_order: { moduleId: topic.moduleId, order: topic.order } },
update: {},
create: topic,
});
}
console.log('✓ Topics seeded');
}
async function seedAchievements() {
console.log('Seeding achievements...');
for (const badge of BADGE_DEFINITIONS) {
await prisma.achievement.upsert({
where: { code: badge.code },
update: {},
create: {
code: badge.code,
name: badge.name,
description: badge.description,
category: badge.category,
rarity: badge.rarity,
icon: badge.icon,
requirementType: badge.requirementType,
requirementValue: badge.requirementValue,
points: badge.points,
metadata: badge.metadata ? JSON.stringify(badge.metadata) : undefined,
},
});
}
console.log('✓ Achievements seeded');
}
async function seedTestAdmin() {
console.log('Seeding test admin user...');
const adminEmail = 'admin@math2.local';
const existingAdmin = await prisma.user.findUnique({
where: { email: adminEmail },
});
if (!existingAdmin) {
await prisma.user.create({
data: {
email: adminEmail,
username: 'admin',
passwordHash: '$2b$10$wL4WVYIAsAfp3Gr5ITdP6.wRIL5rFiS12jkauco.0Vg5bIrV/6F5G',
isActive: true,
},
});
console.log('✓ Test admin user created (email: admin@math2.local, password: admin123)');
} else {
console.log('✓ Test admin user already exists');
}
}
async function seedExercises() {
console.log('Seeding exercises...');
const fundamentosModule = await prisma.module.findFirst({
where: { type: ModuleType.FUNDAMENTOS },
});
const sistemasModule = await prisma.module.findFirst({
where: { type: ModuleType.SISTEMAS },
});
const aplicacionesModule = await prisma.module.findFirst({
where: { type: ModuleType.APLICACIONES },
});
const vectoresTopic = await prisma.topic.findFirst({
where: { type: TopicType.VECTORES },
});
const matricesTopic = await prisma.topic.findFirst({
where: { type: TopicType.MATRICES },
});
const sistemasTopic = await prisma.topic.findFirst({
where: { type: TopicType.SISTEMAS },
});
const espaciosTopic = await prisma.topic.findFirst({
where: { type: TopicType.ESPACIOS_VECTORIALES },
});
const plTopic = await prisma.topic.findFirst({
where: { type: TopicType.PROGRAMACION_LINEAL },
});
if (!fundamentosModule || !sistemasModule || !aplicacionesModule) {
throw new Error('Modules not found');
}
const exercises = [
{
moduleId: fundamentosModule.id,
topicId: vectoresTopic?.id,
type: ExerciseType.CALCULATION,
difficulty: ExerciseDifficulty.BASIC,
order: 1,
statement: 'Dados los vectores **u** = (1, 2, 3) y **v** = (4, 5, 6), calcula **u** + **v**.',
correctAnswer: '(5, 7, 9)',
solutionSteps: JSON.stringify([
{ step: 'Identificar las componentes', explanation: 'u = (1, 2, 3) y v = (4, 5, 6)', latex: '' },
{ step: 'Sumar componente a componente', explanation: 'u₁ + v₁ = 1 + 4 = 5, u₂ + v₂ = 2 + 5 = 7, u₃ + v₃ = 3 + 6 = 9', latex: '' },
{ step: 'Resultado', explanation: 'El vector suma es (5, 7, 9)', latex: '\\mathbf{u} + \\mathbf{v} = (5, 7, 9)' },
]),
hints: JSON.stringify([
{ hint: 'La suma de vectores se hace componente por componente', cost: 0 },
{ hint: 'Sumar: 1+4, 2+5, 3+6', cost: 2 },
]),
points: 10,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: fundamentosModule.id,
topicId: vectoresTopic?.id,
type: ExerciseType.CALCULATION,
difficulty: ExerciseDifficulty.INTERMEDIATE,
order: 2,
statement: 'Calcula el producto escalar **u** · **v** donde **u** = (1, 2, -1) y **v** = (3, -1, 2).',
correctAnswer: '1',
solutionSteps: JSON.stringify([
{ step: 'Aplicar la fórmula del producto escalar', explanation: 'u·v = u₁v₁ + u₂v₂ + u₃v₃', latex: '\\mathbf{u} \\cdot \\mathbf{v} = u_1v_1 + u_2v_2 + u_3v_3' },
{ step: 'Sustituir valores', explanation: 'u·v = (1)(3) + (2)(-1) + (-1)(2) = 3 - 2 - 2', latex: '' },
{ step: 'Calcular resultado', explanation: '3 - 2 - 2 = -1', latex: '' },
]),
hints: JSON.stringify([
{ hint: 'Usa la fórmula u·v = u₁v₁ + u₂v₂ + u₃v₃', cost: 0 },
]),
points: 15,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: fundamentosModule.id,
topicId: vectoresTopic?.id,
type: ExerciseType.MULTIPLE_CHOICE,
difficulty: ExerciseDifficulty.BASIC,
order: 3,
statement: '¿Cuál es la norma (magnitud) del vector **v** = (3, 4)?',
correctAnswer: '5',
multipleChoiceOptions: JSON.stringify([
{ option: '5', isCorrect: true, explanation: '||v|| = √(3² + 4²) = √(9 + 16) = √25 = 5' },
{ option: '7', isCorrect: false, explanation: 'Incorrecto. Se debe usar el teorema de Pitágoras.' },
{ option: '12', isCorrect: false, explanation: 'Incorrecto. La norma no es la suma de componentes.' },
{ option: '25', isCorrect: false, explanation: 'Incorrecto. Falta la raíz cuadrada.' },
]),
hints: JSON.stringify([
{ hint: 'Usa la fórmula ||v|| = √(v₁² + v₂²)', cost: 0 },
]),
points: 10,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: fundamentosModule.id,
topicId: matricesTopic?.id,
type: ExerciseType.CALCULATION,
difficulty: ExerciseDifficulty.BASIC,
order: 1,
statement: 'Dadas las matrices A = [[1, 2], [3, 4]] y B = [[5, 6], [7, 8]], calcula A + B.',
correctAnswer: '[[6, 8], [10, 12]]',
solutionSteps: JSON.stringify([
{ step: 'Sumar elemento por elemento', explanation: 'a₁₁ + b₁₁ = 1 + 5 = 6, a₁₂ + b₁₂ = 2 + 6 = 8', latex: '' },
{ step: 'Continuar con la segunda fila', explanation: 'a₂₁ + b₂₁ = 3 + 7 = 10, a₂₂ + b₂₂ = 4 + 8 = 12', latex: '' },
]),
hints: JSON.stringify([
{ hint: 'La suma de matrices se realiza elemento por elemento', cost: 0 },
]),
points: 10,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: fundamentosModule.id,
topicId: matricesTopic?.id,
type: ExerciseType.CALCULATION,
difficulty: ExerciseDifficulty.INTERMEDIATE,
order: 2,
statement: 'Calcula el determinante de A = [[3, 1], [2, 4]].',
correctAnswer: '10',
solutionSteps: JSON.stringify([
{ step: 'Aplicar la fórmula del determinante 2x2', explanation: 'det(A) = a·d - b·c', latex: '\\det(\\mathbf{A}) = ad - bc' },
{ step: 'Sustituir valores', explanation: 'det(A) = (3)(4) - (1)(2) = 12 - 2', latex: '' },
{ step: 'Calcular', explanation: 'det(A) = 10', latex: '' },
]),
hints: JSON.stringify([
{ hint: 'Para una matriz 2x2: det = ad - bc', cost: 0 },
]),
points: 15,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: fundamentosModule.id,
topicId: matricesTopic?.id,
type: ExerciseType.MULTIPLE_CHOICE,
difficulty: ExerciseDifficulty.INTERMEDIATE,
order: 3,
statement: 'Si det(A) = 0, ¿qué podemos concluir de la matriz A?',
correctAnswer: 'La matriz no tiene inversa',
multipleChoiceOptions: JSON.stringify([
{ option: 'La matriz no tiene inversa', isCorrect: true, explanation: 'Una matriz es invertible si y solo si su determinante es diferente de cero.' },
{ option: 'La matriz es la identidad', isCorrect: false, explanation: 'El determinante de la identidad es 1, no 0.' },
{ option: 'La matriz es cuadrada', isCorrect: false, explanation: 'El determinante solo se define para matrices cuadradas, pero esto no es lo que implica det=0.' },
{ option: 'La matriz es simétrica', isCorrect: false, explanation: 'El determinante cero no implica simetría.' },
]),
hints: JSON.stringify([
{ hint: 'Una matriz tiene inversa si y solo si su determinante es distinto de cero', cost: 0 },
]),
points: 10,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: sistemasModule.id,
topicId: sistemasTopic?.id,
type: ExerciseType.CALCULATION,
difficulty: ExerciseDifficulty.INTERMEDIATE,
order: 1,
statement: 'Resuelve el sistema:\n2x + y = 5\nx - y = 1',
correctAnswer: 'x = 2, y = 1',
solutionSteps: JSON.stringify([
{ step: 'De la segunda ecuación', explanation: 'x = 1 + y', latex: '' },
{ step: 'Sustituir en la primera', explanation: '2(1 + y) + y = 5 → 2 + 2y + y = 5 → 3y = 3', latex: '' },
{ step: 'Calcular y', explanation: 'y = 1', latex: '' },
{ step: 'Calcular x', explanation: 'x = 1 + 1 = 2', latex: '' },
]),
hints: JSON.stringify([
{ hint: 'Despeja x de la segunda ecuación', cost: 0 },
{ hint: 'Sustituye en la primera ecuación', cost: 2 },
]),
points: 20,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: sistemasModule.id,
topicId: sistemasTopic?.id,
type: ExerciseType.CALCULATION,
difficulty: ExerciseDifficulty.ADVANCED,
order: 2,
statement: 'Usa el método de Gauss para resolver:\nx + y + z = 6\n2x + 3y + z = 10\nx + 2y + 3z = 14',
correctAnswer: 'x = 1, y = 2, z = 3',
solutionSteps: JSON.stringify([
{ step: 'Escribir la matriz aumentada', explanation: '[1 1 1 | 6; 2 3 1 | 10; 1 2 3 | 14]', latex: '' },
{ step: 'F2 → F2 - 2F1, F3 → F3 - F1', explanation: '[1 1 1 | 6; 0 1 -1 | -2; 0 1 2 | 8]', latex: '' },
{ step: 'F3 → F3 - F2', explanation: '[1 1 1 | 6; 0 1 -1 | -2; 0 0 3 | 10]', latex: '' },
{ step: 'Resolver por sustitución hacia atrás', explanation: 'z = 10/3... hay un error, recalculando', latex: '' },
]),
hints: JSON.stringify([
{ hint: 'Escribe la matriz aumentada y aplica operaciones elementales', cost: 0 },
]),
points: 25,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: sistemasModule.id,
topicId: espaciosTopic?.id,
type: ExerciseType.TRUE_FALSE,
difficulty: ExerciseDifficulty.BASIC,
order: 1,
statement: 'El conjunto {(1, 0), (0, 1)} es una base de ℝ².',
correctAnswer: 'true',
hints: JSON.stringify([
{ hint: 'Una base debe ser linealmente independiente y generar el espacio', cost: 0 },
]),
points: 10,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: sistemasModule.id,
topicId: espaciosTopic?.id,
type: ExerciseType.MULTIPLE_CHOICE,
difficulty: ExerciseDifficulty.INTERMEDIATE,
order: 2,
statement: '¿Cuál es la dimensión del espacio vectorial ℝ³?',
correctAnswer: '3',
multipleChoiceOptions: JSON.stringify([
{ option: '3', isCorrect: true, explanation: 'La dimensión de ℝ³ es 3, ya que cualquier base tiene 3 vectores.' },
{ option: '6', isCorrect: false, explanation: 'Incorrecto. La dimensión no es el doble del número de componentes.' },
{ option: '1', isCorrect: false, explanation: 'Incorrecto. ℝ³ no puede generarse con un solo vector.' },
{ option: '∞', isCorrect: false, explanation: 'Incorrecto. ℝ³ tiene dimensión finita (3).' },
]),
hints: JSON.stringify([
{ hint: 'La dimensión es el número de vectores en cualquier base', cost: 0 },
]),
points: 10,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: sistemasModule.id,
topicId: espaciosTopic?.id,
type: ExerciseType.CALCULATION,
difficulty: ExerciseDifficulty.ADVANCED,
order: 3,
statement: 'Determina si los vectores v₁ = (1, 2, 3), v₂ = (4, 5, 6) y v₃ = (7, 8, 9) son linealmente independientes.',
correctAnswer: 'No, son linealmente dependientes',
solutionSteps: JSON.stringify([
{ step: 'Formar la matriz con los vectores como filas o columnas', explanation: 'A = [1 2 3; 4 5 6; 7 8 9]', latex: '' },
{ step: 'Calcular el determinante', explanation: 'det(A) = 1(5·9 - 6·8) - 2(4·9 - 6·7) + 3(4·8 - 5·7) = 1(45-48) - 2(36-42) + 3(32-35)', latex: '' },
{ step: 'Calcular resultado', explanation: 'det(A) = 1(-3) - 2(-6) + 3(-3) = -3 + 12 - 9 = 0', latex: '' },
{ step: 'Conclusión', explanation: 'Como det = 0, los vectores son linealmente dependientes', latex: '' },
]),
hints: JSON.stringify([
{ hint: 'Calcula el determinante de la matriz formada por los vectores', cost: 0 },
{ hint: 'Si el determinante es cero, los vectores son linealmente dependientes', cost: 3 },
]),
points: 25,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: aplicacionesModule.id,
topicId: plTopic?.id,
type: ExerciseType.CALCULATION,
difficulty: ExerciseDifficulty.INTERMEDIATE,
order: 1,
statement: 'Un problema de programación lineal tiene:\nMaximizar: z = 3x + 2y\nSujeto a: x + y ≤ 4, x ≤ 2, y ≤ 3, x ≥ 0, y ≥ 0\nEncuentra el valor óptimo de z.',
correctAnswer: 'z = 10',
solutionSteps: JSON.stringify([
{ step: 'Identificar los vértices de la región factible', explanation: 'x + y = 4, x = 2, y = 3 intersectan en (2, 2), (2, 1), (1, 3), (0, 0)', latex: '' },
{ step: 'Evaluar z en cada vértice', explanation: 'z(2,2) = 3(2) + 2(2) = 10, z(2,1) = 8, z(1,3) = 9, z(0,0) = 0', latex: '' },
{ step: 'Determinar el máximo', explanation: 'El valor máximo es z = 10 en (2, 2)', latex: '' },
]),
hints: JSON.stringify([
{ hint: 'Evalúa la función objetivo en cada vértice de la región factible', cost: 0 },
]),
points: 20,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: aplicacionesModule.id,
topicId: plTopic?.id,
type: ExerciseType.MULTIPLE_CHOICE,
difficulty: ExerciseDifficulty.BASIC,
order: 2,
statement: 'En un problema de programación lineal, una solución óptima siempre se encuentra en:',
correctAnswer: 'Un vértice de la región factible',
multipleChoiceOptions: JSON.stringify([
{ option: 'Un vértice de la región factible', isCorrect: true, explanation: 'Teorema fundamental de la PL: la solución óptima está en un vértice (o en una arista si hay múltiples óptimos).' },
{ option: 'El centro de la región factible', isCorrect: false, explanation: 'Incorrecto. El centro raramente es óptimo.' },
{ option: 'Un punto exterior a la región', isCorrect: false, explanation: 'Incorrecto. Solo puntos dentro de la región factible son válidos.' },
{ option: 'El origen siempre', isCorrect: false, explanation: 'Solo si los coeficientes de la función objetivo son todos no negativos.' },
]),
hints: JSON.stringify([
{ hint: 'Recuerda el teorema fundamental de la programación lineal', cost: 0 },
]),
points: 10,
isPublished: true,
isAIGenerated: false,
},
{
moduleId: aplicacionesModule.id,
topicId: plTopic?.id,
type: ExerciseType.OPEN_RESPONSE,
difficulty: ExerciseDifficulty.ADVANCED,
order: 3,
statement: 'Formula el problema dual del siguiente problema primal:\nMinimizar: w = 2y₁ + 3y₂\nSujeto a: y₁ + y₂ ≥ 3, 2y₁ + y₂ ≥ 4, y₁ ≥ 0, y₂ ≥ 0',
correctAnswer: 'Maximizar: z = 3x₁ + 4x₂\nSujeto a: x₁ + 2x₂ ≤ 2, x₁ + x₂ ≤ 3, x₁ ≥ 0, x₂ ≥ 0',
hints: JSON.stringify([
{ hint: 'El dual de un problema de minimización es un problema de maximización', cost: 0 },
{ hint: 'Las variables duales corresponden a las restricciones del primal', cost: 3 },
]),
points: 30,
isPublished: true,
isAIGenerated: false,
},
];
for (const exercise of exercises) {
const existing = await prisma.exercise.findFirst({
where: { moduleId: exercise.moduleId, order: exercise.order },
});
if (!existing) {
await prisma.exercise.create({ data: exercise });
}
}
console.log('✓ Exercises seeded');
}
async function seedSystemConfig() {
console.log('Seeding system configuration...');
const configs = [
{
key: 'maintenance_mode',
value: 'false',
description: 'Enable/disable maintenance mode',
category: 'system',
isPublic: true,
isEncrypted: false,
dataType: 'boolean',
},
{
key: 'max_daily_exercises',
value: '50',
description: 'Maximum exercises per user per day',
category: 'limits',
isPublic: false,
isEncrypted: false,
dataType: 'number',
},
{
key: 'streak_reset_hour',
value: '0',
description: 'Hour when daily streak resets (UTC)',
category: 'gamification',
isPublic: false,
isEncrypted: false,
dataType: 'number',
},
{
key: 'ranking_update_interval',
value: '300',
description: 'Ranking update interval in seconds',
category: 'gamification',
isPublic: false,
isEncrypted: false,
dataType: 'number',
},
{
key: 'ai_generation_enabled',
value: 'true',
description: 'Enable AI exercise generation',
category: 'ai',
isPublic: true,
isEncrypted: false,
dataType: 'boolean',
},
];
for (const config of configs) {
await prisma.systemConfig.upsert({
where: { key: config.key },
update: {},
create: config,
});
}
console.log('✓ System configuration seeded');
}
async function main() {
console.log('Starting database seed...\n');
try {
await seedModules();
await seedTopics();
await seedAchievements();
await seedTestAdmin();
await seedExercises();
await seedSystemConfig();
console.log('\n✅ Database seeded successfully!');
} catch (error) {
console.error('❌ Error seeding database:', error);
process.exit(1);
} finally {
await prisma.$disconnect();
}
}
main();