Fase 2 (expansion): - Francesca: +6 etapas matematicas (5-10), +7 etapas lectura (3-9), +2 ortografia - Sebastian: +8 etapas matematicas (4-11), +6 lectura, +3 historia, +3 geografia, +1 banderas - Nuevas paginas: ortografia, lectura, geografia, matematicas - ~900 ejercicios nuevos, paridad ~500 por perfil Fase 3 (bug fixes + hardening): - Fix: SessionLog auto-create en grade route - Fix: engine cache (no borrar antes de revisar) - Fix: FSRS cards actualizadas en flujo curriculum - Fix: responseMs real (no hardcodeado 3000) - Fix: options dentro de content en sebastian etapa-1 - Fix: trazo-letra consonantes crash - Security: execFileSync anti-command-injection en TTS - DB: 18 cascade deletes + indices + unique constraints - APIs debug: reset, state, seed - Docker: espeak-ng + prisma + user/group - E2E: 23 tests nuevos (curriculum-flow.spec.ts) - Code review: tailwind colors, middleware dev mode, eslint config Verificado: tsc exit 0, build exit 0, 61 E2E tests pass
212 lines
5.6 KiB
TypeScript
212 lines
5.6 KiB
TypeScript
import type { Stage } from "../types"
|
|
|
|
const exercises: any[] = []
|
|
let idx = 0
|
|
|
|
// Part 1: Estructura de carta (partes)
|
|
const cartas = [
|
|
{
|
|
instruction: "¿Qué parte de la carta es 'Querido amigo'?",
|
|
correct: "Saludo",
|
|
wrong1: "Despedida",
|
|
wrong2: "Cuerpo",
|
|
emoji: "✉️",
|
|
},
|
|
{
|
|
instruction: "¿Qué parte de la carta es 'Atentamente, Juan'?",
|
|
correct: "Despedida",
|
|
wrong1: "Saludo",
|
|
wrong2: "Fecha",
|
|
emoji: "✍️",
|
|
},
|
|
{
|
|
instruction: "¿Qué parte de la carta es 'Buenos Aires, 15 de marzo'?",
|
|
correct: "Fecha y lugar",
|
|
wrong1: "Saludo",
|
|
wrong2: "Firma",
|
|
emoji: "📅",
|
|
},
|
|
{
|
|
instruction: "¿Qué parte de la carta va al final con tu nombre?",
|
|
correct: "Firma",
|
|
wrong1: "Saludo",
|
|
wrong2: "Destinatario",
|
|
emoji: "🖊️",
|
|
},
|
|
{
|
|
instruction: "¿Cómo se llama la persona que escribe la carta?",
|
|
correct: "Remitente",
|
|
wrong1: "Destinatario",
|
|
wrong2: "Cartero",
|
|
emoji: "📝",
|
|
},
|
|
{
|
|
instruction: "¿Cómo se llama la persona que recibe la carta?",
|
|
correct: "Destinatario",
|
|
wrong1: "Remitente",
|
|
wrong2: "Cartero",
|
|
emoji: "📬",
|
|
},
|
|
]
|
|
|
|
for (const c of cartas) {
|
|
exercises.push({
|
|
id: `seb-lect6-carta-${idx}`,
|
|
stage: 6,
|
|
skillCode: `carta-parte-${idx}`,
|
|
type: "eleccion",
|
|
prerequisites: idx === 0 ? [`seb-lect5-completar-24`] : [exercises[idx - 1].id],
|
|
content: {
|
|
instruction: c.instruction,
|
|
text: c.instruction,
|
|
audioText: c.instruction,
|
|
emoji: c.emoji,
|
|
options: [
|
|
{ label: c.correct, correct: true, id: `c-${idx}` },
|
|
{ label: c.wrong1, correct: false, id: `w1-${idx}` },
|
|
{ label: c.wrong2, correct: false, id: `w2-${idx}` },
|
|
].sort(() => Math.random() - 0.5),
|
|
},
|
|
functionalContext: "Correspondencia interescolar Freinet: conocer las partes de una carta.",
|
|
errorType: "omision-letra",
|
|
})
|
|
idx++
|
|
}
|
|
|
|
// Part 2: Ordenar la carta
|
|
const cartasOrdenar = [
|
|
{
|
|
instruction: "Ordená las partes de una carta:",
|
|
parts: ["Fecha y lugar", "Saludo", "Cuerpo de la carta", "Despedida", "Firma"],
|
|
emoji: "✉️",
|
|
},
|
|
]
|
|
|
|
for (const co of cartasOrdenar) {
|
|
const shuffled = [...co.parts].sort(() => Math.random() - 0.5)
|
|
exercises.push({
|
|
id: `seb-lect6-orden-${idx}`,
|
|
stage: 6,
|
|
skillCode: `carta-orden-${idx}`,
|
|
type: "secuencia",
|
|
prerequisites: [exercises[idx - 1].id],
|
|
content: {
|
|
instruction: co.instruction,
|
|
text: "Ordená las partes de una carta correctamente",
|
|
audioText: "Ordená las partes de una carta",
|
|
emoji: co.emoji,
|
|
sequence: shuffled,
|
|
},
|
|
functionalContext: "Correspondencia interescolar Freinet: ordenar las partes de una carta.",
|
|
errorType: "omision-letra",
|
|
})
|
|
idx++
|
|
}
|
|
|
|
// Part 3: Preguntas sobre correspondencia
|
|
const corresp = [
|
|
{
|
|
q: "¿Con qué frase podés empezar una carta a un amigo?",
|
|
correct: "Querido amigo",
|
|
wrong1: "Señor juez",
|
|
wrong2: "A quien corresponda",
|
|
emoji: "👋",
|
|
},
|
|
{
|
|
q: "¿Cómo podés despedirte en una carta a tu abuela?",
|
|
correct: "Con cariño, tu nieto",
|
|
wrong1: "Atentamente",
|
|
wrong2: "Sinceramente",
|
|
emoji: "💖",
|
|
},
|
|
{
|
|
q: "Además de cartas, ¿qué otra forma de correspondencia existe?",
|
|
correct: "Correo electrónico",
|
|
wrong1: "Teléfono",
|
|
wrong2: "Radio",
|
|
emoji: "📧",
|
|
},
|
|
{
|
|
q: "¿Qué dato debe estar en el sobre para que llegue la carta?",
|
|
correct: "La dirección del destinatario",
|
|
wrong1: "El teléfono del remitente",
|
|
wrong2: "La edad del cartero",
|
|
emoji: "🏠",
|
|
},
|
|
{
|
|
q: "¿Qué se necesita para enviar una carta por correo?",
|
|
correct: "Un sello / estampilla",
|
|
wrong1: "Una foto",
|
|
wrong2: "Un código de barras",
|
|
emoji: "💌",
|
|
},
|
|
{
|
|
q: "¿Qué escribís en el cuerpo de la carta?",
|
|
correct: "Lo que querés contar",
|
|
wrong1: "Solo el saludo",
|
|
wrong2: "Solo la fecha",
|
|
emoji: "📄",
|
|
},
|
|
{
|
|
q: "¿Por qué es importante escribir la fecha en una carta?",
|
|
correct: "Para saber cuándo se escribió",
|
|
wrong1: "Para decorar la hoja",
|
|
wrong2: "Para que llegue más rápido",
|
|
emoji: "📅",
|
|
},
|
|
{
|
|
q: "Si le escribís una carta a tu maestra, ¿qué saludo usás?",
|
|
correct: "Querida maestra",
|
|
wrong1: "Hola, che",
|
|
wrong2: "Señora, le comunico",
|
|
emoji: "👩🏫",
|
|
},
|
|
{
|
|
q: "¿Qué información va en el remitente?",
|
|
correct: "Tu nombre y dirección",
|
|
wrong1: "Solo tu nombre",
|
|
wrong2: "La dirección del destinatario",
|
|
emoji: "📤",
|
|
},
|
|
{
|
|
q: "¿Qué significa 'correspondencia'?",
|
|
correct: "Intercambio de cartas y mensajes",
|
|
wrong1: "Un tipo de baile",
|
|
wrong2: "Un juego de mesa",
|
|
emoji: "📬",
|
|
},
|
|
]
|
|
|
|
for (const cor of corresp) {
|
|
exercises.push({
|
|
id: `seb-lect6-corresp-${idx}`,
|
|
stage: 6,
|
|
skillCode: `correspondencia-${idx}`,
|
|
type: "eleccion",
|
|
prerequisites: [exercises[idx - 1].id],
|
|
content: {
|
|
instruction: cor.q,
|
|
text: cor.q,
|
|
audioText: cor.q,
|
|
emoji: cor.emoji,
|
|
options: [
|
|
{ label: cor.correct, correct: true, id: `c-${idx}` },
|
|
{ label: cor.wrong1, correct: false, id: `w1-${idx}` },
|
|
{ label: cor.wrong2, correct: false, id: `w2-${idx}` },
|
|
].sort(() => Math.random() - 0.5),
|
|
},
|
|
functionalContext: "Correspondencia interescolar Freinet: conocer el formato y propósito de las cartas.",
|
|
errorType: "omision-letra",
|
|
})
|
|
idx++
|
|
}
|
|
|
|
const stage: Stage = {
|
|
id: 6,
|
|
name: "Correspondencia interescolar (Freinet)",
|
|
description: "Aprender la estructura de una carta: saludo, cuerpo, despedida, firma, y cómo escribir correspondencia.",
|
|
exercises,
|
|
}
|
|
|
|
export default stage
|