feat: fase 4 — overhaul, docker, seguridad, métodos europeos
- Eliminada ruta duplicada /sebastian/sumas (código muerto) - Removido topic 'sumas' del engine (reemplazado por 'matematicas') - Creado docker-compose.yml (PostgreSQL + app, 1 comando install) - Dockerfile: copiado prisma CLI al runner stage para db push - APIs debug protegidas: 403 en producción (reset, state, seed) - Audit métodos europeos: 24 archivos corregidos al 100% - Montessori: matemática Francesca + Sebastián - Decroly: lectura, ortografía, historia, geografía, banderas - Borel-Maisonny: lectura inicial Isabella (ya existía) - Freinet: expresión escrita Sebastián (ya existía) - Validación prerequisitos: 0 rotos en contenido nuevo (157 ejercicios) - INSTALL.md: guía completa de instalación - fase4.md: documentación del overhaul - E2E: 2 tests corregidos, 61/61 pasan - TypeScript: exit 0, Build: exit 0
This commit is contained in:
@@ -71,7 +71,7 @@ for (let i = 0; i < lecturas.length; i++) {
|
||||
id: o.toLowerCase().slice(0, 12),
|
||||
})),
|
||||
},
|
||||
functionalContext: 'Leer textos cortos con comprensión.',
|
||||
functionalContext: 'Leer textos cortos con comprensión.. Centro de interés Decroly.',
|
||||
errorType: 'omision-letra',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ for (let i = 0; i < lecturas.length; i++) {
|
||||
id: o.toLowerCase().slice(0, 12),
|
||||
})),
|
||||
},
|
||||
functionalContext: 'Leer textos algo más largos.',
|
||||
functionalContext: 'Leer textos algo más largos.. Centro de interés Decroly.',
|
||||
errorType: 'omision-letra',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ for (let i = 0; i < synonymPairs.length; i++) {
|
||||
{ label: p.word, correct: false, id: `w2-${i}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Enriquecer léxico identificando sinónimos de palabras comunes.",
|
||||
functionalContext: "Enriquecer léxico identificando sinónimos de palabras comunes.. Centro de interés Decroly.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
idx++
|
||||
|
||||
@@ -70,7 +70,7 @@ for (const cuento of cuentos) {
|
||||
emoji: cuento.emoji,
|
||||
sequence: shuffled.map((s) => cuento.secuencia[s]),
|
||||
},
|
||||
functionalContext: "Ordenar eventos de un cuento clásico en secuencia narrativa.",
|
||||
functionalContext: "Ordenar eventos de un cuento clásico en secuencia narrativa.. Centro de interés Decroly.",
|
||||
errorType: "omision-letra",
|
||||
})
|
||||
idx++
|
||||
@@ -114,7 +114,7 @@ for (const cuento of cuentos) {
|
||||
id: o.toLowerCase().slice(0, 12),
|
||||
})),
|
||||
},
|
||||
functionalContext: "Comprensión de cuentos clásicos: responder preguntas sobre la trama.",
|
||||
functionalContext: "Comprensión de cuentos clásicos: responder preguntas sobre la trama.. Centro de interés Decroly.",
|
||||
errorType: "omision-letra",
|
||||
})
|
||||
idx++
|
||||
|
||||
@@ -49,7 +49,7 @@ for (const m of mayusculas) {
|
||||
{ label: m.optionB, correct: m.optionB === m.correct, id: `b-${idx}` },
|
||||
],
|
||||
},
|
||||
functionalContext: "Regla ortográfica: mayúscula inicial de oración.",
|
||||
functionalContext: "Regla ortográfica: mayúscula inicial de oración.. Centro de interés Decroly.",
|
||||
errorType: "omision-letra",
|
||||
})
|
||||
idx++
|
||||
@@ -72,7 +72,7 @@ for (const n of nombres) {
|
||||
{ label: n.wrong, correct: false, id: `w-${idx}` },
|
||||
],
|
||||
},
|
||||
functionalContext: "Regla ortográfica: mayúscula en nombres propios de personas y lugares.",
|
||||
functionalContext: "Regla ortográfica: mayúscula en nombres propios de personas y lugares.. Centro de interés Decroly.",
|
||||
errorType: "omision-letra",
|
||||
})
|
||||
idx++
|
||||
|
||||
@@ -61,7 +61,7 @@ for (let i = 0; i < palabras.length; i++) {
|
||||
id: `opt-${i}-${j}`,
|
||||
})),
|
||||
},
|
||||
functionalContext: "Regla ortográfica: siempre 'm' antes de 'p' y 'b' en español.",
|
||||
functionalContext: "Regla ortográfica: siempre 'm' antes de 'p' y 'b' en español.. Centro de interés Decroly.",
|
||||
errorType: "omision-letra",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ for (const m of mults) {
|
||||
{ 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.',
|
||||
functionalContext: 'Multiplicar números de 1 dígito.. Método Montessori.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
@@ -97,7 +97,7 @@ for (let i = 0; i < lecturas.length; i++) {
|
||||
id: o.toLowerCase().slice(0, 10),
|
||||
})),
|
||||
},
|
||||
functionalContext: 'Leer textos cortos con comprensión.',
|
||||
functionalContext: 'Leer textos cortos con comprensión.. Método Montessori.',
|
||||
errorType: 'omision-letra',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ exercises.push({
|
||||
{ label: 'La Constitución', correct: false, id: 'constitucion' },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: 'Identificar el escudo nacional.',
|
||||
functionalContext: 'Identificar el escudo nacional.. Centro de interés Decroly.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ for (const b of banderas) {
|
||||
{ label: distractor2, correct: false, id: `w2-${idx}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: `Identificar la bandera de ${b.nombre}.`,
|
||||
functionalContext: `Identificar la bandera de ${b.nombre}.. Centro de interés Decroly.`,
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
idx++
|
||||
|
||||
@@ -40,7 +40,7 @@ for (const r of regiones) {
|
||||
{ label: wrong2, correct: false, id: `w2-${idx}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Identificar las regiones geográficas de Argentina.",
|
||||
functionalContext: "Identificar las regiones geográficas de Argentina.. Centro de interés Decroly.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
idx++
|
||||
@@ -65,7 +65,7 @@ for (const p of pcias) {
|
||||
{ label: pcias[(idx + 2) % pcias.length].provincias, correct: false, id: `w2-${idx}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Asociar provincias argentinas con su región geográfica.",
|
||||
functionalContext: "Asociar provincias argentinas con su región geográfica.. Centro de interés Decroly.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
idx++
|
||||
|
||||
@@ -37,7 +37,7 @@ for (let i = 0; i < ejercicios.length; i++) {
|
||||
{ label: e.w2, correct: false, id: `w2-${i}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Geografía argentina: accidentes geográficos como ríos, montañas y climas.",
|
||||
functionalContext: "Geografía argentina: accidentes geográficos como ríos, montañas y climas.. Centro de interés Decroly.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ for (const c of capitales) {
|
||||
{ label: wrong2, correct: false, id: `w2-${idx}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Geografía argentina: emparejar provincias con sus respectivas capitales.",
|
||||
functionalContext: "Geografía argentina: emparejar provincias con sus respectivas capitales.. Centro de interés Decroly.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
idx++
|
||||
|
||||
@@ -13,7 +13,7 @@ const ejercicios = [
|
||||
{ label: 'José de San Martín', correct: false, id: 'sanmartin' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: personajes.',
|
||||
functionalContext: 'Historia argentina: personajes.. Centro de interés Decroly.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
@@ -28,7 +28,7 @@ const ejercicios = [
|
||||
{ label: '1820', correct: false, id: '1820' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: fechas.',
|
||||
functionalContext: 'Historia argentina: fechas.. Centro de interés Decroly.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
@@ -43,7 +43,7 @@ const ejercicios = [
|
||||
{ label: 'Sarmiento', correct: false, id: 'sarmiento' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: símbolos patrios.',
|
||||
functionalContext: 'Historia argentina: símbolos patrios.. Centro de interés Decroly.',
|
||||
errorType: 'confusion-letra',
|
||||
},
|
||||
{
|
||||
@@ -58,7 +58,7 @@ const ejercicios = [
|
||||
{ label: 'Tucumán', correct: false, id: 'tuc' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: provincias.',
|
||||
functionalContext: 'Historia argentina: provincias.. Centro de interés Decroly.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
@@ -73,7 +73,7 @@ const ejercicios = [
|
||||
{ label: '1', correct: false, id: '1' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: símbolos patrios.',
|
||||
functionalContext: 'Historia argentina: símbolos patrios.. Centro de interés Decroly.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
@@ -88,7 +88,7 @@ const ejercicios = [
|
||||
{ label: 'Agosto', correct: false, id: 'agosto' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: fechas patrias.',
|
||||
functionalContext: 'Historia argentina: fechas patrias.. Centro de interés Decroly.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -13,7 +13,7 @@ const ejercicios = [
|
||||
{ label: 'Cruzaron los Andes', correct: false, id: 'andes' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: hechos históricos.',
|
||||
functionalContext: 'Historia argentina: hechos históricos.. Centro de interés Decroly.',
|
||||
errorType: 'omision-letra',
|
||||
},
|
||||
{
|
||||
@@ -28,7 +28,7 @@ const ejercicios = [
|
||||
{ label: 'Rivadavia', correct: false, id: 'rivadavia' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: campañas militares.',
|
||||
functionalContext: 'Historia argentina: campañas militares.. Centro de interés Decroly.',
|
||||
errorType: 'confusion-letra',
|
||||
},
|
||||
{
|
||||
@@ -43,7 +43,7 @@ const ejercicios = [
|
||||
{ label: '500', correct: false, id: '500' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: hechos militares.',
|
||||
functionalContext: 'Historia argentina: hechos militares.. Centro de interés Decroly.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
},
|
||||
{
|
||||
@@ -58,7 +58,7 @@ const ejercicios = [
|
||||
{ label: 'Un monumento', correct: false, id: 'monumento' },
|
||||
],
|
||||
},
|
||||
functionalContext: 'Historia argentina: instituciones.',
|
||||
functionalContext: 'Historia argentina: instituciones.. Centro de interés Decroly.',
|
||||
errorType: 'omision-letra',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -127,7 +127,7 @@ for (let i = 0; i < ejercicios.length; i++) {
|
||||
{ label: e.w2, correct: false, id: `w2-${i}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Historia argentina: independencia (1816), Congreso de Tucumán, Constitución de 1853.",
|
||||
functionalContext: "Historia argentina: independencia (1816), Congreso de Tucumán, Constitución de 1853.. Centro de interés Decroly.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ for (let i = 0; i < ejercicios.length; i++) {
|
||||
{ label: e.w2, correct: false, id: `w2-${i}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Historia argentina: inmigración europea, educación pública, ferrocarril y crecimiento (1853-1930).",
|
||||
functionalContext: "Historia argentina: inmigración europea, educación pública, ferrocarril y crecimiento (1853-1930).. Centro de interés Decroly.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ for (let i = 0; i < ejercicios.length; i++) {
|
||||
{ label: e.w2, correct: false, id: `w2-${i}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Símbolos patrios argentinos: bandera, escudo, himno, escarapela y fechas patrias.",
|
||||
functionalContext: "Símbolos patrios argentinos: bandera, escudo, himno, escarapela y fechas patrias.. Centro de interés Decroly.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ for (let i = 0; i < lecturas.length; i++) {
|
||||
id: o.toLowerCase().slice(0, 15),
|
||||
})),
|
||||
},
|
||||
functionalContext: "Comprensión profunda de textos informativos: extraer idea principal, detalles y secuencia.",
|
||||
functionalContext: "Comprensión profunda de textos informativos: extraer idea principal, detalles y secuencia.. Centro de interés Decroly.",
|
||||
errorType: "omision-letra",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ for (let i = 0; i < lecturas.length; i++) {
|
||||
id: o.toLowerCase().slice(0, 15),
|
||||
})),
|
||||
},
|
||||
functionalContext: "Deducir moralejas, motivaciones y causas implícitas en textos narrativos.",
|
||||
functionalContext: "Deducir moralejas, motivaciones y causas implícitas en textos narrativos.. Centro de interés Decroly.",
|
||||
errorType: "omision-letra",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ for (let i = 0; i < ejercicios.length; i++) {
|
||||
id: o.toLowerCase().slice(0, 20),
|
||||
})),
|
||||
},
|
||||
functionalContext: "Distinguir la idea principal de los detalles de apoyo en textos expositivos.",
|
||||
functionalContext: "Distinguir la idea principal de los detalles de apoyo en textos expositivos.. Centro de interés Decroly.",
|
||||
errorType: "omision-letra",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ for (let i = 0; i < ejercicios.length; i++) {
|
||||
skillCode: `seb-suma-${i + 1}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: i === 0 ? [] : [ejercicios[i - 1].id],
|
||||
functionalContext: 'Sumas de 2-3 dígitos nivel inicial.',
|
||||
functionalContext: 'Sumas de 2-3 dígitos nivel inicial.. Método Montessori.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ for (let i = 0; i < problems.length; i++) {
|
||||
{ label: e.wrong2, correct: false, id: `w2-${i}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Resolver problemas de varios pasos que requieren 2-3 operaciones combinadas.",
|
||||
functionalContext: "Resolver problemas de varios pasos que requieren 2-3 operaciones combinadas.. Método Montessori.",
|
||||
errorType: "discriminacion-auditiva",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ for (const p of perims) {
|
||||
{ label: `${p.peri - 5} cm`, correct: false, id: `w2-${idx}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Calcular perímetros de cuadrados y rectángulos en problemas geométricos.",
|
||||
functionalContext: "Calcular perímetros de cuadrados y rectángulos en problemas geométricos.. Método Montessori.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
idx++
|
||||
@@ -79,7 +79,7 @@ for (const a of areas) {
|
||||
{ label: `${a.area - 5} cm²`, correct: false, id: `w2-${idx}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Calcular áreas de cuadrados y rectángulos en problemas geométricos básicos.",
|
||||
functionalContext: "Calcular áreas de cuadrados y rectángulos en problemas geométricos básicos.. Método Montessori.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
idx++
|
||||
|
||||
@@ -83,7 +83,7 @@ for (let i = 0; i < ejercicios.length; i++) {
|
||||
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.',
|
||||
functionalContext: 'Ejercicios interactivos de sumas con objetos cotidianos.. Método Montessori.',
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ for (let i = 0; i < pctExercises.length; i++) {
|
||||
{ label: e.wrong2, correct: false, id: `w2-${i}` },
|
||||
].sort(() => Math.random() - 0.5),
|
||||
},
|
||||
functionalContext: "Calcular porcentajes básicos (50%, 25%, 10%) aplicados a descuentos, propinas y situaciones cotidianas.",
|
||||
functionalContext: "Calcular porcentajes básicos (50%, 25%, 10%) aplicados a descuentos, propinas y situaciones cotidianas.. Método Montessori.",
|
||||
errorType: "confusion-letra",
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user