feat: multi-profile system with Francesca and Sebastian curricula
- Add Profile enum (ISABELLA, FRANCESCA, SEBASTIAN) to Child model - Add ?profile= query param override to /api/curriculum/next - Pass profile prop from profile-specific pages to ExerciseSession - Fix curriculum import paths (engine uses @/curriculum/ alias) - Clear stale curriculumCache on dev reload - Fix self-referential prerequisites in Francesca etapa-1 - Fix prerequisite chains in Francesca etapa-2,3,4 and Sebastian etapa-2,3 - Add Francesca curriculum: 2-3 digit sums, subtractions, multiplications, short readings - Add Sebastian curriculum: 2-3 digit sums, interactive exercises, Argentine history, flags - All 44 E2E tests pass, TypeScript compiles cleanly
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const lecturas = [
|
||||
{
|
||||
text: 'Ana tiene un gato. El gato es negro. Juegan juntas en el jardín.',
|
||||
options: ['El gato es negro', 'El gato es blanco', 'Tiene un perro'],
|
||||
correcta: 'El gato es negro',
|
||||
emoji: '🐱',
|
||||
},
|
||||
{
|
||||
text: 'La frutilla es roja. La banana es amarilla. La uva es morada.',
|
||||
options: ['La frutilla es roja', 'La banana es roja', 'La uva es verde'],
|
||||
correcta: 'La frutilla es roja',
|
||||
emoji: '🍓',
|
||||
},
|
||||
{
|
||||
text: 'El coche es rojo. La moto es azul. La bici es verde.',
|
||||
options: ['El coche es rojo', 'La moto es roja', 'La bici es roja'],
|
||||
correcta: 'El coche es rojo',
|
||||
emoji: '🚗',
|
||||
},
|
||||
{
|
||||
text: 'La nena lee un cuento. Papá le ayuda. Es un cuento de princesas.',
|
||||
options: ['Lee un cuento', 'Ve la tele', 'Juega a la pelota'],
|
||||
correcta: 'Lee un cuento',
|
||||
emoji: '📚',
|
||||
},
|
||||
{
|
||||
text: 'En la plaza hay un columpio. Los niños se divierten. Es un día soleado.',
|
||||
options: ['Hay un columpio', 'Hay un tobogán', 'No hay nada'],
|
||||
correcta: 'Hay un columpio',
|
||||
emoji: '🎡',
|
||||
},
|
||||
{
|
||||
text: 'La vaca dice mu. La oveja dice bé. El caballo dice ihí.',
|
||||
options: ['La vaca dice mu', 'La oveja dice mu', 'El caballo dice bé'],
|
||||
correcta: 'La vaca dice mu',
|
||||
emoji: '🐄',
|
||||
},
|
||||
{
|
||||
text: 'El helado es de chocolate. La galleta es de vainilla. La gaseosa es de cola.',
|
||||
options: ['El helado es de chocolate', 'La galleta es de chocolate', 'La gaseosa es de limón'],
|
||||
correcta: 'El helado es de chocolate',
|
||||
emoji: '🍦',
|
||||
},
|
||||
{
|
||||
text: 'La luna está en el cielo. El sol se escondió. Las estrellas brillan.',
|
||||
options: ['La luna está en el cielo', 'El sol está en el cielo', 'Las estrellas duermen'],
|
||||
correcta: 'La luna está en el cielo',
|
||||
emoji: '🌙',
|
||||
},
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < lecturas.length; i++) {
|
||||
const l = lecturas[i]
|
||||
exercises.push({
|
||||
id: `fra-lect1-${i}`,
|
||||
stage: 1,
|
||||
skillCode: `lectura-fra-${i}`,
|
||||
type: 'lectura',
|
||||
prerequisites: i === 0 ? [] : [`fra-lect1-${i - 1}`],
|
||||
content: {
|
||||
instruction: `Leé este texto`,
|
||||
text: l.text,
|
||||
audioText: l.text,
|
||||
emoji: l.emoji,
|
||||
options: l.options.map((o) => ({
|
||||
label: o,
|
||||
correct: o === l.correcta,
|
||||
id: o.toLowerCase().slice(0, 12),
|
||||
})),
|
||||
},
|
||||
functionalContext: 'Leer textos cortos con comprensión.',
|
||||
errorType: 'omision-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 1,
|
||||
name: 'Lecturas nivel 1',
|
||||
description: 'Leer textos muy cortos y responder preguntas simples.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,68 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const lecturas = [
|
||||
{
|
||||
text: 'El día de la primavera, todos los chicos van al parque. Llevan merienda, juegan y cantan. Los árboles tienen flores.',
|
||||
options: ['Van al parque', 'Se quedan en casa', 'Ven la tele'],
|
||||
correcta: 'Van al parque',
|
||||
emoji: '🌸',
|
||||
},
|
||||
{
|
||||
text: 'El Río de la Plata es muy ancho. El obelisco está en Buenos Aires. La Casa Rosada es de color rosa.',
|
||||
options: ['El obelisco está en Buenos Aires', 'El obelisco está en Córdoba', 'La Casa Rosada es blanca'],
|
||||
correcta: 'El obelisco está en Buenos Aires',
|
||||
emoji: '🏙️',
|
||||
},
|
||||
{
|
||||
text: 'En el zoológico hay leones, elefantes y jirafas. Los leones duermen mucho. Las jirafas comen hojas.',
|
||||
options: ['Los leones duermen mucho', 'Los leones comen hojas', 'Las jirafas duermen mucho'],
|
||||
correcta: 'Los leones duermen mucho',
|
||||
emoji: '🦁',
|
||||
},
|
||||
{
|
||||
text: 'El cumpleaños de Clara es en octubre. Cumple 8 años. Invita a todos sus compañeros de clase.',
|
||||
options: ['Cumple 8 años', 'Cumple 5 años', 'No invita a nadie'],
|
||||
correcta: 'Cumple 8 años',
|
||||
emoji: '🎂',
|
||||
},
|
||||
{
|
||||
text: 'La biblioteca tiene muchos libros. Los chicos eligen uno y se sientan a leer. Es un lugar muy silencioso.',
|
||||
options: ['Es muy silencioso', 'Es muy ruidoso', 'No hay libros'],
|
||||
correcta: 'Es muy silencioso',
|
||||
emoji: '📚',
|
||||
},
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < lecturas.length; i++) {
|
||||
const l = lecturas[i]
|
||||
exercises.push({
|
||||
id: `fra-lect2-${i}`,
|
||||
stage: 2,
|
||||
skillCode: `lectura-fra2-${i}`,
|
||||
type: 'lectura',
|
||||
prerequisites: i === 0 ? ['fra-lect1-0'] : [`fra-lect2-${i - 1}`],
|
||||
content: {
|
||||
instruction: `Leé y respondé`,
|
||||
text: l.text,
|
||||
audioText: l.text,
|
||||
emoji: l.emoji,
|
||||
options: l.options.map((o) => ({
|
||||
label: o,
|
||||
correct: o === l.correcta,
|
||||
id: o.toLowerCase().slice(0, 12),
|
||||
})),
|
||||
},
|
||||
functionalContext: 'Leer textos algo más largos.',
|
||||
errorType: 'omision-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 2,
|
||||
name: 'Lecturas nivel 2',
|
||||
description: 'Leer textos un poco más largos y responder preguntas.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,51 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const sums = Array.from({ length: 15 }, (_, i) => {
|
||||
const a = Math.floor(i / 3) + 1
|
||||
const b = (i % 3) + 1
|
||||
const res = a + b
|
||||
return { a, b, res }
|
||||
})
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
for (const s of sums) {
|
||||
const prereqs: string[] = []
|
||||
if (s.a > 1 || s.b > 1) {
|
||||
if (s.b === 1) {
|
||||
prereqs.push(`fra1-suma-${s.a - 1}-1`)
|
||||
} else {
|
||||
prereqs.push(`fra1-suma-1-${s.b - 1}`)
|
||||
}
|
||||
}
|
||||
|
||||
exercises.push({
|
||||
id: `fra1-suma-${s.a}-${s.b}`,
|
||||
stage: 1,
|
||||
skillCode: `suma-${s.a + s.b}`,
|
||||
type: 'sensibilizacion',
|
||||
prerequisites: prereqs,
|
||||
content: {
|
||||
instruction: `Sumá: ${s.a} + ${s.b}`,
|
||||
audioText: `${s.a} más ${s.b} es ${s.res}`,
|
||||
emoji: '🧮',
|
||||
color: '#8CB8A0',
|
||||
options: [
|
||||
{ label: String(s.res), correct: true, id: String(s.res) },
|
||||
{ label: String(s.res - 1), correct: false, id: String(s.res - 1) },
|
||||
{ label: String(s.res + 1), correct: false, id: String(s.res + 1) },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: `Sumar ${s.a} + ${s.b} con método Montessori.`,
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 1,
|
||||
name: 'Sumas de 1 dígito',
|
||||
description: 'Aprender sumas básicas del 1 al 9 con material concreto Montessori.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const sums = [
|
||||
{ a: 10, b: 5, res: 15 }, { a: 23, b: 34, res: 57 }, { a: 45, b: 12, res: 57 },
|
||||
{ a: 67, b: 22, res: 89 }, { a: 100, b: 50, res: 150 }, { a: 34, b: 56, res: 90 },
|
||||
{ a: 78, b: 21, res: 99 }, { a: 55, b: 33, res: 88 }, { a: 42, b: 47, res: 89 },
|
||||
{ a: 90, b: 15, res: 105 }, { a: 13, b: 87, res: 100 }, { a: 29, b: 71, res: 100 },
|
||||
{ a: 150, b: 75, res: 225 }, { a: 200, b: 100, res: 300 },
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < sums.length; i++) {
|
||||
const s = sums[i]
|
||||
exercises.push({
|
||||
id: `fra2-suma-${i}`,
|
||||
stage: 2,
|
||||
skillCode: `suma2-${i}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: [`fra2-suma-${i > 0 ? i - 1 : 0}`],
|
||||
content: {
|
||||
instruction: `Sumá: ${s.a} + ${s.b}`,
|
||||
audioText: `${s.a} más ${s.b} es ${s.res}`,
|
||||
emoji: '➕',
|
||||
options: [
|
||||
{ label: String(s.res), correct: true, id: String(s.res) },
|
||||
{ label: String(s.res + (Math.random() > 0.5 ? 10 : -10)), correct: false, id: `wrong-${i}-a` },
|
||||
{ label: String(s.res + (Math.random() > 0.5 ? 1 : -1)), correct: false, id: `wrong-${i}-b` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Sumar números de 2 y 3 dígitos con método Montessori.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 2,
|
||||
name: 'Sumas de 2-3 dígitos',
|
||||
description: 'Resolver sumas de números de 2 y 3 dígitos con material concreto.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,44 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const restas = [
|
||||
{ a: 10, b: 3, res: 7 }, { a: 50, b: 20, res: 30 }, { a: 90, b: 45, res: 45 },
|
||||
{ a: 100, b: 35, res: 65 }, { a: 200, b: 75, res: 125 }, { a: 80, b: 23, res: 57 },
|
||||
{ a: 120, b: 40, res: 80 }, { a: 55, b: 22, res: 33 }, { a: 75, b: 30, res: 45 },
|
||||
{ a: 150, b: 60, res: 90 }, { a: 300, b: 100, res: 200 }, { a: 99, b: 33, res: 66 },
|
||||
{ a: 45, b: 12, res: 33 }, { a: 180, b: 50, res: 130 },
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < restas.length; i++) {
|
||||
const r = restas[i]
|
||||
const wrong1 = r.res - 10
|
||||
const wrong2 = r.res + 10
|
||||
exercises.push({
|
||||
id: `fra3-resta-${i}`,
|
||||
stage: 3,
|
||||
skillCode: `resta2-${i}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: i === 0 ? ['fra1-suma-9-1'] : [`fra3-resta-${i - 1}`],
|
||||
content: {
|
||||
instruction: `Restá: ${r.a} - ${r.b}`,
|
||||
audioText: `${r.a} menos ${r.b} es ${r.res}`,
|
||||
emoji: '➖',
|
||||
options: [
|
||||
{ label: String(r.res), correct: true, id: String(r.res) },
|
||||
{ label: String(wrong1 >= 0 ? wrong1 : r.res + 5), correct: false, id: `wrong-${i}-a` },
|
||||
{ label: String(wrong2), correct: false, id: `wrong-${i}-b` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Restar números de 2 y 3 dígitos con método Montessori.',
|
||||
errorType: 'inversion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 3,
|
||||
name: 'Restas de 2-3 dígitos',
|
||||
description: 'Resolver restas de números de 2 y 3 dígitos con material concreto.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
function multIdx(a: number, b: number) {
|
||||
return (b - 2) * 4 + (a - 1)
|
||||
}
|
||||
|
||||
const mults = Array.from({ length: 12 }, (_, i) => {
|
||||
const a = (i % 4) + 1
|
||||
const b = Math.floor(i / 4) + 2
|
||||
return { a, b, res: a * b }
|
||||
})
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
for (const m of mults) {
|
||||
const idx = multIdx(m.a, m.b)
|
||||
exercises.push({
|
||||
id: `fra4-mult-${m.a}-${m.b}`,
|
||||
stage: 4,
|
||||
skillCode: `mult-${m.a}x${m.b}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: idx > 0 ? [`fra4-mult-${mults[idx - 1].a}-${mults[idx - 1].b}`] : [],
|
||||
content: {
|
||||
instruction: `Multiplicá: ${m.a} × ${m.b}`,
|
||||
audioText: `${m.a} veces ${m.b} es ${m.res}`,
|
||||
emoji: '✖️',
|
||||
options: [
|
||||
{ label: String(m.res), correct: true, id: String(m.res) },
|
||||
{ label: String(m.res + m.a), correct: false, id: `wrong-${m.a}a` },
|
||||
{ label: String(m.res + m.b), correct: false, id: `wrong-${m.b}a` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Multiplicar números de 1 dígito.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const lecturas = [
|
||||
{
|
||||
title: 'El sol',
|
||||
text: 'El sol brilla. Los niños juegan. Comen helado. Están contentos.',
|
||||
question: '¿Qué hacen los niños?',
|
||||
options: ['Juegan', 'Duermen', 'Estudian'],
|
||||
correcta: 'Juegan',
|
||||
emoji: '☀️',
|
||||
},
|
||||
{
|
||||
title: 'La merienda',
|
||||
text: 'Mamá prepara leche. Tomás come tostadas. ¡Qué rico!',
|
||||
question: '¿Qué prepara mamá?',
|
||||
options: ['Leche', 'Café', 'Agua'],
|
||||
correcta: 'Leche',
|
||||
emoji: '🥛',
|
||||
},
|
||||
{
|
||||
title: 'El parque',
|
||||
text: 'En el parque hay un árbol. Los pájaros cantan. Hace sol.',
|
||||
question: '¿Dónde están los pájaros?',
|
||||
options: ['En el parque', 'En el cielo', 'En casa'],
|
||||
correcta: 'En el parque',
|
||||
emoji: '🌳',
|
||||
},
|
||||
{
|
||||
title: 'La familia',
|
||||
text: 'Papá lee un libro. Mamá cocina. Los niños ayudan.',
|
||||
question: '¿Qué lee papá?',
|
||||
options: ['Un libro', 'El diario', 'Una carta'],
|
||||
correcta: 'Un libro',
|
||||
emoji: '📖',
|
||||
},
|
||||
{
|
||||
title: 'El río',
|
||||
text: 'El río corre. El pez nada. La rana salta.',
|
||||
question: '¿Qué hace la rana?',
|
||||
options: ['Salta', 'Nada', 'Vuela'],
|
||||
correcta: 'Salta',
|
||||
emoji: '🐸',
|
||||
},
|
||||
]
|
||||
|
||||
for (let i = 0; i < lecturas.length; i++) {
|
||||
const l = lecturas[i]
|
||||
exercises.push({
|
||||
id: `fra4-lectura-${i}`,
|
||||
stage: 4,
|
||||
skillCode: 'lectura-corta',
|
||||
type: 'lectura',
|
||||
prerequisites: i === 0 ? ['fra4-mult-1-2'] : [`fra4-lectura-${i - 1}`],
|
||||
content: {
|
||||
instruction: `Leé: ${l.title}`,
|
||||
text: l.text,
|
||||
audioText: l.text,
|
||||
emoji: l.emoji,
|
||||
options: l.options.map((o) => ({
|
||||
label: o,
|
||||
correct: o === l.correcta,
|
||||
id: o.toLowerCase().slice(0, 10),
|
||||
})),
|
||||
},
|
||||
functionalContext: 'Leer textos cortos con comprensión.',
|
||||
errorType: 'omision-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 4,
|
||||
name: 'Multiplicaciones y lecturas',
|
||||
description: 'Multiplicaciones de 1 dígito y lectura comprensiva de textos cortos.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,73 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const banderas = [
|
||||
{ id: 'buenos-aires', nombre: 'Buenos Aires', color: '#009688', emoji: '🌿' },
|
||||
{ id: 'cordoba', nombre: 'Córdoba', color: '#2196F3', emoji: '⛰️' },
|
||||
{ id: 'santafe', nombre: 'Santa Fe', color: '#FFC107', emoji: '🌾' },
|
||||
{ id: 'mendoza', nombre: 'Mendoza', color: '#4CAF50', emoji: '🍇' },
|
||||
{ id: 'tucuman', nombre: 'Tucumán', color: '#FF5722', emoji: '🌶️' },
|
||||
{ id: 'salta', nombre: 'Salta', color: '#00BCD4', emoji: '🏔️' },
|
||||
{ id: 'entrerios', nombre: 'Entre Ríos', color: '#8BC34A', emoji: '🌿' },
|
||||
{ id: 'neuquen', nombre: 'Neuquén', color: '#3F51B5', emoji: '🏔️' },
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < banderas.length; i++) {
|
||||
const b = banderas[i]
|
||||
const distractor = banderas[(i + 1) % banderas.length]
|
||||
exercises.push({
|
||||
id: `seb-bandera-${b.id}`,
|
||||
stage: 1,
|
||||
skillCode: `bandera-${b.id}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: i === 0 ? [] : [`seb-bandera-${banderas[i - 1].id}`],
|
||||
content: {
|
||||
instruction: `¿De qué provincia es esta bandera?`,
|
||||
audioText: `Esta es la bandera de ${b.nombre}`,
|
||||
emoji: b.emoji,
|
||||
options: [
|
||||
{ label: b.nombre, correct: true, id: b.id },
|
||||
{ label: distractor.nombre, correct: false, id: distractor.id },
|
||||
{ label: banderas[(i + 2) % banderas.length].nombre, correct: false, id: banderas[(i + 2) % banderas.length].id },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: `Identificar la bandera de ${b.nombre}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
const escudo = {
|
||||
id: 'escudo-nacional',
|
||||
nombre: 'Escudo nacional',
|
||||
emoji: '🇦🇷',
|
||||
color: '#56A',
|
||||
}
|
||||
|
||||
exercises.push({
|
||||
...escudo,
|
||||
stage: 1,
|
||||
skillCode: `bandera-escudo`,
|
||||
type: 'eleccion',
|
||||
prerequisites: [`seb-bandera-${banderas[banderas.length - 1].id}`],
|
||||
content: {
|
||||
instruction: '¿Qué es el símbolo nacional con el sol?',
|
||||
audioText: 'El escudo nacional tiene dos manos abrazadas y el sol.',
|
||||
emoji: escudo.emoji,
|
||||
options: [
|
||||
{ label: 'El escudo nacional', correct: true, id: 'escudo' },
|
||||
{ label: 'La bandera', correct: false, id: 'bandera' },
|
||||
{ label: 'La Constitución', correct: false, id: 'constitucion' },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Identificar el escudo nacional.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
|
||||
const stage: Stage = {
|
||||
id: 1,
|
||||
name: 'Banderas y símbolos',
|
||||
description: 'Identificar banderas de provincias argentinas y el escudo nacional.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,116 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const ejercicios = [
|
||||
{
|
||||
id: 'seb-h1-1',
|
||||
content: {
|
||||
instruction: '¿Quién fue el primer presidente argentino?',
|
||||
audioText: '¿Quién fue el primer presidente argentino?',
|
||||
emoji: '🇦🇷',
|
||||
options: [
|
||||
{ label: 'Bernardino Rivadavia', correct: true, id: 'rivadavia' },
|
||||
{ label: 'Manuel Belgrano', correct: false, id: 'belgrano' },
|
||||
{ label: 'José de San Martín', correct: false, id: 'sanmartin' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: personajes.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
id: 'seb-h1-2',
|
||||
content: {
|
||||
instruction: '¿En qué año se declaró la independencia?',
|
||||
audioText: '¿En qué año se declaró la independencia?',
|
||||
emoji: '📜',
|
||||
options: [
|
||||
{ label: '1816', correct: true, id: '1816' },
|
||||
{ label: '1800', correct: false, id: '1800' },
|
||||
{ label: '1820', correct: false, id: '1820' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: fechas.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
id: 'seb-h1-3',
|
||||
content: {
|
||||
instruction: '¿Quién creó la bandera argentina?',
|
||||
audioText: '¿Quién creó la bandera argentina?',
|
||||
emoji: '🚩',
|
||||
options: [
|
||||
{ label: 'Manuel Belgrano', correct: true, id: 'belgrano' },
|
||||
{ label: 'San Martín', correct: false, id: 'sanmartin' },
|
||||
{ label: 'Sarmiento', correct: false, id: 'sarmiento' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: símbolos patrios.',
|
||||
errorType: 'confusion-letra',
|
||||
},
|
||||
{
|
||||
id: 'seb-h1-4',
|
||||
content: {
|
||||
instruction: '¿Dónde nació San Martín?',
|
||||
audioText: '¿Dónde nació San Martín?',
|
||||
emoji: '🗺️',
|
||||
options: [
|
||||
{ label: 'Yapeyú', correct: true, id: 'yapeyu' },
|
||||
{ label: 'Buenos Aires', correct: false, id: 'ba' },
|
||||
{ label: 'Tucumán', correct: false, id: 'tuc' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: provincias.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
id: 'seb-h1-5',
|
||||
content: {
|
||||
instruction: 'La bandera tiene celeste y blanco. ¿Cuántos colores tiene?',
|
||||
audioText: 'La bandera tiene celeste y blanco. ¿Cuántos colores tiene?',
|
||||
emoji: '🚩',
|
||||
options: [
|
||||
{ label: '2', correct: true, id: '2' },
|
||||
{ label: '3', correct: false, id: '3' },
|
||||
{ label: '1', correct: false, id: '1' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: símbolos patrios.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
id: 'seb-h1-6',
|
||||
content: {
|
||||
instruction: '¿En qué mes es la fiesta de la independencia?',
|
||||
audioText: 'La independencia se celebra en julio.',
|
||||
emoji: '🎉',
|
||||
options: [
|
||||
{ label: 'Julio', correct: true, id: 'julio' },
|
||||
{ label: 'Mayo', correct: false, id: 'mayo' },
|
||||
{ label: 'Agosto', correct: false, id: 'agosto' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: fechas patrias.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < ejercicios.length; i++) {
|
||||
const e = ejercicios[i]
|
||||
exercises.push({
|
||||
...e,
|
||||
id: e.id,
|
||||
stage: 1,
|
||||
skillCode: 'historia-argentina',
|
||||
type: 'eleccion',
|
||||
prerequisites: i === 0 ? [] : [ejercicios[i - 1].id],
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 1,
|
||||
name: 'Historia argentina nivel 1',
|
||||
description: 'Conocer personajes, fechas y símbolos patrios argentinos.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,86 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const ejercicios = [
|
||||
{
|
||||
id: 'seb-h2-1',
|
||||
content: {
|
||||
instruction: 'La Revolución de Mayo fue en 1810. ¿Qué pasó ese día?',
|
||||
audioText: 'El 25 de Mayo de 1810 empezó la independencia argentina.',
|
||||
emoji: '📜',
|
||||
options: [
|
||||
{ label: 'Crearon el primer gobierno patrio', correct: true, id: 'gobierno' },
|
||||
{ label: 'Ganaron la batalla de San Lorenzo', correct: false, id: 'batalla' },
|
||||
{ label: 'Cruzaron los Andes', correct: false, id: 'andes' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: hechos históricos.',
|
||||
errorType: 'omision-letra',
|
||||
},
|
||||
{
|
||||
id: 'seb-h2-2',
|
||||
content: {
|
||||
instruction: '¿Quién liberó Chile y Perú?',
|
||||
audioText: 'San Martín liberó Chile y Perú.',
|
||||
emoji: '⚔️',
|
||||
options: [
|
||||
{ label: 'San Martín', correct: true, id: 'sanmartin' },
|
||||
{ label: 'Belgrano', correct: false, id: 'belgrano' },
|
||||
{ label: 'Rivadavia', correct: false, id: 'rivadavia' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: campañas militares.',
|
||||
errorType: 'confusion-letra',
|
||||
},
|
||||
{
|
||||
id: 'seb-h2-3',
|
||||
content: {
|
||||
instruction: 'El Ejército de los Andes cruzó la cordillera. ¿Cuántos soldados eran?',
|
||||
audioText: 'El Ejército de los Andes tenía entre 5 y 7 mil soldados.',
|
||||
emoji: '⛰️',
|
||||
options: [
|
||||
{ label: 'Entre 5 y 7 mil', correct: true, id: '5-7k' },
|
||||
{ label: '10 mil', correct: false, id: '10k' },
|
||||
{ label: '500', correct: false, id: '500' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: hechos militares.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
id: 'seb-h2-4',
|
||||
content: {
|
||||
instruction: '¿Qué es el Cabildo?',
|
||||
audioText: 'El Cabildo fue un edificio donde se reunían los vecinos.',
|
||||
emoji: '🏛️',
|
||||
options: [
|
||||
{ label: 'Un edificio donde se reunían', correct: true, id: 'cabildo-reunion' },
|
||||
{ label: 'Un barco', correct: false, id: 'barco' },
|
||||
{ label: 'Un monumento', correct: false, id: 'monumento' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: instituciones.',
|
||||
errorType: 'omision-letra',
|
||||
},
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < ejercicios.length; i++) {
|
||||
const e = ejercicios[i]
|
||||
exercises.push({
|
||||
...e,
|
||||
id: e.id,
|
||||
stage: 2,
|
||||
skillCode: 'historia-avanzada',
|
||||
type: 'eleccion',
|
||||
prerequisites: i === 0 ? ['seb-h1-1'] : [ejercicios[i - 1].id],
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 2,
|
||||
name: 'Historia argentina nivel 2',
|
||||
description: 'Hechos militares y personajes históricos avanzados.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,92 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const ejercicios = [
|
||||
{
|
||||
id: 'seb-suma-1',
|
||||
content: {
|
||||
instruction: 'Sumá: 15 + 27',
|
||||
audioText: '15 más 27 es',
|
||||
emoji: '➕',
|
||||
},
|
||||
options: [
|
||||
{ label: '42', correct: true, id: '42' },
|
||||
{ label: '40', correct: false, id: '40' },
|
||||
{ label: '45', correct: false, id: '45' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'seb-suma-2',
|
||||
content: {
|
||||
instruction: 'Sumá: 34 + 56',
|
||||
audioText: '34 más 56 es',
|
||||
emoji: '➕',
|
||||
},
|
||||
options: [
|
||||
{ label: '90', correct: true, id: '90' },
|
||||
{ label: '80', correct: false, id: '80' },
|
||||
{ label: '100', correct: false, id: '100' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'seb-suma-3',
|
||||
content: {
|
||||
instruction: 'Sumá: 78 + 22',
|
||||
audioText: '78 más 22 es',
|
||||
emoji: '➕',
|
||||
},
|
||||
options: [
|
||||
{ label: '100', correct: true, id: '100' },
|
||||
{ label: '99', correct: false, id: '99' },
|
||||
{ label: '101', correct: false, id: '101' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'seb-suma-4',
|
||||
content: {
|
||||
instruction: 'Sumá: 45 + 55',
|
||||
audioText: '45 más 55 es',
|
||||
emoji: '➕',
|
||||
},
|
||||
options: [
|
||||
{ label: '100', correct: true, id: '100' },
|
||||
{ label: '95', correct: false, id: '95' },
|
||||
{ label: '110', correct: false, id: '110' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'seb-suma-5',
|
||||
content: {
|
||||
instruction: 'Sumá: 123 + 456',
|
||||
audioText: '123 más 456 es',
|
||||
emoji: '➕',
|
||||
},
|
||||
options: [
|
||||
{ label: '579', correct: true, id: '579' },
|
||||
{ label: '569', correct: false, id: '569' },
|
||||
{ label: '580', correct: false, id: '580' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < ejercicios.length; i++) {
|
||||
const e = ejercicios[i]
|
||||
exercises.push({
|
||||
...e,
|
||||
stage: 1,
|
||||
skillCode: `seb-suma-${i + 1}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: i === 0 ? [] : [ejercicios[i - 1].id],
|
||||
functionalContext: 'Sumas de 2-3 dígitos nivel inicial.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 1,
|
||||
name: 'Sumas 2-3 dígitos',
|
||||
description: 'Resolver sumas de 2 y 3 dígitos de forma fluida.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,98 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const ejercicios = [
|
||||
{
|
||||
id: 'seb2-manzanas',
|
||||
type: 'conciencia',
|
||||
content: {
|
||||
instruction: 'Agarrá 3 manzanas y 4 naranjas. ¿Cuántas frutas tenés?',
|
||||
audioText: '3 más 4 es',
|
||||
emoji: '🍎🍊',
|
||||
options: [
|
||||
{ label: '7', correct: true, id: '7' },
|
||||
{ label: '6', correct: false, id: '6' },
|
||||
{ label: '8', correct: false, id: '8' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'seb2-dedos',
|
||||
type: 'conciencia',
|
||||
content: {
|
||||
instruction: 'Mostrá 5 dedos de una mano y 3 de la otra. ¿Cuántos dedos hay?',
|
||||
audioText: '5 más 3 es',
|
||||
emoji: '🖐️',
|
||||
options: [
|
||||
{ label: '8', correct: true, id: '8' },
|
||||
{ label: '7', correct: false, id: '7' },
|
||||
{ label: '9', correct: false, id: '9' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'seb2-pasos',
|
||||
type: 'conciencia',
|
||||
content: {
|
||||
instruction: 'Caminaste 20 pasos. Ahora caminaste 15 más. ¿Cuántos pasos en total?',
|
||||
audioText: '20 más 15 es',
|
||||
emoji: '👣',
|
||||
options: [
|
||||
{ label: '35', correct: true, id: '35' },
|
||||
{ label: '30', correct: false, id: '30' },
|
||||
{ label: '40', correct: false, id: '40' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'seb2-bloques',
|
||||
type: 'conciencia',
|
||||
content: {
|
||||
instruction: 'Tenés 10 bloques rojos y 12 bloques azules. ¿Cuántos bloques tenés?',
|
||||
audioText: '10 más 12 es',
|
||||
emoji: '🧱',
|
||||
options: [
|
||||
{ label: '22', correct: true, id: '22' },
|
||||
{ label: '21', correct: false, id: '21' },
|
||||
{ label: '23', correct: false, id: '23' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'seb2-monedas',
|
||||
type: 'conciencia',
|
||||
content: {
|
||||
instruction: 'Tenés 50 pesos y encontrás 75 más. ¿Cuántos pesos tenés?',
|
||||
audioText: '50 más 75 es',
|
||||
emoji: '🪙',
|
||||
options: [
|
||||
{ label: '125', correct: true, id: '125' },
|
||||
{ label: '115', correct: false, id: '115' },
|
||||
{ label: '130', correct: false, id: '130' },
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < ejercicios.length; i++) {
|
||||
const e = ejercicios[i]
|
||||
exercises.push({
|
||||
id: e.id,
|
||||
stage: 2,
|
||||
skillCode: `suma-inter-${e.id}`,
|
||||
type: e.type as any,
|
||||
prerequisites: i === 0 ? ['seb-suma-1'] : [ejercicios[i - 1].id],
|
||||
...e.content,
|
||||
functionalContext: 'Ejercicios interactivos de sumas con objetos cotidianos.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 2,
|
||||
name: 'Sumas interactivas',
|
||||
description: 'Resolver sumas con objetos cotidianos: frutas, bloques, pasos.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
const desafios = [
|
||||
{ a: 45, b: 67, res: 112 }, { a: 99, b: 88, res: 187 }, { a: 150, b: 250, res: 400 },
|
||||
{ a: 333, b: 444, res: 777 }, { a: 200, b: 555, res: 755 }, { a: 123, b: 321, res: 444 },
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
for (let i = 0; i < desafios.length; i++) {
|
||||
const d = desafios[i]
|
||||
exercises.push({
|
||||
id: `seb3-desafio-${i}`,
|
||||
stage: 3,
|
||||
skillCode: `suma-challenge-${i}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: i === 0 ? ['seb2-monedas'] : [`seb3-desafio-${i - 1}`],
|
||||
content: {
|
||||
instruction: `Desafío: ${d.a} + ${d.b}`,
|
||||
audioText: `Sumá: ${d.a} más ${d.b}`,
|
||||
emoji: '🏆',
|
||||
options: [
|
||||
{ label: String(d.res), correct: true, id: String(d.res) },
|
||||
{ label: String(d.res + 10), correct: false, id: `c${i}a` },
|
||||
{ label: String(d.res - 5), correct: false, id: `c${i}b` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Desafío de sumas avanzadas. Utilizá descomposición.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
const stage: Stage = {
|
||||
id: 3,
|
||||
name: 'Desafíos de sumas',
|
||||
description: 'Sumas 3 dígitos desafiantes con método Montessori.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
Reference in New Issue
Block a user