Generador de evaluaciones
Un editor de pruebas donde lo que se ve en pantalla es la hoja impresa, las preguntas y alternativas se reordenan arrastrándolas, cada pregunta queda categorizada por objetivo de aprendizaje e indicador, y hay herramientas de IA que consumen una bolsa de tokens del establecimiento.
1El problema
Crear una prueba en WebClass hoy pasa por el módulo que vive en el repo
vanilla (sistema/webclass/home/preguntas,
home/pruebas, home/evaluacionesbanco,
home/importarpreguntas). Tiene lo esencial y lleva años
funcionando, pero arrastra cuatro problemas concretos:
- El profesor no ve cómo va a quedar la prueba hasta que la descarga. Edita en formularios y recién al imprimir descubre que una pregunta quedó cortada entre dos páginas, o que la hoja se fue a tres páginas.
- Reordenar es caro. Cambiar una pregunta de lugar o mover una alternativa obliga a editar campos de orden, no a arrastrar.
- La categorización existe en la base pero está escondida. Ya hay tablas de objetivos, habilidades e indicadores por pregunta (ver §3), y aun así la tabla de especificaciones se arma a mano en una planilla aparte. Y la pantalla deja declarar un solo objetivo por pregunta cuando las tablas admiten varios: las preguntas que integran dos contenidos —las mejores— quedan declaradas a medias. Ver §6.5.b.
- No hay asistencia de IA en ninguna parte del flujo.
- La prueba se arma sin mirar cómo le fue al curso. WebClass sabe el logro de cada objetivo —lo calcula el informe de aprendizaje—, pero eso vive en otra sección, a cuatro clics de donde se crea la evaluación. Se termina decidiendo qué evaluar de memoria, teniendo el dato. funcionalidad nueva
- No se reusa nada. Un profesor escribe unas 40 preguntas al año y al año siguiente las vuelve a escribir. Hoy el camino más rápido para armar una prueba es digitalizar el PDF del año pasado, teniendo esas preguntas en la base. Ver §6.9.b.
- Las preguntas de desarrollo no tienen pauta. Son las únicas que no se corrigen solas, y hoy la pauta de corrección no dice nada de ellas: «6 puntos de desarrollo» los reparte cada profesor a ojo, y con dos cursos paralelos eso es una diferencia de nota que después nadie puede explicar. funcionalidad nueva
No es un módulo nuevo desde cero: es llevar a Laravel el editor que hoy está en vanilla, sobre las mismas tablas. Si se crean tablas paralelas, el banco de preguntas del establecimiento queda partido en dos y la corrección de respuestas de alumnos —que sigue en vanilla— deja de encontrar sus preguntas.
La excepción, y es una sola: la rúbrica por pregunta (§6.4) no existe hoy —es la funcionalidad nueva que este documento propone— y es lo único que pide tocar el modelo de datos fuera de las tablas de tokens. Va marcada funcionalidad nueva donde aparece.
Lo demás marcado como nuevo —el banco de items, la categorización múltiple, el plan del generador con IA— es pantalla: se apoya en tablas que ya existen y con la forma que ya tienen.
2Quién lo usa
| Rol | Qué hace con esto | Qué le importa |
|---|---|---|
| Profesor de asignatura | Arma la prueba, la imprime, la aplica. | Que salga bien impresa y que se demore poco. |
| Jefe de UTP | Revisa que la prueba cubra los objetivos acordados antes de autorizarla. | La tabla de especificaciones y la cobertura por OA. |
| Coordinador de departamento | Valida preguntas para que entren al banco del establecimiento. | Que las preguntas lleguen categorizadas y con su retroalimentación escrita. |
3Lo que ya existe en la base — reusar, no recrear
Relevado el 2026-09-11 leyendo los DAO del repo vanilla y los modelos Eloquent de
wc-laravel/app/. La estructura para casi todo lo que pide este
gadget ya está.
| Tabla | Para qué | Modelo Eloquent que ya existe |
|---|---|---|
prueba | Cabecera: título, instrucciones, sector, colegio, profesor, tipo, estado, visible, revisada, validado | App\Prueba |
pregunta | El ítem: texto, tipo, dificultad, penalización, y tres campos de retroalimentación (retrocorrecta, retroparcial, retroincorrecta) | App\Pregunta |
prueba_preguntas | Qué preguntas tiene una prueba, y en qué orden | App\PruebaPregunta (sin $table declarado) |
respuesta_alternativa | Alternativas de selección múltiple | — |
respuesta_vof | Verdadero / falso | — |
respuesta_corta | Respuesta corta | — |
respuesta_enpareja_ordenrespuesta_enpareja_vinculo | Emparejamiento (dos columnas) | — |
pregunta_atributo( pregunta, eje, tipo, atributo) | Objetivos, habilidades y contenidos por pregunta. Es la categorización que pide el gadget. N:M: admite varios por pregunta (§6.5.b). Columnas verificadas en el código; tipo dice a qué catálogo apunta atributo: 1 contenidos · 2 aprendizaje · 3 objetivos · 4 habilidades · 7 actitudes — cada uno su propia tabla, con id, nombre, nomenclatura y eje. No guarda el nivel (§11) | — |
pregunta_indicador → indicadores | Indicador de evaluación por pregunta, con columna objetivo que lo amarra al OA. También N:M | App\EvaluationIndicators |
pregunta_ambito / prueba_ambito | Ámbito y nivel | App\AmbitoPregunta |
prueba_atributo | Atributos a nivel de prueba | — |
respuesta_*_alumno | Respuestas rendidas. No se toca en este gadget, pero manda dos veces: si cambia el id de una pregunta ya rendida se pierde la corrección, y de acá sale el logro por objetivo de §5.3 | varios |
curso | Los cursos del establecimiento. Los lee el quinto camino de creación (§5.3); sólo lectura | — |
- No crear tablas nuevas para preguntas, alternativas ni categorización. Se escribe sobre las que ya existen.
- Lo nuevo en la base son tres tablas para los tokens de IA —la bolsa
del colegio, el reparto que el manager hace entre los profesores y el consumo
(§7)— y
dos columnas anulables:
rubrica.id_pregunta, para la rúbrica por pregunta —funcionalidad nueva que este documento propone (§6.4)—, yprueba.encabezado, un JSON con las casillas que llena el alumno (§6.8.c). Máspregunta_valoracion, una tabla chica para saber qué preguntas del banco y de la IA el profesor volvería a usar (§6.11). Y, para el recurso compartido (§6.4.b), dónde guardar el texto: elpregunta.idrecursoque WebClass ya tiene apunta a la tablaarchivoy sirve para una imagen, no para texto. La retroalimentación, incluida la de cada alternativa, ya tiene dónde guardarse (§6.6). - Confirmar los nombres de columna antes de programar. Se verificaron los
nombres de tabla en los DAO; las columnas de las tablas
respuesta_*ypregunta_atributohay que leerlas directamente de la base de producción.
4Dónde vive en wc-laravel
El producto no tiene un layout común: cada módulo trae el suyo. Este gadget necesita ser un módulo propio.
resources/views/evaluaciones/
├── layouts/header.blade.php layout propio del modulo
├── crear.blade.php pantalla 1
└── editor.blade.php pantalla 2
resources/js/evaluaciones/evaluaciones.js entrada Vue 2
resources/sass/evaluaciones.scss
app/Http/Controllers/Evaluaciones/
├── EvaluacionController.php CRUD de la prueba
├── PreguntaController.php alta/edicion/orden de preguntas
├── CategorizacionController.php OA, indicador, atributos
└── AsistenteIaController.php herramientas de IA + tokens
Una línea más en webpack.mix.js
.js('resources/js/evaluaciones/evaluaciones.js', 'public/js')
Rutas (routes/web.php)
Route::group(['prefix' => 'evaluaciones', 'namespace' => 'Evaluaciones'], function () {
Route::get('/crear', 'EvaluacionController@crear');
Route::post('/', 'EvaluacionController@store');
Route::get('/{prueba}/editor', 'EvaluacionController@editor');
Route::post('/{prueba}/orden', 'PreguntaController@reordenar');
Route::post('/{prueba}/guardar', 'EvaluacionController@guardar');
Route::post('/ia/{herramienta}','AsistenteIaController@ejecutar');
});
- Laravel 5.7 sobre PHP 7.1. Nada de
match, propiedades tipadas, argumentos nombrados ni arrow functions de PHP 7.4. - Vue 2 (el
webpack.mix.jsfija el aliasvue$ → vue/dist/vue.common.js). No Vue 3, no Composition API. - Conviven jQuery, Bootstrap 4, DataTables y Select2. El editor puede ser Vue puro, pero no debe romper los plugins jQuery que ya cargan otras pantallas.
- El producto corre sobre MySQL (9 conexiones declaradas en
config/database.php), no SQL Server. Producción está en MySQL 8.4 —confirmado el 23-09—, que es bastante más nuevo que el Laravel que lo consulta.
JSONnativo paraprueba.encabezado(§6.8.c): valida al escribir. Y si alguna vez hace falta consultar dentro, se puede indexar un camino del JSON con una columna generada —no hace falta ahora, pero deja de ser un callejón sin salida—.- Las restricciones
CHECKse aplican de verdad. En 5.7 se parseaban y se ignoraban. Sirve parapregunta_valoracion.valor(§6.11), que sólo admite 1 y −1, y para que un cupo de tokens no pueda quedar negativo (§7). - Funciones de ventana y CTE, que son justo lo que pide el logro por objetivo —promedios y rankings por atributo— sin armar subconsultas anidadas.
- Ninguna de las columnas que este gadget toca choca con las palabras que
pasaron a ser reservadas en MySQL 8 (
rank,groups,rows,over,window,system…). Revisado sobre las tablas de §4.
Un detalle de operación, no de este gadget: en 8.4 el
mysql_native_password ya no viene activo. Si el sistema conecta hoy
es porque el asunto está resuelto; sólo hay que tenerlo presente si se
crea un usuario o una conexión nueva para esta funcionalidad.
5Pantalla 1 — Crear el recurso
Arriba, el título de la herramienta —«Generador de evaluaciones»— y debajo el nombre del recurso con su etiqueta «Nombre:». Los dos juntos y en ese orden: sin el título no se sabe en qué herramienta se está, y sin la etiqueta el nombre del recurso se lee como el título de la pantalla y nadie descubre que es editable.
Después, tres selectores y cuatro caminos de creación. Nivel y asignatura son obligatorios: definen qué catálogo de objetivos de aprendizaje se ofrece después, así que no se puede entrar al editor sin ellos.
La primera versión eran cuatro tarjetas en una fila, cada una con su icono y su fondo de color. Gerencia las rechazó por la diagramación, y tenían además un problema de fondo: presentaban como equivalentes cosas que no lo son, y el color de cada tarjeta no significaba nada —era decoración—.
Los cuatro caminos se parten en dos grupos, que es la diferencia que de verdad existe:
- Empezar a escribir — desde cero, o desde un archivo que el profesor ya tiene.
- Partir del currículo — de la tabla de especificaciones o del logro del curso. Son los dos que consumen tokens, y por eso los dos llevan su etiqueta.
Cada camino es una fila a lo ancho: título, una bajada de una línea y «Comenzar →» a la derecha. Sin iconos y sin fondo de color; el único color es el azul de acción del producto, y aparece al pasar por encima. Ocupa la mitad del alto, se lee de arriba abajo como el resto del formulario, y admite un quinto camino sin rediseñar nada.
El «Comenzar →» no es decoración: una fila con un título y una bajada se lee como un párrafo, y sin algo que diga que es pulsable nadie le hace clic.
Elegir el camino crea el recurso. El paso intermedio no aportaba nada: marcar «desde cero» y después confirmar «Crear» eran dos clics para una sola decisión, y el botón deshabilitado obligaba a adivinar qué faltaba.
- Desde cero entra al editor de inmediato.
- A partir de tabla de especificaciones y a partir de situación curso/alumno abren la misma pantalla (§5.2) —la segunda con el logro delante (§5.3)—, y entran al editor cuando se decidió cuántas preguntas de cada fila.
- Digitalizar desde un archivo abre su diálogo al tiro, y entra cuando las preguntas reconocidas quedaron revisadas e importadas.
- Desde tabla de especificaciones abre su panel, y entra con el botón «Crear N preguntas» que aparece recién cuando la tabla está leída y sus columnas identificadas. Este camino sí necesita confirmación: hay que revisar el mapeo de columnas antes de armar nada.
- Si falta el nivel o la asignatura, el clic avisa cuál falta en vez de no hacer nada.
«Desde el banco de items» salió de la creación. El banco se usa desde el botón + del editor, para traer items sueltos a una prueba que ya existe. Empezar una prueba entera desde el banco era la misma pantalla de búsqueda abierta dos veces.
| Camino | Qué hace | Nota |
|---|---|---|
| Desde cero | Editor con la hoja vacía. | El más simple; sirve de base para los otros. |
| Digitalizar desde un archivo | Sube la prueba en PDF o en Word y separa preguntas y alternativas. | El resultado siempre queda en revisión: el reconocimiento de fórmulas e imágenes falla seguido. |
| A partir de tabla de especificaciones funcionalidad nueva | La tabla del currículo: qué objetivos y qué habilidades entran, cuántas preguntas de cada uno, de qué tipos, y si salen del banco o de la IA. Ver §5.2. | Reúne lo que antes eran dos tarjetas. El Excel de UTP se importa acá y llena esta misma tabla. Consume tokens sólo por lo generado, y el costo se ve antes. |
| A partir de situación curso/alumno funcionalidad nueva | La misma pantalla, con el logro de cada objetivo y de cada habilidad según todo lo que el curso —o los alumnos que se elijan dentro de él— ya rindieron. Ver §5.3. | El único camino que parte de datos y no de la memoria del profesor. |
Se puede entregar por etapas. «Desde cero» y «desde el banco» son el mínimo para reemplazar lo que hay hoy. El PDF y la tabla de especificaciones pueden ir en una segunda entrega sin bloquear nada.
5.1 Importar la tabla de especificaciones
La tabla ya existe en el colegio, en una planilla de UTP. Obligar a reescribirla campo por campo dentro de WebClass es la forma más segura de que nadie use esta función. Se aceptan dos entradas:
- Pegar las celdas copiadas de Excel o Google Sheets.
- Subir el archivo (
.xlsx,.xls,.csv).
Después de leerla se muestra una vista previa con las columnas identificadas — objetivo, indicador, nº de preguntas, puntaje, habilidad, dificultad, eje — y el docente corrige la que esté mal antes de continuar. Con eso se crean las preguntas vacías, cada una ya asignada a su OA e indicador, repartiendo el puntaje de la fila entre sus preguntas.
- No se adivina el formato: se propone y se confirma. Cada colegio titula
sus columnas distinto. Se detecta el rol por el título
(
/objetivo|oa/,/indicador/,/nº|cantidad|preguntas/…) y se deja un select por columna para corregirlo. - El separador se detecta. Excel y Sheets ponen TAB en el
portapapeles; un
.csvexportado en Chile suele venir con punto y coma, no con coma. - Hay que respetar las comillas. Un indicador como
"Resuelve problemas de área, perímetro y volumen"lleva coma adentro: partir por coma a secas lo corta en dos columnas y descuadra la fila entera. También hay que tratar""como comilla literal. - Si no hay fila de títulos, igual se puede. Se detecta mirando si la primera fila trae números; si no los hay, se asume que son títulos.
- Los OA importados pueden no estar en el catálogo. Hay que agregarlos igual al desplegable de categorización — si no, al abrir la pregunta el select aparece en «sin asignar» y se pierde en silencio lo que traía la especificación. Lo mismo con el indicador.
composer.json de wc-laravel ya trae cuatro:
maatwebsite/excel 3.1, phpoffice/phpspreadsheet,
box/spout y cyber-duck/laravel-excel. La primera se usa en
todo app/Exports/, así que el equipo ya la conoce — y sirve
tanto para exportar como para importar.
El .xlsx se lee en el servidor, no en el navegador. El pegado y
el .csv sí se pueden procesar en el cliente, que da respuesta
instantánea; el .xlsx es un ZIP con XML adentro y no vale la pena
resolverlo en JavaScript teniendo la librería en PHP.
Precedente útil: el módulo home/importarpreguntas del repo
vanilla ya importa preguntas desde Excel, con plantillas por tipo
(corta.xls, desarollo.xls, emparejamiento.xls,
fyv.xls). Conviene mirar esas plantillas antes de inventar un formato.
5.2 La tabla: qué se mide y cuántas preguntas de cada cosa funcionalidad nueva
Dos de los cuatro caminos —«a partir de tabla de especificaciones» y «a partir de la situación del curso»— abren la misma pantalla, en pantalla propia. Es una tabla con una fila por objetivo (o por habilidad) del nivel, y en cada fila se decide cuántas preguntas y de dónde salen. La diferencia entre los dos caminos son dos columnas: el de curso trae el logro, el otro no.
«Desde la tabla de especificaciones» y «con ayuda de la IA» preguntaban lo mismo —qué objetivos y cuántas preguntas de cada uno— y se diferenciaban sólo en de dónde salía cada pregunta: una estructura vacía para llenar a mano en un caso, una propuesta de la IA en el otro.
Eso no es un camino distinto: es una columna más, y se decide fila por fila, porque la respuesta cambia por objetivo. Del banco cuando hay material —que es lo barato y lo ya validado—, con IA cuando no lo hay. Obligar a elegir una sola fuente para toda la prueba era la pregunta equivocada.
El Excel de UTP no desapareció. Sigue estando, pero ahora llena esta tabla en vez de saltarse la pantalla: lo importado se revisa en el mismo lugar donde se decide todo lo demás. Lo que no calce con el catálogo del nivel se dice —cuántas filas y cuáles— en vez de descartarse en silencio.
Objetivos o habilidades — dos pestañas sobre la misma tabla
El currículo se mira de dos maneras y las dos están en la base, en
pregunta_atributo: qué contenido mide una pregunta y
qué habilidad exige. Hay departamentos que arman la prueba por objetivo y
otros que la arman por habilidad —«necesito tres de analizar»—, y las dos
formas son legítimas.
- La pestaña cambia qué lista se ve, no la prueba: se puede pedir 2 preguntas de un objetivo y 3 de una habilidad, y las dos cosas valen a la vez.
- Y de más de un nivel. En el camino de la tabla, el nivel y la asignatura del catálogo se eligen ahí mismo y cambiarlos no borra lo ya pedido: se acumula. Un recuperativo mide objetivos del año anterior junto con los del año en curso, y la prueba tiene que poder decirlo. Cada pregunta sale del banco de su propio nivel y entra marcada como ajena si se aparta del de la evaluación.
- Cambiar de pestaña no borra lo pedido en la otra, y el rótulo de cada una lleva la cuenta: sin eso, lo decidido en la pestaña que no se está mirando es invisible y se vuelve a pedir.
- «Proponer» rehace sólo la pestaña y el nivel que se están mirando. Vaciar todo borraría en silencio trabajo del profesor, que es lo que un botón que dice «proponer» no puede hacer.
- Sobre la tabla va un resumen de todo lo pedido —de las dos pestañas y de todos los niveles—, con lo de otro nivel marcado. Sin eso, la tabla en pantalla muestra una fracción de lo decidido y el resto es invisible: se vuelve a pedir.
Consecuencia directa de lo anterior, y no es un detalle de implementación: «Aplicar» de 1° Medio y «Aplicar» de 2° Medio son la misma cadena. Con la habilidad sola como identificador se pisan entre sí, y al cambiar de nivel se pierde lo pedido en el anterior. Lo pedido se guarda contra tipo + nivel + asignatura + código.
Lo mismo vale al importar el Excel de UTP: el código de cada objetivo se busca en todos los niveles de esa asignatura, no sólo en el que está a la vista. Una tabla de UTP para un recuperativo trae objetivos de dos años, y descartar los del otro nivel sería perder justo lo que distingue a esa prueba.
Arriba de todo, una fila comodín: «Cualquiera del nivel» funcionalidad nueva
No todo profesor arma la prueba objetivo por objetivo. Hay quien quiere diez preguntas de 2° Medio · Matemática y revisarlas después, y sin esta fila ese camino obligaba a repartir a mano entre catorce objetivos para pedir algo que da lo mismo de cuál salga. Era el atajo que tenía la tarjeta del plan de IA antes de fusionarla con esta pantalla, y se repone acá.
- No significa «sin objetivo»: significa «elígelo tú». Lo que llega del banco viene con el suyo. Lo que genera la IA sale repartido por el catálogo del nivel —un objetivo distinto por pregunta, con su indicador— y llega categorizado, con el enunciado diciendo que el objetivo lo eligió la plataforma para que el profesor lo revise. Una pregunta sin categorizar dejaría la prueba fuera del banco y fuera de la tabla de especificaciones, que es justo lo que esta pantalla existe para llenar.
- El banco que ofrece es el del nivel entero, no el de un objetivo: por eso el número de esa fila es mucho más grande que el de las de abajo.
- No entra en las cuentas del currículo. No se cuenta entre los objetivos del nivel, no tiene logro que mostrar —en el camino del curso sus tres columnas dicen «no aplica»— y «Proponer» no la toca: proponer reparte por el currículo, que es lo contrario de lo que la fila significa.
- Sólo en la pestaña de Objetivos. En Habilidades no aparece: ahí cada pregunta generada ya trae la suya, y «cualquier habilidad» no le ahorra nada a nadie.
- Lleva clave como cualquier otra fila —con su nivel y su asignatura— con el
código reservado
*, así que se acumula al cambiar de nivel igual que las demás y aparece en el resumen de lo pedido.
Abajo, los objetivos propios del colegio funcionalidad nueva
Un colegio mide cosas que el catálogo del Mineduc no trae: un sello del proyecto
educativo, una habilidad que el departamento decidió seguir. WebClass ya lo permite
—es pregunta_atributo_adicional, ver
§6.5.c— y el producto calcula su logro
igual que el de un objetivo del catálogo. Si la tabla no los mostrara, armar la
prueba desde acá sería un retroceso frente a lo que el profesor ya puede hacer.
- Van después del currículo y fuera de su orden. Con curso, el orden de la tabla es la recomendación, y esa recomendación es sobre el catálogo: un objetivo que el colegio se puso a sí mismo no compite con los del Mineduc por el primer lugar.
- Traen su logro en el camino del curso, como cualquier fila, y su banco: la cuenta de preguntas que ya lo declaran.
- No entran en las cuentas del currículo —«3 de 6 objetivos del nivel nunca evaluados» habla del catálogo— y «Proponer» no los toca: cuánto pesan en la prueba lo decide el profesor.
- Salen de lo que el colegio ya escribió en otras preguntas. Debajo de la tabla hay un campo para agregar uno nuevo, que queda pedido con una pregunta. Si se escribe uno casi igual a uno existente —otra mayúscula, sin tilde, con punto final— se usa el existente y se dice: el informe agrupa por el texto exacto y los contaría como dos.
- En la pestaña de Habilidades aparecen las habilidades propias
(
tipo = 4); en la de Objetivos, los objetivos (tipo = 3). - Lo que genera la IA para una fila propia llega con ese objetivo propio, y cuenta como categorizado. Lo que llega del banco trae los suyos, además de su OA.
Borraba todo lo pedido en la pestaña, incluido lo pedido a mano en el comodín, aunque este documento decía que no lo tocaba. Ahora rehace sólo las filas del currículo; el comodín y los propios quedan como el profesor los dejó.
De dónde sale cada pregunta: banco o IA, por fila
- El selector dice cuántas preguntas tiene el banco de esa fila —«Banco 5»— y queda deshabilitado cuando tiene cero. Ese número es el dato con el que se elige.
- Si se piden más de las que el banco tiene, se dice en la misma fila y las que faltan las genera la IA. No se puede fallar en silencio ni repetir el mismo item para llegar al número.
- Las del banco no cuestan tokens y entran listas; las de IA cuestan y entran como borrador. Una pregunta que ya rindieron treinta cursos y una que acaba de escribir un modelo no merecen la misma confianza.
De qué tipos
- Un campo por tipo —selección múltiple, varias correctas, V/F, respuesta corta, desarrollo, términos pareados—. Sin esto salen todas de alternativas, que es lo que produce cualquier generador cuando no se le pregunta.
- El reparto manda sólo sobre lo que genera la IA. Una pregunta traída del banco llega con el tipo que ya tiene, y reescribirlo sería inventar. Por eso la cuenta que tiene que calzar es la de IA, no el total.
- Mientras no calcen se dice cuánto falta y Crear queda deshabilitado; hay un «Repartir automáticamente». Y el reparto se rehace solo cada vez que cambian las cantidades: si no, tocar una fila dejaría la pantalla bloqueada por una cuenta que el profesor no rompió.
- Las preguntas salen intercaladas, no en bloque por tipo.
- Crear imágenes para las generadas: una figura por pregunta, con el generador de §7.b y su mismo precio. El costo se recalcula al marcarlo.
5.3 Lo que agrega el camino curso/alumno: el logro funcionalidad nueva
Los otros caminos parten de lo que el profesor quiere evaluar. Este parte de lo que el curso necesita que le evalúen, que no es lo mismo y casi nunca se mira. Y no se mira por una razón concreta: el dato ya existe en WebClass —lo calcula el informe de aprendizaje—, pero vive en otra sección, a cuatro clics del lugar donde se arma la prueba. Un dato que hay que ir a buscar a otra pantalla es un dato que no se usa.
Se elige un curso y la tabla gana tres columnas: ya evaluado, logro y estado, calculados sobre todas las evaluaciones ya rendidas. Vale para las dos pestañas: un curso puede tener los objetivos al día y estar al debe en «analizar», y eso es lo que la prueba siguiente tendría que ejercitar.
Sólo se ofrecen los cursos del nivel elegido arriba. Mostrar los de otros niveles contradecía el paso anterior —el profesor ya dijo qué nivel iba a evaluar— y cambiaba el catálogo entero por accidente.
Bajo el curso hay un campo de alumnos. Se puede elegir uno o varios, y entonces el logro que muestra la tabla es el de ellos: lo que salga descendido es lo suyo, y la prueba se arma para eso.
Va como el «Para:» de un correo, no como una fila de botones: un curso tiene 34 alumnos y puede tener 45. En botones ocupaban cinco renglones y no se encontraba a nadie. Se escribe para filtrar —sin importar tildes—, lo elegido queda como ficha dentro del campo, Enter agrega el primero que calza y Retroceso con el campo vacío quita la última. Vacío significa todo el curso, y el marcador dice eso mismo.
El motivo es que un promedio de curso esconde justamente al que hay que evaluar distinto. Si la mitad va en 80% y la otra en 40%, el objetivo aparece «en proceso» y nadie se entera. En la maqueta se ve directo: el curso 2° Medio A tiene 2 objetivos bajos y 2 logrados; eligiendo a un alumno descendido pasa a 4 bajos y ninguno logrado —la misma tabla, otra prueba—.
Es la misma consulta del cuadro de arriba con un filtro por alumno: no hay cálculo nuevo ni tabla nueva. Y sirve para lo que hoy no tiene herramienta: la prueba diferenciada de dos o tres alumnos, y el recuperativo de los que quedaron abajo.
El título de la pantalla y las migas dicen de quién es la situación que se está mirando, y la evaluación queda registrada con el curso y los alumnos de los que salió (§6.10).
Un objetivo que el curso nunca rindió no es un 0%: es que no se sabe. Mostrarlo como cero sería afirmar algo falso sobre el curso, y dejarlo fuera de la tabla —que es lo que pasa si se parte de lo evaluado— escondería justamente lo que hay que mirar.
Los dos estados piden cosas distintas: el sin evaluar pide averiguar, el logro bajo pide reforzar. Por eso van con etiquetas separadas, y en este camino el orden de la tabla es la recomendación: primero lo nunca medido, después lo más bajo. Sin curso no hay nada que recomendar y se deja el orden del currículo, que es el que el profesor conoce.
El botón «Proponer según el logro» llena las cantidades solo: 3 a lo nunca evaluado y a lo bajo, 2 a lo que va en proceso y ninguna a lo logrado. Es una propuesta editable, para no partir de una tabla en blanco, que es donde la mayoría abandona.
Los alumnos del PIE se avisan acá, no después de imprimir funcionalidad nueva
Elegido el curso, la pantalla dice cuántos de sus alumnos tienen necesidades educativas especiales, separando permanentes de transitorias, y qué adecuación pide cada diagnóstico. En el campo de alumnos, los del PIE van marcados —tanto en el listado de búsqueda como en la ficha, una vez elegidos— con su tipo a la vista.
Va en esta pantalla y no en otra porque acá es donde se decide la prueba. Si el curso tiene un alumno con discapacidad visual, el tamaño de letra deja de ser una preferencia; si tiene dos con déficit atencional, treinta preguntas apretadas en una hoja es una decisión y no un descuido. Enterarse después de imprimir no sirve de nada.
- No bloquea y no cambia nada solo. Las adecuaciones las define el equipo PIE, no un generador de pruebas. Lo que hace la pantalla es que el dato no pase inadvertido.
- Con alumnos elegidos, el aviso habla de ellos, no del curso: la prueba se está armando para ese grupo. Y si ninguno de los elegidos es del PIE, se dice también, recordando que el curso completo sí tiene.
- Un curso sin alumnos PIE lo dice igual, con un visto. El silencio se lee como «no se comprobó», que es lo contrario de lo que se quiere.
WebClass ya tiene el formulario PIE —su layout es, de hecho, el que
layouts/app.blade.php sirve en el repo—, así que el dato
existe: quién está en el programa y con qué diagnóstico.
Esta pantalla sólo lo lee. No se crea ninguna tabla.
Lo que hay que confirmar antes de programar, y va en el §11:
en qué tabla vive la nómina PIE y con qué campo se
relaciona con curso; si el diagnóstico está codificado
o es texto libre; y quién puede verlo, que es lo más delicado.
Los nombres se muestran. Decidido por WebClass el 23-09: hoy en el colegio esa información ya está a la vista de todos, y a esta funcionalidad sólo entran docentes. Así que el aviso dice quiénes son, no sólo cuántos — que es lo que el profesor necesita para armar la prueba.
Dos límites que igual hay que respetar al programarlo, y que no dependen de esa decisión:
- No ampliar la audiencia. El dato se muestra a quien ya puede verlo. Si mañana esta pantalla se abre a un perfil que hoy no accede al PIE —un administrativo, un sostenedor—, el aviso tiene que dejar de mostrar nombres para ese perfil.
- No sale impreso nunca. El diagnóstico vive en la pantalla donde se arma la prueba, no en la prueba. Ni en la hoja del alumno, ni en la pauta, ni en el PDF que se descarga.
Los alumnos PIE de la maqueta están puestos a mano, respetando los topes del decreto 170: hasta 2 permanentes y 5 transitorias por curso. Se respetaron a propósito —un curso con veinte alumnos PIE no existe, y una maqueta que lo muestre hace discutir un caso que no se da—. El curso 2° Medio B se dejó sin ninguno, para poder ver también esa pantalla.
Las adecuaciones sugeridas por diagnóstico las escribió la maqueta y WebClass las revisó y aprobó el 23-09, de forma provisoria: quedan como están hasta que avisen lo contrario.
Lo que sí conviene dejar resuelto al programarlo: que ese texto se pueda
cambiar sin tocar el código. Es contenido pedagógico, lo va a
corregir el equipo PIE tarde o temprano, y una frase incrustada en un
if convierte una corrección de redacción en un despliegue.
| Columna | Qué muestra | De dónde sale |
|---|---|---|
| Objetivo / Habilidad | Código, nombre y eje, o el nombre de la habilidad | Catálogo Mineduc del nivel |
| Ya evaluado (sólo con curso) | Cuántas preguntas, en cuántas evaluaciones, y la fecha de la última | respuesta_*_alumno → prueba_preguntas → pregunta_atributo |
| Logro (sólo con curso) | Barra y porcentaje: puntaje obtenido sobre posible, del curso completo | La misma consulta |
| Estado (sólo con curso) | Sin evaluar / Bajo / En proceso / Logrado | Los umbrales del informe de aprendizaje, no una escala nueva |
| Preguntas | Cuántas se quieren de esa fila | Lo decide el profesor |
| De dónde | Banco o IA, por fila, con la cuenta de lo que el banco tiene | pregunta_atributo / pregunta_indicador |
El logro por objetivo y por habilidad es una consulta sobre datos que ya están, pero hay tres decisiones que no se pueden tomar desde acá:
- ¿Entran todas las evaluaciones rendidas, o sólo las del año en curso? Un objetivo medido hace dos años, con otros alumnos en el curso, no dice lo mismo.
- ¿Cuentan las pruebas no validadas y los ensayos, o sólo las calificadas?
- Con la categorización múltiple (§6.5.b), una pregunta de dos objetivos: ¿su puntaje se reparte entre los dos, como en la tabla de especificaciones, o cuenta entero en cada uno? Acá son porcentajes, no una suma que deba cuadrar, así que entero en cada uno parece lo correcto —la pregunta midió los dos—, pero hay que decirlo.
Los otros caminos abren un panel bajo las filas porque preguntan dos o tres cosas. Este muestra una tabla de seis columnas con una fila por objetivo del nivel y ahí abajo no se lee. Además es la única pantalla del gadget que se mira antes de decidir, no mientras se trabaja.
Se lee en pasos numerados y el pie queda fijo abajo: con quince objetivos, el total y el botón de crear no pueden quedar al final del scroll.
Tres decisiones de control que no son cosméticas, porque se repiten
una vez por fila: el curso va en tarjetas y no en un desplegable
—se elige una vez y tiene que quedar a la vista mientras se lee la tabla—;
la cantidad va con botones −/+, porque las flechitas nativas de un
campo numérico miden ocho píxeles; y banco o IA son dos botones
a la vista, porque la cuenta del banco es el dato con el que se elige y dentro de
un <select> hay que abrirlo para verla.
6Pantalla 2 — El editor
6.1 El editor está paginado: cada hoja de la pantalla es una página del PDF
El centro de la pantalla no es un lienzo continuo con una línea de corte dibujada encima: son hojas de verdad, separadas, cada una a escala real con su número de página al pie. Cuando el contenido pasa del alto útil, la pregunta siguiente se va a la hoja siguiente, igual que al imprimir. Es lo que resuelve el problema principal del §1.
- Alto útil = alto de la hoja − los dos márgenes. Se van agregando preguntas y, cuando una no cabe, empieza una hoja nueva.
- Una pregunta nunca se parte entre dos páginas. Como efecto, al final de una hoja puede quedar espacio en blanco: es correcto, no es un error de maquetación.
- El enunciado y cada alternativa se editan en el lugar, sin abrir un formulario aparte.
- Al salir de un campo se vuelve a paginar: si el enunciado creció, el corte se movió, y un editor que no lo recalcula deja de decir la verdad.
- Hay que medir el contenido, no la hoja. La hoja tiene
min-heightdel alto de página, así que suscrollHeightvale siempre el alto completo y la comparación se cumple siempre: sale una pregunta por página. El contenido va en un div propio y se mide ese. - Paginar antes de que cargue la tipografía da otro resultado. Con la
fuente de respaldo el mismo contenido medía 940 px y con la definitiva
716 px — una página de diferencia. Hay que repaginar en
document.fonts.ready.
6.2 Los enunciados y las alternativas se escriben en un editor WYSIWYG con LaTeX
Tanto el enunciado como cada alternativa son campos con formato: negrita, cursiva, subrayado, superíndice, subíndice, tipografía, tamaño de letra, imágenes y fórmulas.
La barra de formato flotaba sobre el campo que se estaba editando. Se descartó por tres motivos medidos en la maqueta: se corría con el scroll, tapaba justo la línea que se estaba escribiendo, y obligaba a apuntarle a un blanco que cambiaba de lugar en cada campo.
Ahora un clic sobre el enunciado, sobre una alternativa o sobre las instrucciones abre un modal con la barra siempre en el mismo sitio, arriba, y un área de escritura amplia. El título del modal dice qué se está editando («Alternativa C de la pregunta 4») y bajo los botones va el contexto (tipo de pregunta y puntaje, o si la alternativa es la correcta).
- Aplicar vuelca el texto a la hoja y repagina. Cancelar y Esc descartan.
- Clic fuera del modal = Aplicar. Es la traducción fiel de lo que hacía el editor anterior: al escribir sobre la hoja, pinchar en otra parte confirmaba. Cambiarlo a «descartar» perdería texto sin avisar.
- Los modales se apilan. Fórmula, tabla y gráfico se abren desde el editor de texto, así que Esc tiene que cerrar sólo el de más arriba: si cerrara los dos, cancelar una fórmula se llevaría puesto el texto que se estaba escribiendo.
- Los campos de una sola línea siguen escribiéndose sobre la hoja: el nombre de la prueba, los términos pareados y las respuestas aceptadas. Nunca llevaron barra de formato, y abrir un modal para teclear cuatro palabras sería peor que el problema que resuelve.
- En la hoja esos campos se ven exactamente como se imprimen —esa es la gracia del editor—; lo que cambia es que al pasar el mouse se realzan y al hacer clic se abren. Son focusables y responden a Enter y a espacio.
Consecuencia sobre las fórmulas: en la hoja el texto ya no es editable, así que un clic sobre una fórmula abre el editor del campo completo; el editor de LaTeX se abre al hacerle clic dentro del modal. La fórmula sigue siendo reeditable, a un clic más.
Alineación por fila
La barra trae los cuatro botones habituales —izquierda, centro, derecha y justificado— y se aplican a la fila donde está el cursor, o a lo que esté seleccionado. El botón queda hundido mostrando cómo está alineado eso: sin esa seña, los cuatro se ven iguales y no hay forma de saberlo.
execCommand que hay que esquivar- El texto tiene que estar dentro de bloques. Los enunciados vienen como
texto suelto separado por
<br>. Sobre eso,justifyCenterno encuentra un párrafo al que aplicarse y Chrome termina alineando el campo entero: se pide centrar una línea y se centra todo. La maqueta envuelve cada fila en un<div>al abrir el editor, una vez, y ahí la alineación queda por fila. - Con una imagen seleccionada no se usa
execCommand. Habría que dejarle la selección sobre la imagen, y entonces Chrome toma los límites del rango en el elemento padre: alineaba también el párrafo vecino y dejaba<div>vacíos de regalo. Se escribe eltext-aligndirecto en el bloque que envuelve la imagen.
También hay que leer el estado de la alineación del
text-align calculado, no de queryCommandState: justo
después de aplicarla, queryCommandState devuelve el valor anterior
y el botón queda hundido con un paso de atraso.
Dos formas de poner una imagen: subirla o generarla
La barra trae dos botones distintos, no uno: 🖼️ Subir una imagen y 🎨 Generar una imagen con IA (§7.b). Son dos caminos separados y el segundo cuesta tokens; mezclarlos en un solo botón obligaría a entrar a un formulario de IA al profesor que sólo quiere poner la figura que ya tiene escaneada.
- Acepta PNG, JPEG, WebP y GIF, hasta 12 MB por archivo.
- Se achica en el navegador antes de entrar, a un tope de 1400 px de ancho. Por encima de eso no aporta nada impreso, y el problema es real: una prueba con veinte fotos de celular sin tocar es un PDF de 40 MB que nadie va a poder mandar por correo ni imprimir en el colegio. El aviso dice cuánto se achicó y cuánto pesa al final.
- Los PNG y los GIF se reencodean como PNG, no como JPEG: pasarlos a JPEG les pone fondo blanco y una figura con transparencia queda con un recuadro alrededor.
- La imagen subida se comporta como cualquier otra: se redimensiona tirando de una esquina y se alinea con los botones de la barra.
La maqueta mete la imagen como data: dentro del enunciado, porque no
tiene servidor. En el producto hay que subirla y guardar una URL: un
enunciado con una foto embebida en base64 son cientos de kilobytes en la columna de
texto de pregunta, se replica en cada copia de la prueba y rompe
cualquier búsqueda sobre ese campo.
Hay que definir dónde viven (el gadget no tiene tabla de archivos propia) y quién las puede ver: una imagen de una prueba no rendida no puede quedar en una URL pública adivinable.
El tamaño de una imagen se cambia tirando de una esquina
Las imágenes del enunciado —la generada por IA y la recortada de un PDF— entran con un tamaño de oficio que casi nunca es el que el profesor quiere. Un clic la selecciona y aparecen cuatro tiradores, uno por esquina; se arrastra cualquiera de ellos.
- Mantiene la proporción siempre: se escribe el ancho y el alto queda en
auto. Una figura deformada en una prueba de geometría es un error de contenido, no de estética. - Mientras se arrastra se muestra la medida en píxeles.
- Mínimo 60 px; máximo, el ancho de la columna de la hoja
—no el del modal, que es más ancho—. Midiéndolo contra el
modal, el profesor podía estirar hasta 640 px y en el papel salía
recortada a 570 por el
max-width: había dimensionado contra algo que no era lo que se imprime. - Con la imagen seleccionada, Supr la borra.
- El ancho se guarda en el elemento (
style="width:NNNpx"), así que viaja con el enunciado y sale igual en el PDF.
Si el marco y sus cuatro tiradores vivieran dentro del contenteditable,
entrarían en el HTML que se guarda en el enunciado y terminarían
impresos en la prueba. Van en un elemento aparte, posicionado encima —lo que
obliga a reubicarlo cuando el campo se desplaza o la ventana cambia de
tamaño—.
Por lo mismo, la clase que marca la imagen elegida se saca antes de leer el HTML al aplicar. Es el tipo de basura que no se nota hasta que aparece en un PDF.
Las imágenes van en línea (inline-block) dentro de un
bloque con text-align, no sueltas: con display:block y
margin:auto quedaban siempre centradas y los botones de alineación
no las movían.
Y se recorta: mostrar sólo una parte funcionalidad nueva
Una figura escaneada, generada por IA o traída de un Word casi nunca viene encuadrada: arrastra el enunciado de al lado, media tabla, el borde de la hoja, el número de página del libro. Hasta ahora la única salida era recortarla en otro programa y volver a subirla — un viaje de ida y vuelta por algo que se resuelve con un rectángulo.
- Con la imagen seleccionada aparece ✂ Recortar en su propio marco, que es donde está mirando quien acaba de elegirla.
- Se arrastra un rectángulo sobre la imagen; lo que queda afuera se oscurece, y se dice qué porcentaje del ancho y del alto se va a ver.
- Un clic sin arrastrar no es un recorte: es un clic. Por debajo del 3% se descarta.
- Funciona igual sobre una figura vectorial generada por IA, avisando que al recortarla pasa a ser una imagen de píxeles.
Un recorte es una forma de mirar la imagen, no una manera de destruirla. Si se guarda sólo el resultado, equivocarse de encuadre cuesta volver a conseguir el archivo — que puede ser un escaneo que ya no está. Por eso hay «Quitar el recorte», que devuelve la imagen entera.
En el producto eso se guarda como un rectángulo, no como una imagen nueva.
La imagen sube una vez y el recorte viaja como cuatro números
—x, y, ancho, alto en
fracción del original— junto a su URL. Así el recorte se puede
cambiar después, dos preguntas pueden usar dos recortes de la misma
imagen sin subirla dos veces, y el PDF se arma en el servidor recortando al vuelo.
Guardar la imagen recortada como archivo nuevo duplica el almacenamiento y pierde
justamente lo que hace falta para corregirla.
La maqueta guarda el original en data-original y reemplaza el
src, porque no tiene servidor donde poner el archivo; el
comportamiento visible —recortar y poder volver atrás— es el mismo.
- De toda la prueba, en Opciones: es lo que se usa el 95% de las veces — «esta prueba va en Arial 12». Cambiarlo repagina.
- De un trozo puntual, en la barra del editor de texto: para destacar un dato dentro de un enunciado.
- El tamaño se expresa en puntos, no en píxeles. El profesor piensa en papel, y el pt es la unidad que se traduce sin conversiones a la impresión.
- Sólo tipografías del sistema (Arial, Verdana, Tahoma, Times New Roman, Georgia, Cambria, Courier New y una redondeada tipo «escolar», que en primer ciclo se usa de verdad). Nada de webfonts: la prueba tiene que verse igual en el computador del profesor, en el PDF y en la impresora del colegio.
- Ojo con
execCommand('fontSize'): sólo acepta valores de 1 a 7, que no sirven para trabajar en puntos. Hay que aplicarlo y después reemplazar los<font size="7">por unspancon el tamaño real — o, mejor, dejar que lo resuelva el editor del producto.
La fórmula se inserta escribiendo LaTeX con vista previa en vivo y una fila de atajos para lo más usado (fracción, raíz, ±, ≤, π, Δ, ∑). Una vez puesta se comporta como un objeto: se selecciona entera y al hacer clic se vuelve a abrir el editor de LaTeX. No se puede escribir por dentro, que es lo que la rompería.
El enunciado se guarda como HTML (es lo que el editor WYSIWYG necesita) y
cada fórmula viaja dentro como un <span> que
conserva el LaTeX original en un atributo:
<span class="formula" data-latex="k = \frac{25}{16}">…render…</span>
Así se puede volver a editar la fórmula sin re-interpretar el HTML, y
el día que se cambie de renderizador basta recorrer los
data-latex y volver a pintar. Guardar sólo el HTML renderizado
dejaría las fórmulas inmodificables.
- El editor no hay que elegirlo, ya está. wc-laravel trae tres:
CKEditor (en
pie,pme,gabrielaypreguntaInmersa), Quill (finance,suite/concept) y Trumbowyg (finance, con su configuración enwebpack.mix.js). La recomendación es CKEditor, porque es el que ya usapreguntaInmersa, que es el módulo de preguntas. Tener un cuarto editor en el producto no se justifica. - El renderizador de matemática sí falta. Se buscó en los dos repos: no hay KaTeX, ni MathJax, ni MathQuill, ni WIRIS. Hoy no se pueden escribir fórmulas. Para el navegador, KaTeX (más liviano y rápido que MathJax, y alcanza de sobra para matemática escolar).
- OJO con el PDF. El módulo actual genera el PDF con TCPDF y
mPDF (están en
home/preguntas/BancoDeEvaluaciones/pdf/), y ninguno de los dos renderiza el HTML+CSS que produce KaTeX: las fracciones y las raíces saldrían descuadradas o en blanco. Hay dos salidas y hay que elegir una antes de programar:- generar el PDF con un navegador headless imprimiendo la misma página (lo que garantiza que el PDF sea idéntico al editor), o
- renderizar cada fórmula a SVG o PNG en el servidor y que TCPDF inserte la imagen.
6.2.b Tablas dentro de una pregunta
El botón de tabla abre un selector de tamaño por rejilla — se pasa el mouse y se elige 3 × 4, como en Word o Docs — con la opción de usar la primera fila como encabezado. Después se escribe directo en las celdas.
Sirve para lo que en matemática y ciencias aparece todo el tiempo: tablas de frecuencia, de valores x/y, de datos experimentales. Las tablas van dentro del enunciado, no como un objeto aparte: son parte de la pregunta y tienen que viajar con ella al banco de items.
Lo que falta y hay que definir: agregar y borrar filas o columnas después de creada, combinar celdas, y alineación por columna. La maqueta inserta la tabla y deja escribir, nada más. Si se usa CKEditor, esto viene resuelto.
6.2.c Gráficos interactivos: JSXGraph
Un bloque de gráfico dentro del enunciado, con dos formas de describirlo en el mismo campo:
- La forma corta, que es la que usa un profesor: la función
(
f(x)=-5x^2+30x), los puntos (A=(3,45)) y opcionalmente la ventana (ventana=(-1,7,-5,50)), una por línea. Cubre lo que pide una prueba de colegio sin obligar a programar. - Código JSXGraph, pegado tal cual desde los ejemplos de
jsxgraph.org, con suJXG.JSXGraph.initBoard(BOARDID, …). Así entran deslizadores, geometría dinámica y superficies 3D, que la forma corta no cubre y que la librería sí sabe hacer.
No hay que elegir el modo: se reconoce solo. La marca es la misma en todos los
ejemplos de la librería —JXG.JSXGraph.initBoard, o un
board.create(— y ninguna de esas cadenas puede aparecer en la forma
corta, que no lleva llamadas ni puntos. BOARDID es el hueco que la propia
documentación deja para el id del contenedor, así que el ejemplo se pega
sin tocar una letra.
Pegar un ejemplo de la documentación no fallaba: cada línea de código se descartaba en silencio por no calzar con ninguna de las tres formas cortas, el tablero salía vacío con sus ejes —que parece un gráfico legítimo— y las sesenta líneas de código quedaban impresas en la cabecera del bloque, encima del dibujo.
Dos arreglos, y el segundo vale para cualquier motor: el código se ejecuta, y cuando no se entiende nada se dice con todas sus letras en vez de dibujar una cuadrícula vacía. Un gráfico en blanco que parece correcto llega impreso a la sala; un mensaje de error, no. La cabecera, además, ahora es una referencia —«27 líneas»—, no el contenido.
Aceptar código significa que el enunciado de una pregunta guarda JavaScript del profesor y que alguien lo ejecuta. En la maqueta da igual: es código propio en el navegador propio. En el producto no, y hay que decidirlo antes de programarlo — una pregunta del banco la escribe un profesor y la rinde el alumno de otro colegio.
Las dos salidas razonables, y las dos sirven:
- Aislarlo en un
iframeconsandboxy sin acceso a la página ni a la sesión: el gráfico se dibuja adentro y lo peor que puede hacer el código es romper su propio recuadro. - Dibujarlo en el servidor y guardar el SVG resultante, que es lo que de todos modos hay que hacer para el PDF (ver abajo). El alumno recibe una imagen, no código. Pierde la interacción en línea, pero para la mayor parte de las preguntas no hace falta.
Mientras eso no se defina, lo prudente es que el modo código quede restringido a quien crea preguntas y no viaje al alumno.
GeoGebra es gratis sólo para uso no comercial, y su licencia dice
explícitamente que eso «depende del uso, no del usuario»: que el
colegio sea educativo no basta, porque el uso que hace WebClass es incorporarlo a
un producto que se vende. Su propio texto pide, para uso comercial, un
License and Collaboration Agreement escribiendo a
office@geogebra.org; y la cláusula de embedding exige
además que el licenciatario garantice que los usuarios finales le den un uso
no comercial.
Desmos tiene el mismo problema, aunque menos visible: su modelo son
«paid partnerships with publishers, assessment companies, educational
institutions and other commercial partners», y para usar su API remiten a
partnerships@desmos.com. No hay un precio público: es acuerdo
caso a caso.
JSXGraph (Universidad de Bayreuth) está doblemente licenciado bajo LGPL y MIT. Se puede usar dentro de un producto que se vende, sin pedir permiso, sin pagar y sin cláusulas sobre qué hace el usuario final.
| Licencia | Uso en un producto que se vende | Salida | |
|---|---|---|---|
| JSXGraph | LGPL + MIT | Libre | SVG o canvas |
| CindyJS | Apache 2.0 | Libre | canvas |
| GeoGebra | Propietaria | Requiere acuerdo | canvas (PNG por API) |
| Desmos | Propietaria | Requiere partnership | canvas |
Técnicamente JSXGraph también calza mejor: es una librería suelta sin dependencias (no un applet de terceros), corre entera en el navegador sin servidor, cubre geometría euclidiana, gráficos de funciones, estadística y 3D, y —lo que más importa acá— dibuja en SVG. Un SVG entra directo al PDF sin pasar por una captura de pantalla; un applet en canvas no.
Decidido con el negocio: JSXGraph, y GeoGebra queda fuera. La maqueta tenía un selector de motor con las dos opciones, por si algún día se conseguía el acuerdo; se quitó. Un desplegable que ofrece algo que no se puede usar invita a elegirlo, y después hay que explicar por qué no. Con un solo motor tampoco hay selector: la pantalla dice cuál es y bajo qué licencia, y punto.
Con GeoGebra se fue también el selector de tipo de applet
(gráficos, geometría, 3D, probabilidad), que era suyo, y la carga de
deployggb.js desde geogebra.org.
JSXGraph está probado con seis casos: parábola, recta, raíz,
trigonométrica, función con asíntota y función con punto
marcado. Más uno en modo código: la superficie 3D con deslizador y
plano tangente del propio sitio de la librería, pegada sin editar, sobre la
versión 1.13.3 —que trae view3d y
functiongraph3d, comprobado, no supuesto—.
- En papel no existe un gráfico interactivo. La misma pregunta tiene que dar interactivo en línea y una imagen estática en el PDF. Con JSXGraph la imagen es el propio SVG, que se puede guardar junto al bloque; hay que guardarlo al crear la pregunta, no generarlo al imprimir, porque el PDF se arma en el servidor y ahí no hay navegador dibujando.
- Encuadrar bien una función cualquiera es un problema de verdad.
Ajustar al mínimo y máximo muestreados deja una parábola
aplastada contra el eje; se probó recortar las colas por percentiles y
tampoco sirve, porque la distribución de valores está muy sesgada.
Por eso hay
ventana=(x₀,x₁,y₀,y₁): el autor la fija cuando le importa. Desmos y GeoGebra lo resuelven con heurísticas propias; no hay que intentar reinventarlas. - No sirve para evaluar, sólo para ilustrar — al menos en esta etapa. Que el estudiante responda manipulando el gráfico es otro producto: exige capturar su construcción y corregirla.
En la maqueta el bloque muestra una vista previa estática y un botón «Ver el gráfico real» que recién ahí carga la librería. Se hizo así a propósito: la maqueta tiene que abrir sin internet, que es como se muestra en una reunión.
6.3 Agregar preguntas — botón flotante, como en Google Forms
Un botón fijo a la ventana, abajo a la derecha, siempre visible. Al pulsarlo se despliega hacia arriba una paleta con los tipos de pregunta y los dos orígenes alternativos:
- Los siete tipos de pregunta de WebClass (§6.3.a)
- Texto compartido por varias preguntas (§6.4.b)
- Digitalizar desde un archivo —PDF o Word— (§6.3.c) · Recortar de un PDF o imagen (§6.3.b)
- Desde el banco de items · Con ayuda de la IA
La pregunta se agrega al final, la vista baja hasta ella y el cursor queda en el enunciado, listo para escribir.
6.3.a Los tipos de pregunta: los que WebClass ya guarda
No se inventó ninguno. La lista sale de leer el módulo
home/preguntas/CreaPreguntas del vanilla: el
if($tipo==N) de controlador/controladorPregunta.php y las
clases Objetos/Respuesta_*.php. pregunta.tipo es un entero
y estos son sus valores:
tipo | Qué es | Dónde vive la respuesta | En la maqueta |
|---|---|---|---|
| 1 | Verdadero / Falso | respuesta_vof | sí |
| 1 | V/F con justificación | respuesta_vof_justificacion — tiene justificacion y puntajeObtenido propios | sí, nuevo |
| 2 | Términos pareados | respuesta_enpareja_orden (texto, columna, orden) + respuesta_enpareja_vinculo (vinculo_a, vinculo_v, puntaje) | sí, nuevo |
| 3 | Desarrollo (ensayo) | respuesta_desarrollo | sí |
| 4 | Selección múltiple, una correcta | respuesta_alternativa (texto, puntaje, orden, retroalimentacion) | sí |
| 4 | Selección múltiple, varias correctas | La misma tabla, usando puntaje como porcentaje en vez de bandera | sí, nuevo |
| 5 | Respuesta corta | respuesta_corta (texto, puntaje, retroalimentacion) | sí, nuevo |
Los iconos del producto (truefalse.gif, match.gif,
essay.gif, multichoice.gif, shortAnswer.gif)
son los de Moodle, y existe un módulo giftEvaluation: la
numeración viene de ahí. Conviene tenerlo presente si alguna vez se
quiere importar o exportar en formato GIFT.
respuesta_alternativa tiene una columna puntaje por
alternativa. Lo que se ve en algunas partes del código es que se la lee como
bandera —if($res->getPuntaje()>0) → «Opción
correcta»—, pero el producto ya la escribe como porcentaje. Eso
cambia la conclusión y vale la pena verlo entero.
En el formulario de creación de preguntas, cada alternativa tiene su propio
campo de calificación —id_fraction_0…id_fraction_7,
o sea hasta ocho alternativas— que viaja como
calificacionRespuestaN y termina en
respuesta_alternativa.puntaje. Los nombres delatan el origen: es el
modelo de Moodle, y en el repo está además el importador de
GIFT.
La regla la impone el propio producto, en editarPreguntas.php:
var sumfrac = frac0 + frac1 + … + frac7;
if (sumfrac != 1) { alert('La calificación sugerida no es el 100%'); return; }
O sea: las fracciones tienen que sumar 1. Es exactamente lo que hace la maqueta —repartir 100% entre las correctas y no dejar guardar si no cuadra—, con una sola diferencia que hay que respetar al implementar: la base guarda 0,5, no 50. La maqueta muestra porcentajes porque es lo que el profesor entiende; al escribir hay que dividir por 100.
Lo mismo vale para respuesta_corta.puntaje —aceptar
«7» al 100% y «2 y 5» al 50%— y para
respuesta_enpareja_vinculo.puntaje, que habilita puntaje parcial por par
acertado. Ninguna tabla nueva.
Se guarda una fracción, sí. Pero al corregir, el producto la lee como
bandera. En DatosTestDao, para una pregunta de alternativas:
$puntaje = respuesta_alternativa.puntaje; // la fraccion
if ($puntaje > 0) { $puntaje = $puntajePregunta; } // ← el puntaje COMPLETO
else { $puntaje = 0; }
O sea: cualquier fracción mayor que cero da el puntaje entero de la pregunta. Una pregunta autorizada 50/50 le daría 100% al alumno que marcó sólo una. Y recibe una alternativa, no varias: hoy es selección única.
Consecuencia para el alcance. Este gadget crea preguntas y la aplicación sigue el camino actual de WebClass —decidido así—, pero entonces hay que decirlo sin rodeos: si se publica la autoría de varias correctas sin tocar el corrector, las notas salen mal y nadie se entera. Es peor que no tener la funcionalidad. Las dos salidas honestas son ajustar el corrector junto con esto, o no habilitar el tipo hasta que se ajuste.
valida_porcentaje() muestra la alerta y hace return, pero
retorna de sí misma, no del que la llama: quien la invoca
(validar_retroalimentacion) no mira lo que devuelve y el formulario
se envía igual.
Consecuencia práctica para este gadget: en producción puede haber preguntas cuyas fracciones no sumen 1. El generador no puede asumir que el dato viene limpio — al traer una pregunta del banco hay que mirar la suma y avisar, no confiar. Es el mismo criterio que ya se aplica a las alternativas repetidas (§8.a): lo que ya está mal no se corrige solo, se muestra.
Selección múltiple con varias correctas
- La letra alterna en vez de mover una marca única, y se dibuja cuadrada en lugar de redonda: es la señal de que se puede marcar más de una, antes de leer el enunciado.
- Cada alternativa correcta lleva su porcentaje del puntaje, editable, en la zona que no se imprime: en el papel el alumno no debe ver cuánto vale cada una.
- Marcar una nueva correcta reparte 100% en partes iguales. Es predecible; quien quiera 60/40 lo escribe después.
- Poner un porcentaje mayor que cero es marcarla correcta: el puntaje y la bandera son el mismo dato, igual que en la base.
- Si los porcentajes no suman 100% se avisa bajo la pregunta y no se deja guardar. Sumar menos hace la pregunta imposible de obtener completa; sumar más la hace valer más de lo que dice su puntaje. No se corrige solo: cambiarle la prueba al docente por detrás es peor que avisarle.
- En la pauta de corrección, estas preguntas rinden un grupo de letras
(
ACE), no una sola.
Términos pareados
- Se editan por pares, que es como se piensan: término y definición en la misma fila.
- La columna B se imprime revuelta, y el orden se guarda en la pregunta
(
respuesta_enpareja_orden.orden): si se re-revolviera en cada repintado, la pauta impresa dejaría de servir. - La columna A lleva un recuadro para escribir la letra, se numera sola y los pares se arrastran para reordenar.
- La clave (
1→B 2→D…) se calcula sola y no se imprime. Hay un botón para volver a revolver la columna B. - No se puede guardar con un par que tenga una columna vacía.
El señuelo sin pareja «+ distractor»
La columna B puede llevar opciones que no calzan con ningún término de la A. Sin ellas, el último par sale gratis: quien ya emparejó el resto acierta por descarte. Con un señuelo, cada fila hay que resolverla.
- Se agregan con el botón «+ distractor», al lado de
«+ par». Son una fila más de la columna B, sin fila en la A:
por eso la B queda más larga que la A y las letras siguen corridas
(
A…Fcon cuatro pares y dos señuelos). - Se revuelven junto con los pares, no se pegan al final. Un señuelo que siempre cae en la última letra se delata solo y deja de servir.
- En pantalla la fila se marca con el rótulo sin
pareja y trae su propia × para quitarla. En el papel no se marca
nada: ambos elementos llevan
no-imprimir, y el texto del señuelo se imprime como una opción más. - La clave de pantalla los lista aparte:
1→B 2→D 3→C 4→F · sin pareja: A, E. - El puntaje de la pregunta no cambia al agregar un señuelo: se sigue puntuando por par correcto. Un señuelo no suma ni resta por sí mismo; penaliza porque ocupa el lugar de una respuesta que no existe.
- Los pares siguen con un mínimo de dos. Los señuelos no tienen mínimo —son opcionales— pero ninguno puede quedar sin texto: en el papel saldría una letra en blanco. La validación dice «tiene un distractor sin texto».
Modelo de datos: ya existe, no hay que inventarlo. Un señuelo es una fila
de respuesta_enpareja_orden con columna = B y su
orden, cuyo vínculo en respuesta_enpareja_vinculo queda
con vinculo_a = -2. Es exactamente lo que el producto llama
«distractor» en editarPreguntas.php y
controladorPregunta.php. El control está comentado en varios
archivos: la tarea es descomentarlo y completarlo —y verificar que el
corrector no intente emparejar un -2—, no escribirlo de cero.
Ver la caja sobre la palabra «distractor»,
porque en la otra acepción sí se descartó.
Respuesta corta
- En el papel es una raya. Lo que el sistema necesita es la lista de respuestas aceptadas, y esa no se imprime.
- Cada respuesta aceptada lleva su porcentaje, que es
respuesta_corta.puntaje: así «7», «7,0» y «siete» valen 100% y «2 y 5» vale 50%. - No se puede guardar sin al menos una respuesta aceptada.
- Hay que definir la tolerancia de la comparación: mayúsculas, tildes, espacios y coma vs. punto decimal. Ver §11.
Desarrollo, con rúbrica para el profesor funcionalidad nueva
WebClass tiene rúbricas, pero son un recurso aparte: se arman en Evaluación › Rúbricas de aprendizaje y se aplican a trabajos o actividades. Lo que no existe es una rúbrica pegada a una pregunta de una prueba, que viaje con ella y salga en su pauta de corrección.
Eso es lo que este documento propone, y es el único punto del gadget donde hay que agregar algo al modelo de datos fuera de las tablas de tokens. Todo lo demás —la forma de la rúbrica, sus criterios, sus niveles de logro— se toma tal cual del producto, para no abrir un formato paralelo que después haya que reconciliar.
Decisión de negocio antes de programar: si esto se aprueba, hay que definir también si la rúbrica de una pregunta puede guardarse en el banco de Rúbricas de aprendizaje para reutilizarla, o si vive sólo dentro de la evaluación. Ver §11.
En el papel la pregunta es un bloque de líneas. Lo que se agrega es que nace acompañada de una rúbrica: es el único tipo que no se corrige solo, y sin pauta «6 puntos de desarrollo» los reparte cada profesor a ojo —con dos cursos paralelos, eso es una diferencia de nota que nadie puede explicar después.
El módulo Rúbricas de aprendizaje ya guarda rúbricas, y este gadget usa ese mismo modelo:
| En la maqueta | Tabla del producto | Campo |
|---|---|---|
| La rúbrica | rubrica | id_nivel, id_sector, autor |
| Un criterio (fila) | rubrica_criterio | titulo, orden, tipo |
| Un nivel de logro (columna) | concepto_valores | descripcion, conversion, color, simbolo |
| La celda (descriptor) | rubrica_criterio_detalle | titulo, id_rubrica_criterio, id_concepto_valores |
| Lo que se marca al corregir | rubrica_alumno_criterio / rubrica_alumno_eva | id_rub_crit_det |
El conversion de concepto_valores es el
«%» que se ve en la cabecera de cada columna: el porcentaje del puntaje
del criterio que se paga en ese nivel. No hubo que inventarlo.
Hoy rubrica cuelga de una evaluación
(id_concepto_evaluacion), de un nivel y de una asignatura. No tiene
forma de apuntar a una pregunta. Ese es el amarre que falta, y es todo lo que
falta.
Propuesta: una columna anulable en la tabla que ya existe.
ALTER TABLE rubrica ADD COLUMN id_pregunta INT NULL DEFAULT NULL;
-- NULL = rúbrica del banco, como hoy: se arma y se aplica aparte
-- id = rúbrica de esa pregunta, viaja con ella y sale en su pauta
Se prefiere la columna por sobre una tabla puente porque la relación es
uno a uno —una pregunta, una rúbrica— y porque así
las rúbricas de preguntas y las del banco siguen siendo la misma entidad:
el día que se quiera guardar una en el banco, basta con poner la columna en
NULL. Con una tabla puente habría que migrar filas.
- Hay que revisar las consultas del banco de rúbricas: los listados
de Rúbricas de aprendizaje tienen que filtrar
id_pregunta IS NULL, o al profesor le van a aparecer las rúbricas de cada pregunta de cada prueba mezcladas con las suyas. - Borrar una pregunta borra su rúbrica (y sus
rubrica_criterio/rubrica_criterio_detalle). Las del banco, no. - Vale la regla general del gadget: una prueba ya rendida no se edita, y la rúbrica es parte de eso —cambiarla después de corregir mueve las notas puestas—.
La rúbrica no se dibuja dentro de la hoja. La hoja es lo que se imprime, y meterle una tabla de corrección adentro rompe la única promesa del editor: lo que ves es lo que sale. Además empujaba las preguntas a la página siguiente y hacía que la vista dejara de mostrar la paginación real.
En cambio es una opción más del carril lateral de la pregunta, junto a Categorización y Retroalimentación, y sólo aparece en las preguntas de desarrollo. Al hacerle clic se abre un modal ancho con la tabla: en el cajón lateral no cabría, porque es una matriz de criterios por niveles.
- La marca lleva ✓ cuando la rúbrica está completa y cierra; si no suma, el carril muestra la etiqueta roja «rúbrica no suma» —el mismo tratamiento que «sin clave»— sin necesidad de apretar Guardar para enterarse.
- El carril se actualiza con el modal abierto: cambiar un puntaje adentro se refleja afuera en el momento.
- Los botones de + criterio, + nivel y Quitar rúbrica van en el pie del modal, no dentro de la tabla: la tabla ya es densa.
- Nace con tres niveles —Logrado 100%, Parcial 50%, No logrado 0%— y dos criterios con descriptores de ejemplo. Se agregan más con «+ nivel»; con cuatro o cinco, la tabla se desplaza sola dentro del modal.
- Un nivel nuevo entra antes del último, no al final: el último es «No logrado» y la escala tiene que seguir leyendo de mayor a menor.
- Cada criterio lleva su puntaje máximo, y cada celda muestra cuántos puntos vale (puntaje del criterio × % del nivel). Eso es lo que convierte la rúbrica en algo con lo que se pone una nota.
- La suma de los criterios tiene que ser el puntaje de la pregunta. Si no calza, se avisa en la cabecera y Guardar se bloquea diciendo cuánto suma —el mismo control que el de los porcentajes de las preguntas de varias correctas—. Tampoco se puede guardar con un criterio sin nombre ni con una celda sin descriptor: al corregir, la celda vacía aparece justo en el nivel que hay que decidir.
- La rúbrica se puede quitar. Queda en su lugar el aviso de que la pregunta se corrige a mano y el botón para volver a ponerla.
Como la rúbrica no vive en la hoja, para la pauta hay que bajarla al papel a propósito. Al Descargar:
- Para el estudiante → la hoja sale tal cual se ve en el editor, sin rúbrica.
- Pauta de corrección → el sistema inserta bajo cada pregunta de desarrollo una versión impresa de su rúbrica: una tabla, sin un solo campo ni botón. Hasta ahora la pauta no decía nada de las preguntas de desarrollo. Terminada la impresión la hoja vuelve a quedar limpia.
Detalle de implementación que importa: no alcanza con la bandera de «mostrar correctas». En el editor esa bandera está puesta casi siempre —para que el profesor vea la clave mientras arma—, así que colgarse de ella haría reaparecer la rúbrica sobre la hoja, que es justo lo que se sacó. Hace falta una bandera aparte, activa sólo mientras se genera la pauta.
Las decisiones que esta funcionalidad deja abiertas están juntas en §11, encabezando la lista.
V/F con justificación
Es el tipo 1 más un bloque de líneas rotulado
«Justifica tu respuesta». La justificación
se corrige a mano y tiene su propio puntaje: la tabla
respuesta_vof_justificacion ya trae justificacion y
puntajeObtenido por separado.
- Tiene que ser flotante, no ir al final del documento. Con la prueba paginada, el final puede estar a varias pantallas de distancia: obligar a bajar para agregar una pregunta y volver a subir es el tipo de fricción que hace que la gente no use la herramienta.
- Todo el botón es clickeable, no sólo el círculo del +. Un rótulo al lado que no responde al clic se lee como un fallo.
- Se esconde cuando hay un cajón o un modal abierto, y en las pestañas que no son Contenido, donde no tendría sentido.
6.3.b Recortar de un PDF o imagen — una pregunta por recorte
El profesor sube el PDF o la foto de una prueba anterior, ve el documento en pantalla y arrastra un rectángulo sobre cada pregunta. Cada recorte entra como una pregunta, en texto editable: el enunciado queda escrito, las alternativas se separan solas y las tablas se rehacen como tabla.
Esto antes entraba como imagen, y la razón era el OCR: se midió con
Tesseract.js y las alternativas salían 3mx8m,
mxgm, smx8m — se comía el signo × y
confundía dígitos con letras. Una alternativa mal transcrita es peor que
ninguna: se imprime con el error y nadie lo nota hasta que el curso la está
respondiendo.
Pero un PDF nacido digital no se lee con OCR. Trae la capa de texto con coordenadas, y recortar es filtrar por rectángulo: lo que sale es exacto, no adivinado. Es la misma técnica del §6.3.c, acotada a lo que el profesor encuadró.
Si el recorte no tiene texto por debajo —un escaneo, una foto—, la pantalla lo dice en la lista, y ofrece reconocerlo. Ver más abajo.
Recortar de una imagen: reconocer el texto
Este era el caso que quedaba afuera, y es el más común en un colegio: la prueba del año pasado está fotocopiada, o el profesor le saca una foto con el celular. Sin capa de texto, el recorte entero entraba como imagen, con las alternativas en blanco para llenar a mano — es decir, no se ahorraba nada.
- Los recortes sin texto se cuentan y se muestran juntos, con el botón «Reconocer el texto (OCR)». Se reconoce lo que el profesor encuadró, no la página entera.
- No consume tokens. Ver la caja de abajo: el OCR no es una llamada a un proveedor de IA.
- Lo reconocido pasa por el mismo camino que la capa de texto de un PDF: se separan las alternativas, se detecta el tipo de pregunta, y queda texto editable.
- Entra marcado como borrador. Un error del OCR que nadie revisa viaja hasta la sala.
- Se conserva el recorte original junto a la pregunta
(
origenRecorte.imagen): es lo único que permite comprobar después si la transcripción decía lo mismo que el papel.
Los tokens existen por una razón concreta: las herramientas de IA llaman a un proveedor externo que cobra por uso, y la bolsa es lo que le pone techo a esa cuenta. El OCR no es eso. El reconocimiento de texto se hace con Tesseract, que es open source, y corre en dos lugares posibles, ninguno de los cuales cobra por página:
- En el navegador del profesor (
tesseract.js), servido desde los propios assets de WebClass —no desde un CDN—. Costo por uso: cero. Costo real: una descarga inicial de la librería y del idioma español, que queda en caché, y unos segundos de CPU del computador del profesor. Las imágenes no salen de su máquina, que para pruebas de un colegio no es un detalle menor. - En el servidor de WebClass, con el binario de Tesseract. Tampoco cobra por página; cuesta CPU del servidor y permite preprocesar la imagen —enderezar, subir contraste—, que es lo que más mejora el resultado.
Cobrarlo con tokens habría sido cobrar dos veces por algo que no cuesta, y peor: habría puesto un peaje justo en el camino del profesor que llega con la prueba fotocopiada, que es el que más ayuda necesita.
En la maqueta el reconocimiento está simulado. No se puede hacer de verdad ahí: haría falta una librería de varios MB por CDN —que las convenciones de estas maquetas no permiten— o un servicio en el servidor, que es como va en el producto. Lo que sí es real, y es lo que hay que discutir, es el flujo: el costo por recorte, la espera, y que todo lo reconocido entra marcado para revisar.
Y la advertencia de siempre, que sigue en pie: se midió con Tesseract.js y
las alternativas salían 3mx8m, mxgm,
smx8m. Con fórmulas el OCR es malo, y una alternativa mal
transcrita que nadie revisa es peor que ninguna. Por eso el borrador obligatorio y el
recorte original guardado al lado: el OCR no reemplaza al profesor, le ahorra el
tecleo.
Falta definir: si se sirve en el navegador o en el servidor. En el navegador el colegio no paga nada y las imágenes no salen del computador; en el servidor la calidad se puede mejorar con preprocesado, a cambio de CPU. Ninguna de las dos usa tokens.
Una tabla llegaba aplanada como párrafo, con las celdas de las tres columnas intercaladas en orden de lectura («Menú 1 Menú 2 Menú 3 • Fideos con carne y • Ensalada de…»), y encima aparecían recuadros vacíos montados sobre el texto. Eran dos problemas distintos que se manifestaban en el mismo lugar:
- La detección exigía que todas las líneas tuvieran el mismo
número de celdas. Una tabla real no cumple eso: cuando el texto de una
celda no cabe en una línea, la de abajo trae una o dos celdas, no tres. Con la
primera línea corta se cortaba el bloque, no llegaba al mínimo de tres
filas, y la tabla entera caía al camino de «texto suelto».
Ahora las columnas se fijan con la primera línea y cada línea se reparte en ellas; una con menos celdas deja columnas vacías en vez de romper la tabla. Y una línea cuyo texto arranca indentado respecto del inicio de su columna se une a la celda de arriba: es la seña que da el propio PDF, no una suposición sobre viñetas. - Las rayas de la tabla se importaban como una figura. El detector de figuras
busca bandas con tinta y sin texto, y las líneas horizontales de una
tabla son exactamente eso. Entraban como imagen: un recuadro vacío con los
bordes, encima del texto.
Ahora las tablas se detectan primero y sus franjas se excluyen del barrido de figuras.
Para el desarrollador: el orden importa. Detectar tablas antes que figuras no es una preferencia de estilo; sin eso, toda tabla con bordes aporta una figura fantasma.
Las fórmulas se traen como LaTeX, y se pueden editar
Un PDF nacido digital no guarda «√12»: guarda un
√ y un 12 con sus coordenadas, y la raya de la raíz
es un trazo vectorial aparte. Lo mismo con un exponente —el 7 de 2⁷ es un
trozo más chico y más arriba— y con una fracción, que son dos
trozos apilados. Aplanar eso a texto daba 2 7 3 y la pregunta quedaba sin
sentido.
Ahora esas señas —alto del trozo, desplazamiento respecto de la línea
base, apilamiento— se leen y se reconstruye el LaTeX. La fórmula entra
como el mismo <span class="formula" data-latex="…"> que
produce el editor, así que se abre y se corrige como cualquier otra.
| En el PDF | Entra como |
|---|---|
| √12 | \sqrt{12} |
| 6√5 | 6\sqrt{5} |
| ∛2⁷ — raíz con índice | \sqrt[3]{2^{7}}, con el exponente dentro |
| 2⁷ | 2^{7} |
| 2 elevado a 7/3 (fracción apilada) | 2^{\frac{7}{3}} |
| x₁ | x_{1} |
| Una fracción apilada — 3 sobre 8 | \frac{3}{8} |
| ≤ ≥ ≠ ± × ÷ π Δ ∞… | Su comando LaTeX |
- Sólo se convierte lo que tiene una seña matemática. La prosa queda como prosa: una frase no se vuelve fórmula por tener un número. «Un rectángulo mide 3 metros más que su altura» entra como texto.
- El cuerpo de la línea es el trozo MÁS ALTO, no la mediana ni el
más ancho. Un exponente es siempre más chico que el cuerpo, nunca
más grande, así que el máximo no se confunde. Con la mediana o con
el peso por ancho, una línea corta como
2^{7/3}—un trozo de cuerpo y dos chicos— elegía el tamaño del exponente como «lo normal», y entonces no se detectaba ninguna seña. - Ser chico no basta para ser exponente: hay que estar desplazado de la línea base. El texto del cuerpo nunca lo está.
El texto viaja con un marcador en lugar de la fórmula hasta el último paso, para que todo lo que ya existía —partir alternativas, detectar tablas, buscar el número de la pregunta— siga trabajando sobre texto plano. El marcador se cambia por el HTML recién al escapar.
Límites, y hay que decirlos: la capa de texto no trae la raya de la raíz ni la de la fracción —son trazos vectoriales—, así que el alcance del radicando se deduce de que lo que va debajo de la raya va sin separación. Funciona para lo que aparece en una prueba de colegio; una integral, una matriz o una fracción de varios niveles no van a salir bien. El profesor las corrige en el editor de fórmulas, que es donde ya están.
Una fracción escrita como numerador sobre denominador son dos trozos de
texto con una raya vectorial al medio que la capa de texto no trae. Como los dos
caen dentro de la tolerancia con que se arman las líneas, terminaban ambos en la
misma línea; y al ordenarlos por x se intercalaban con los de las
fracciones vecinas. De ahí salía
3 6 8 3 … 8 16 3 11: los numeradores y denominadores de cuatro
fracciones, barajados, y la pregunta ilegíble.
Las fracciones se unen ANTES de armar las líneas, en un solo trozo que ya trae su LaTeX. De ahí en adelante el importador ve una fracción donde hay una fracción.
Lo que distingue una fracción de dos líneas de un párrafo es que están centradas una sobre otra. Dos líneas de texto comparten el margen izquierdo pero no el centro; el numerador y el denominador sí. Sin esa condición, cualquier párrafo de dos líneas cortas se convertiría en una fracción.
Hay un tercer caso, distinto del PDF digital y del escaneo: el documento trae capa de
texto pero no dice qué letra es cada símbolo. Pasa cuando la fuente
matemática viene incrustada sin su tabla ToUnicode, que es lo
habitual en pruebas exportadas desde un editor de ecuaciones. Lo que se extrae son
caracteres del área de uso privado, que en pantalla se ven como cuadraditos:
□3 6 □ 8 3.
Es traicionero porque el importador no lo distingue de un PDF sano: hay texto, así que lo transcribe. Ahora se mide la proporción de caracteres sin significado y, si pasa del 12%, se declara la capa ilegible y se ofrece reconocer el texto —que no cuesta tokens— o dejarlo como imagen. Transcribir cuadraditos en silencio es peor que no transcribir.
Para el producto: el umbral es una decisión que conviene revisar con PDFs reales del colegio. No es cero para tolerar una viñeta o un símbolo suelto que el visor no supo mapear.
El recortador ocupa el 90% de la pantalla, con zoom
El documento es el trabajo, no un detalle del formulario. En un notebook de 13″ la página entraba tan chica que el texto no se leía, y encuadrar «la pregunta completa» a ojo era imposible.
- El modal ocupa 90% de ancho y de alto, en dos columnas: el documento a la izquierda con todo el alto disponible, la lista de recortes a la derecha. Bajo 900 px la lista pasa abajo.
- Un selector de zoom: Ajustar al ancho y de 50% a 200%. El 100% es el tamaño natural de la página, no el del contenedor —si no, «100%» significaría cosas distintas según el ancho de la ventana y el selector dejaría de querer decir algo—.
- Detalle de implementación: el zoom cambia el ancho del
<img>, no untransform. Las coordenadas del recorte se calculan desde el rectángulo del propio<img>, así que al reflotar el layout siguen saliendo bien solas en cualquier zoom. Contransformhabría que corregirlas a mano en cada cálculo.
Un recorte, una pregunta
Antes todos los recortes se sumaban a una sola pregunta, para el caso de una pregunta partida entre dos columnas. Estaba mal calibrado: lo habitual es encuadrar varias preguntas seguidas, y recibirlas todas pegadas obliga a deshacer a mano lo que el sistema juntó. Ahora cada recorte es una pregunta; una partida en dos se arregla con un recorte que abarque las dos partes, o pegando el texto después —que ahora se puede, porque es texto—.
Qué se reconoce dentro del recorte
| En el documento | Entra como |
|---|---|
El número de la pregunta — 1., 2), o dentro de un círculo, o solo en su línea | Se descarta: la numeración la pone la hoja. |
| El enunciado | Texto editable. |
A) B) C)… — una por línea, varias en la misma línea, o en dos columnas | Alternativas separadas, en orden A–D, sin clave marcada. Ver abajo. |
| Verdadero / Falso | La pregunta nace de tipo V/F. |
| Sin alternativas | La pregunta nace de tipo desarrollo. |
| Una tabla, aunque sus celdas ocupen varias líneas | Tabla editable (<table>), no una foto. Ver abajo. |
| Una figura (banda con tinta y sin texto) | Imagen, en su lugar dentro del enunciado — antes, entre o después de las líneas. |
| Un dibujo con rótulos adentro: un plano, una cuadrícula de coordenadas, un diagrama con etiquetas | Una sola imagen, con sus rótulos dentro. Ver abajo. |
| Las rayas de una tabla | Nada: se saltan. Son tinta sin texto, pero no son una figura. |
| Una fórmula: raíces, exponentes, subíndices, fracciones | LaTeX reeditable (<span class="formula" data-latex="…">), no texto aplanado. Ver abajo. |
Leer «una alternativa por línea» parece lo natural y está mal. Cuando las opciones son cortas —y en matemática casi siempre lo son— las pruebas las aprietan:
- Las cuatro en la misma fila:
A) 2 B) 4 C) 6 D) 8 - Dos por fila, en dos renglones.
- En dos columnas:
A)yC)a la izquierda,B)yD)a la derecha. Como el texto se agrupa por línea, lo que llega es «A… C…» y después «B… D…»: hay que reordenarlas por letra. - El separador puede venir pegado:
A.2sin espacio.
Con la lectura por línea, los cuatro casos daban lo mismo: una sola alternativa con las cuatro opciones adentro. La pregunta quedaba inservible y había que escribirla de nuevo, que es exactamente lo que el importador venía a evitar.
Dos reglas evitan inventar alternativas donde hay prosa: la línea tiene que empezar con una marca, y la primera alternativa de la pregunta tiene que ser la A. Así, «El vértice A. Se ubica…» o «según la figura, a) y b) son paralelas» siguen siendo enunciado. Y una letra ya usada no abre alternativa nueva: es continuación de la anterior.
El reordenado por letra sólo se aplica si están todas, de la A hasta la última sin saltos. Si falta una, se deja como venía: ordenar a medias escondería el error en vez de mostrarlo.
Esto vale igual para el recorte y para el PDF completo. Conviene que sea una sola función usada por los dos caminos: estuvo duplicada y las dos copias tenían el mismo defecto.
Las tablas se reconocen por alineación, no por los bordes dibujados: hay tablas sin bordes y hay rayas que no son tablas. Se acepta como tabla una seguidilla de tres o más líneas que se parten en el mismo número de celdas y en las mismas posiciones; con dos filas podría ser cualquier cosa.
Un plano con «Museo», «Biblioteca» y «Plaza» en sus celdas; una cuadrícula de coordenadas con sus letras y números en los bordes; un diagrama rotulado. Son el mismo caso: el dibujo lleva palabras adentro, y esas palabras sin el dibujo no dicen nada. «Museo / Biblioteca / Plaza / Escuela», una por línea, no es una pregunta.
El barrido de figuras de arriba sólo mira las bandas que el texto no ocupa, así que un dibujo cuyas filas llevan rótulos le resulta invisible: las rayas se pierden y los rótulos salen sueltos, como si fueran prosa. La pregunta queda inservible, que es exactamente lo que el importador venía a evitar.
La seña es la tinta que el texto no explica. Se rasteriza el recorte, se tapan los rectángulos de cada item de la capa de texto, y se mira lo que sobra: las rayas, los ejes, los bordes de las celdas. Donde eso se acumula a lo largo de varias franjas seguidas hay un dibujo, y las líneas que caen ahí adentro son sus rótulos: entran dentro de la imagen, no como texto aparte.
Tres reglas evitan convertir en foto lo que sí es texto:
- Varias franjas seguidas. Un subrayado o la raya para responder marcan una; un dibujo marca todas las suyas, porque sus verticales lo cruzan de arriba abajo.
- Prosa enmarcada no es dibujo. Un recuadro con un párrafo adentro también tiene tinta en todas sus franjas —sus dos bordes verticales—. La diferencia es cuánto texto hay: los rótulos de un plano son de una o dos palabras, un párrafo trae seis o más por línea. Si no se distinguiera, un texto recuadrado entraría como foto y dejaría de ser editable.
- Una tabla ya reconocida se respeta. Entra editable; convertirla en foto sería perderla.
Ninguna heurística sobre un PDF rasterizado va a acertar siempre. Un plano rotulado, un gráfico con sus ejes y una tabla con bordes se parecen mucho entre sí mirando píxeles.
Por eso cada recorte trae, en el panel de revisión, un par de botones: «Como texto» o «Como imagen». El que dibujó el recuadro ya sabe qué encerró; lo único que faltaba era dónde decirlo. Y va en el panel de revisión, no en un menú aparte, porque la decisión se toma mirando el recorte y tiene que poder cambiarse antes de importar, no después de tener quince preguntas rotas en la hoja.
Marcado como imagen, el recorte entra como una sola figura con las alternativas en blanco para marcar la clave, igual que un escaneo sin capa de texto. Y la oferta de OCR no aparece para ese recorte: el profesor no pidió reconocer nada, pidió una imagen.
Las figuras se buscan por bandas: se toman las franjas horizontales del recorte que ninguna línea de texto ocupa y se mira si tienen tinta. Hay que mirar las tres clases de banda —antes de la primera línea, entre dos líneas y después de la última—: el caso más común es la figura bajo el enunciado, y mirar sólo los huecos intermedios lo dejaba fuera.
La imagen se recorta al ancho del recorte, no al del texto —una figura suele ser más ancha que las líneas— y después se le quita el aire blanco ajustando al contorno de la tinta. Sin eso la figura entra rodeada de página en blanco y se ve como un error.
Una banda que no llega al 0,4% de tinta se descarta: es espacio entre párrafos, no un dibujo. Y un recorte que trae sólo una figura, sin texto, entra igual — como pregunta de desarrollo con la imagen dentro.
El panel de la derecha muestra, por cada recorte, qué se reconoció —tipo, cuántas alternativas, si trae tabla o figura— antes de importar nada. Es la única forma de darse cuenta de que algo salió mal antes de tener quince preguntas rotas en la hoja.
El documento trae la prueba, no la pauta: ninguna pregunta importada llega con la respuesta correcta marcada, y Guardar se bloquea hasta que estén todas (§8.b).
- El PDF hay que rasterizarlo para poder recortar encima, y además
hay que leer su capa de texto. Las dos cosas las hace
pdf.js(Mozilla, Apache 2.0 — sin problema de licencia), que es lo que usa la maqueta: el archivo no sale del computador hasta que el profesor decide crear las preguntas. Son ~320 KB de librería más 1 MB de worker, que conviene cargar sólo al abrir este cargador y no en cada pantalla. En el servidor están Imagick y Ghostscript —los que generan los PDF hoy— para el escaneo pesado. - Hay que guardar las coordenadas, no sólo el resultado. Por cada recorte: archivo de origen, número de página y el rectángulo. Así se puede volver a interpretar el mismo recorte cuando el reconocimiento mejore, sin pedirle al profesor que recorte de nuevo.
- La deteccion de tablas necesita datos reales. El umbral de la maqueta —tres filas, columnas alineadas dentro de 40 pt— se calibró con un PDF de ejemplo. Antes de soltarlo hay que pasarle pruebas de verdad del colegio y ajustar; una tabla mal reconocida es peor que ninguna.
- Los recortes cruzan páginas. Se navega por el PDF y se sigue recortando. En pantalla, cada marco se dibuja sólo sobre su página; la lista lateral los muestra todos, numerados y con su página.
- No cuesta tokens. Leer la capa de texto es aritmética, no IA: no hay llamada a ningún proveedor y no hay nada que cobrar. Sólo costaría si alguna vez se agrega el modelo de visión para los escaneos (§7).
Fuera de alcance por ahora: detectar solo dónde empieza y termina cada pregunta, enderezar un escaneo torcido, y separar columnas automáticamente. Si el escaneo viene muy inclinado, conviene avisarlo antes de que el profesor pierda el tiempo recortando.
6.3.c Digitalizar desde un archivo completo — sin recortar nada a mano
La diferencia con §6.3.b no es de grado: allá el profesor encuadra cada pregunta y lo encuadrado entra como imagen. Acá se lee el archivo entero y se separan solas las preguntas y sus alternativas. Acepta PDF y Word, y en el PDF aprovecha que un PDF nacido digital trae capa de texto con coordenadas. No es OCR y no adivina: pdf.js entrega cada trozo con su x, su y y su tamaño, y eso es información exacta.
Hay dos decisiones que no se pueden tomar página por página, y tomarlas mal arruina todo lo demás:
- Cuál es el pie que se repite. «Matemática 4° básico | 7» aparece en las once páginas y terminaba pegado al final de la última alternativa de cada una. No se reconoce por su texto —cada prueba tiene el suyo— sino por lo que es: la misma línea, en la misma banda del borde, en la mayoría de las páginas. La firma ignora los dígitos, porque el número de página cambia y el resto no.
- Cuál de las listas numeradas es la de preguntas. Ver abajo.
Recién en la segunda fase se rasterizan las páginas para recortar las figuras, que es la parte cara.
Una prueba trae otras listas numeradas. Las instrucciones de la portada —«1. Lee atentamente cada pregunta», «2. Marca solo una alternativa»— son cinco líneas que empiezan con número, y el importador las tomaba por las cinco primeras preguntas.
El daño no era una pregunta de más: la serie quedaba enganchada en el 5, y las preguntas 1 a 5 de verdad, que empiezan de nuevo en la página siguiente, ya no calzaban con la secuencia y se perdían.
Se eligen las aperturas que forman la mejor cadena creciente del documento completo, y lo que rompe el empate es tener alternativas debajo: una lista de instrucciones no las tiene, una pregunta sí. Así la cadena de las instrucciones —cinco, sin alternativas— pierde contra la de las cuarenta preguntas.
Una fracción no es un trozo: son dos, uno sobre otro, con una raya vectorial al medio que la capa de texto no trae. Unirlos es necesario —si no, los numeradores y denominadores salen barajados— pero unir de más es peor: dos celdas de una tabla y dos alternativas consecutivas también están una sobre otra y perfectamente centradas.
La separación vertical no los distingue. Medido sobre una prueba real:
| Caso | Separación / alto de letra |
|---|---|
| Fracción de verdad | 1,25 |
Alternativas A) y B) | 1,33 |
| Dos filas de una tabla | 1,48 |
Con cualquier umbral que deje pasar la primera pasan las otras dos. Lo que sí distingue es que una fracción vive DENTRO de una línea de texto: su raya queda a la altura de la base del renglón, así que hay otro trozo —«A)», «Camila comió», «<»— cuya y cae justo entre el numerador y el denominador. Entre dos filas de una tabla, o entre dos alternativas, no hay nada: hay papel.
Sin esto, una tabla de «Entrada / Salida» entraba como
12⁄18, 9⁄15, y las cuatro alternativas como dos
fracciones. En la prueba de ejemplo, el reconocimiento pasó de 12
preguntas rotas a 40 correctas.
- La letra de la alternativa. Cuando el PDF entrega la línea entera en un solo trozo —«A) 56 ÷ 0 = 56»—, el signo de división hacía que la fórmula se llevara también la «A)»: la línea dejaba de parecer una alternativa y las cuatro terminaban pegadas dentro del enunciado. El prefijo se separa antes de buscar fórmulas.
- La prosa que sigue. El ancho de una fracción apilada es el del numerador —seis puntos—, no el del cajón que ocupa en el papel, así que lo que viene después parece pegado y la fórmula se llevaba media frase: «Camila comió 3/8 de una torta y su hermano comió» entero como si fuera una ecuación. Una palabra de tres letras o más seguida de un espacio es prosa, y no entra en una fórmula por pegada que venga.
Hay pruebas —muchas— donde cada ejercicio se pegó en Word como captura de pantalla. De esas preguntas el PDF trae, en su capa de texto, exactamente un item: el número. El enunciado, la figura y las alternativas son un dibujo.
Medido sobre una prueba real de IV° Medio: de 32 preguntas, 5 tienen texto y 27 son imágenes. Ningún lector puede extraer texto que no fue escrito como texto — copiar y pegar desde Acrobat da exactamente lo mismo. No es un defecto del importador: es el archivo.
Lo que sí era un defecto es cómo se comportaba. Las daba por reconocidas y entraban vacías, sin enunciado y sin alternativas: el profesor importaba 27 cáscaras y lo descubría después. Ahora:
- Se dicen en el resumen, separadas de las que sí traen texto: «32 encontradas · 5 con su texto · 27 pegadas como imagen». Y se explica por qué, para que no parezca una falla del lector.
- Entran como imagen, con la clave A–E para marcar a mano, igual que un recorte de un escaneo. La prueba queda completa y utilizable aunque su texto no sea editable ni se pueda buscar.
- Se ofrece reconocer el texto (OCR) en este mismo camino. Antes sólo existía en el recortador, que es donde menos falta hace: acá hay una imagen por pregunta, que es justo lo que el reconocimiento necesita. No consume tokens, lo reconocido entra como borrador, y la imagen original se conserva —es lo único que permite comprobar después si la transcripción decía lo mismo—.
Un cuidado que esto obligó a tomar: el detector de pies repetidos (arriba)
no puede tocar una apertura de pregunta. La firma de «6)» es #)
—los dígitos se ignoran a propósito— igual que la de todas las
demás, así que sin esa salvedad se comía los números de
pregunta que caen cerca del borde inferior, y esas preguntas desaparecían del
resultado. En la prueba de ejemplo eran 7 de 32.
También desde Word funcionalidad nueva
La mitad de las pruebas de un colegio están en .docx, no en PDF: el
PDF es lo que se imprime, el Word es el original que el profesor guarda. Pedirle que
exporte a PDF para poder importarlo es pedirle un paso que no entiende para qué
sirve.
Lo que cambia es sólo el lector. El reconocimiento —qué línea abre una pregunta, cuál es una alternativa, cuál es el pie que se repite, cuál de las listas numeradas es la de preguntas— es el mismo código para los dos formatos. El lector de Word produce las mismas líneas que produce pdf.js y de ahí en adelante el camino es idéntico, incluida la pantalla de revisión.
- Las imágenes salen mejor que del PDF. En un PDF hay que ir a
buscarlas recortando el lienzo rasterizado; en un
.docxvienen como archivo dentro del paquete, con su posición. Se extraen enteras y se ponen en la pregunta que las contiene. - Las tablas entran como una línea por fila, con las celdas seguidas. El contenido no se pierde, pero la tabla hay que rehacerla con el botón de tabla del editor. Se dice en el resumen, no se deja descubrir mirando el resultado.
- El
.docviejo no se puede leer —el binario de Word 97 no es un paquete—, y se dice qué hacer: «Guardar como .docx». Un «formato no soportado» deja al profesor sin saber si tiene arreglo. - Si el Word no trae texto —la prueba está dentro de una imagen pegada o de un cuadro de texto— no se ofrece OCR, que es para escaneos: se manda a recortar a mano.
.docx se lee sin librería
Un .docx es un ZIP con XML adentro, y el navegador ya sabe hacer las
dos cosas que hacen falta: DecompressionStream('deflate-raw') infla y
DOMParser parsea. Lo único que hay que escribir es la lectura del
directorio central del ZIP, que son cuatro desplazamientos fijos. En la maqueta
se hizo así por su regla —abre sin internet—, y en el producto
también conviene: una dependencia menos que mantener en el
webpack.mix.js de un Laravel 5.7.
La trampa que cuesta encontrar: el largo del nombre y del extra del encabezado local de cada archivo no coinciden con los del central —Word escribe cosas distintas en cada uno—, así que el comienzo de los datos hay que calcularlo con los del local. Leerlo del central da bytes corridos y un XML que no parsea.
La prueba word.js corre contra un .docx escrito por Word
de verdad, no contra un ZIP armado a mano: con texto, tabla e imagen. Un archivo
sintético no habría mostrado esa trampa.
Cuando las alternativas son dibujos
«¿Cuál de los cuerpos geométricos tiene 6 caras cuadradas?», con cuatro figuras rotuladas A) B) C) D) debajo. Entraban como desarrollo con una sola imagen: el alumno ve las cuatro opciones en el papel, pero el sistema no sabe que son cuatro y no hay dónde marcar la clave, así que la pregunta no se podía corregir. En el ensayo de ejemplo son 2 de 40; en pruebas de Geometría de básica son bastantes más.
Las letras no sirven de guía: se midió la capa de texto de esa página y los rótulos A) B) C) D) no están ahí —son parte del dibujo—. Lo único que trae el PDF es el enunciado y la línea «Marca la letra de la imagen elegida». Lo que sí se puede leer es la imagen: las figuras están separadas por blancos verticales, que es como se dibujaron.
El importador recorre la banda de la figura columna por columna, marca cuáles tienen tinta y corta donde hay un blanco ancho. Si salen entre 3 y 6 grupos, son las alternativas: cada uno se recorta en su propia imagen, se les asignan las letras en orden y la pregunta entra como selección múltiple, con su clave por marcar como cualquier otra. Se avisa en la lista previa: «sus alternativas son dibujos: entran como imágenes».
- El ancho de cada dibujo NO decide. La primera versión exigía que los cuatro midieran parecido —máximo el triple del más angosto— y descartaba una pregunta legítima: en «¿qué dibujo muestra su vista de frente?» las cuatro vistas miden 122, 150, 82 y 44 px. Una vista de frente puede ser una columna y la de al lado, tres. Lo que sí distingue una figura partida en pedazos de un juego de alternativas es que en la figura partida un trozo se lleva casi todo: se exige que ningún grupo pase de la mitad del ancho ocupado.
- Los blancos tienen que ser blancos de verdad, no el mínimo justo con que se cortó: se piden 1,5 veces el umbral. Dentro de un mismo dibujo los huecos lo rozan; entre dos dibujos lo superan con holgura.
- El rótulo dibujado se recorta. Si no, la alternativa dice «A)» dos veces: la letra que pone la hoja y la que trae la imagen. El rótulo es una banda de tinta corta y aislada arriba del dibujo —medido: 25 px contra los 81 del cuerpo geométrico—, así que se toma desde la primera banda alta. De paso el recorte se aprieta contra la tinta: sin eso las cuatro imágenes heredaban el alto de la más alta y la pregunta se comía media hoja.
Con esto el ensayo de ejemplo entra completo: 40 de 40 preguntas con sus 4 alternativas, dos de ellas como imágenes.
En el producto, cada recorte es un archivo más: son cuatro por pregunta y
van en respuesta_alternativa como URL, con la misma regla que las
imágenes del enunciado —§6.2, «Dos formas de poner
una imagen»—. En
la maqueta van como data: porque no hay servidor.
6.4 Arrastrar y soltar
- Preguntas: se toman de un asa que aparece al pasar el mouse y se sueltan en otra posición, incluso en otra hoja. La numeración se rehace sola y la prueba se vuelve a paginar.
- Alternativas: lo mismo dentro de su pregunta; las letras A/B/C/D se reasignan según la posición nueva.
- El orden se persiste en
prueba_preguntas(y el de alternativas en su tablarespuesta_*) con un solo POST al soltar, no uno por elemento.
- El arrastre debe ir por un asa, no por el cuerpo de la pregunta: el
enunciado es
contenteditabley arrastrar texto dentro de un elemento arrastrable pelea con la selección del navegador. - Conviene eventos de puntero y no la API nativa de drag and drop de HTML5, por lo mismo y porque la nativa no funciona con el dedo en tablet.
- Con el editor paginado, cada hoja es un contenedor distinto: el arrastre tiene que aceptar soltar en cualquiera de ellas y recomponer el orden global concatenando las hojas. Si se implementa por contenedor, no se puede mover una pregunta de la hoja 2 a la hoja 1.
6.4.b Un recurso compartido por varias preguntas funcionalidad nueva
«Lee el siguiente texto y responde las preguntas 11 a 14». El texto —o la imagen, o la tabla de datos, o el gráfico— se escribe una sola vez y vale para todas ellas. Es la forma de casi todo ensayo SIMCE y PAES, y de cualquier prueba de comprensión lectora.
Hoy la única manera es copiar el texto dentro de cada enunciado. Eso falla de tres formas, y la tercera es la grave:
- Ocupa la hoja cuatro veces. Un texto de media página repetido en cuatro preguntas es una prueba de tres hojas que debería ser de una.
- Se corrige en un lugar y queda mal en los otros tres. Una errata detectada el día antes de imprimir hay que arreglarla cuatro veces, y basta olvidar una.
- Se rompe al barajar. Al asignar la prueba a un curso, WebClass puede repartir las preguntas en orden distinto para cada alumno. Si el texto vive dentro del enunciado de la pregunta 11, al alumno que la recibe de última le llega el texto al final y las preguntas 12, 13 y 14 antes, apuntando a un texto que todavía no leyó. La prueba deja de tener sentido y nadie se entera hasta que la rinde.
Estas preguntas pasan a ser una unidad. El bloque entero se puede mover a cualquier posición de la prueba, y las preguntas se pueden revolver dentro de él, pero ninguna sale del bloque y el recurso va siempre delante. Barajar sigue funcionando; lo que cambia es la unidad que se baraja.
Eso es una restricción que viaja con la prueba, no una decisión de esta pantalla: la respeta quien la aplique. Acá el gadget hace dos cosas —dejar armar el bloque y garantizar que las preguntas de un recurso queden siempre contiguas y detrás de él—; el que baraja tiene que leer esa marca. Si no la lee, el problema vuelve.
Cómo se usa
- En el menú +, «Texto compartido por varias preguntas». Lo único que se pregunta al crearlo es cuántas preguntas van a usarlo, porque de eso depende dónde queda el bloque; el texto se escribe después sobre la hoja, con el mismo editor que un enunciado.
- El rótulo «responde las preguntas 11 a 14» se arma solo y se actualiza al agregar, sacar o reordenar. Escrito a mano quedaría mintiendo a la primera pregunta que se mueva.
- Cada pregunta dice en su carril a qué texto pertenece, en un selector. Las tres operaciones —meterla, sacarla, pasarla a otro texto— son la misma elección, así que es un solo control.
- La tarjeta del recurso trae «+ Pregunta» y «Separar». Separar deja las preguntas donde están y borra el texto: sin preguntas que lo usen no tiene dónde imprimirse, y eso se avisa antes.
- Borrar la última pregunta de un texto se lleva el texto, y la confirmación lo dice. Puede ser media página escrita a mano.
- La pregunta se mueve al bloque; el bloque no se mueve hacia ella. Si al meter la pregunta 1 a un texto que vive en la 11 se reagrupara sin más, el bloque entero saltaría al principio de la prueba: media hoja se mueve sola por marcar una casilla.
- Al paginar, la unidad es el recurso más su primera pregunta. Medidos por separado, el texto puede quedar al pie de una hoja y su primera pregunta al principio de la siguiente — que es justo lo que el bloque existe para evitar. Si el bloque completo no cabe en una hoja, el texto se imprime una vez, en la primera; repetirlo es una decisión de formato que hay que tomar aparte.
El vínculo ya existe y se llama pregunta.idrecurso
—sin guion bajo—. Verificado en el código del producto: apunta a la
tabla archivo, y lo que se lee de ahí es la URL y la
extensión del archivo.
// EvaluationsController
->leftJoin('archivo as a', 'p.idrecurso', '=', 'a.id')
->select( … 'a.url as url_archivo', 'a.archivo_extension', … )
archivo es la biblioteca de Recursos del colegio: tiene
nombre, autor, niveles, etiqueta,
material, colegio, visible. Es un
catálogo de archivos, no un lugar donde escribir texto.
Consecuencia directa: el recurso compartido de hoy sirve para una imagen. Para un texto —que es el caso de comprensión lectora, el más común de todos— falta dónde guardarlo. La versión anterior de este documento decía que esta funcionalidad «no agrega nada a la base»; era falso y está corregido acá.
Lo que NO hay que hacer es guardar el texto como un archivo en
archivo —un .html o una imagen del texto—. Tres
motivos, y el tercero es el que manda:
archivoes una biblioteca que el colegio ve y ordena. Llenarla de fragmentos sueltos de pruebas la vuelve inservible para lo que es.- Un texto dentro de un archivo no se busca con SQL ni se edita en la pantalla: hay que bajarlo, abrirlo y volver a subirlo.
- Un texto como imagen no se puede agrandar, no lo lee un lector de pantalla y no se reflowea. Choca de frente con lo que este mismo documento pide en §5.3 para un alumno con discapacidad visual: cuerpo 14 o mayor. Sería resolver una cosa rompiendo otra.
Decidido por WebClass el 23-09: la tabla propia. Se describe primero; la otra queda anotada sólo para dejar dicho por qué se descartó.
- ✓ Tabla propia para el estímulo, y una columna
más en
pregunta— es la de menos riesgo, porque no toca nada de lo que ya funciona:CREATE TABLE pregunta_estimulo ( id INT AUTO_INCREMENT PRIMARY KEY, colegio INT NOT NULL, tipo VARCHAR(16) NOT NULL, -- texto | tabla | grafico titulo VARCHAR(255) NULL, contenido MEDIUMTEXT NOT NULL -- el HTML del texto ); ALTER TABLE pregunta ADD COLUMN id_estimulo INT NULL;idrecursoqueda como está y sigue sirviendo para la imagen compartida; lo que hoy existe no cambia de comportamiento. Una pregunta puede tener los dos: la imagen poridrecursoy el texto porid_estimulo. - Descartada — una sola tabla que reemplace a las dos
(
pregunta_recurso(id, tipo, contenido, id_archivo)). Más limpia de mirar, pero obliga a migrar lo que ya está y a tocar consultas que hoy funcionan, en un Laravel 5.7 fuera de soporte. No compensa.
Queda por definir un detalle menor de la tabla elegida: si el estímulo es
del colegio —y entonces reutilizable entre profesores, como el banco—
o del profesor que lo escribió. La columna colegio de arriba
asume lo primero, que es lo coherente con el banco de items.
El clon del producto no trae las migraciones, así que las columnas de
archivo salen de las consultas y de los modelos, no del esquema.
Confirmarlo contra producción antes de escribir la migración.
Que el vínculo viva en pregunta y no en prueba_preguntas
es lo que hace útil al banco, y eso no cambia sea texto o imagen: el
recurso viaja con la pregunta. Una pregunta que dice «en el fragmento
leído» no significa nada sin el fragmento; atado a la pregunta, se la trae a
cualquier prueba y el texto llega con ella. Si el vínculo viviera en la prueba,
esa misma pregunta entraría huérfana y habría que pegarle el texto
a mano cada vez.
En la maqueta se ve: el banco tiene tres preguntas de Lengua que comparten un fragmento —van marcadas «📄 con su texto»—. Al traerlas, entra un texto y no tres copias, y quedan agrupadas solas.
La pregunta abierta de «quién baraja» tiene respuesta. Está en
test.barajar y test.barajar_resp, y el reparto por alumno es
literalmente esto:
$preguntas = $barajarPreguntas == 1 ? $preguntas->shuffle() : $preguntas;
Un shuffle() plano sobre todas las preguntas del test. No sabe que
existe idrecurso, así que con el barajado encendido un
estímulo compartido queda separado de sus preguntas — que es exactamente
el problema que esta funcionalidad viene a resolver.
Ahí hay que barajar por bloques: agrupar las preguntas por su recurso,
revolver los grupos entre sí y las preguntas dentro de cada grupo, y volver a
aplanar. Son pocas líneas en el mismo lugar, pero sin eso la funcionalidad no
sirve, y el archivo está identificado:
MobileApp/Evaluations/EvaluationsController — hay que revisar si el
render web tiene su propia copia de esa lógica.
Si el motor ya muestra el recurso una vez al llegar a la primera pregunta que lo usa, ¿para qué forzar que estén contiguas? Porque «una vez, en la primera» y «justo antes de todas» sólo coinciden si no hay otra pregunta en medio. Con las preguntas 11, 14 y 19 apuntando al mismo texto, el alumno lee el texto en la 11 y tiene que volver dos páginas atrás en la 19.
El gadget garantiza la contigüidad —mete la pregunta junto al bloque— para que lo que se imprime sea lo que el motor asume. No es una restricción nueva sobre la base: es no producir pruebas que el mecanismo soporta pero que se leen mal.
6.5 Categorización — el carril de la derecha
Cada pregunta tiene, a su derecha y alineada con ella, una tarjeta con tres estados: Categorización y Retroalimentación. Cada uno se marca solo cuando está completo, así se ve de un vistazo qué falta. Hay además una banderita para marcar una pregunta y volver a ella.
Al hacer clic se abre un cajón lateral. Los campos de categorización:
El orden sigue el del currículo: primero dónde se busca —nivel, asignatura, eje— y después qué se eligió ahí dentro —objetivo, indicador—. Con el eje debajo del objetivo, el filtro aparecía después de lo filtrado y no servía de nada.
| Campo | Origen | Obligatorio |
|---|---|---|
| Nivel | Por defecto el de la evaluación, editable (ver abajo) | Sí |
| Asignatura | Por defecto la de la evaluación, editable | Sí |
| Eje temático | Sale del propio catálogo de ese nivel + asignatura, no de una lista aparte. Filtra los objetivos | No |
| Objetivo de aprendizaje | Catálogo Mineduc filtrado por nivel + asignatura + eje → pregunta_atributo | Sí |
| Indicador de evaluación | indicadores, filtrado por el OA elegido → pregunta_indicador | Sí |
| Habilidad | Conocer / Comprender / Aplicar / Analizar / Evaluar / Crear | No |
| Dificultad estimada | Baja / Media / Alta → pregunta.dificultad | No |
| Puntaje | Numérico, por pregunta | Sí |
Las seis primeras filas —de nivel a habilidad— se repiten una vez por objetivo: una pregunta puede declarar varios. Ver §6.5.b. La dificultad y el puntaje, en cambio, van una sola vez por pregunta.
No hay campo de etiquetas libres. Estuvo y se quitó: para filtrar el banco de items ya están el objetivo, el indicador, la habilidad, el eje, la dificultad y el nivel —todos de catálogo y todos comparables entre colegios—. Un texto libre al lado se llena distinto en cada sala («u3», «Unidad 3», «unidad III») y termina siendo ruido en el buscador en vez de un filtro.
Vienen puestos con los de la evaluación, pero se pueden cambiar. No es un lujo: un recuperativo casi siempre arrastra contenido del nivel anterior, y un control de síntesis mezcla ejes de varias unidades. Obligar a que el objetivo sea del mismo nivel que la prueba sería mentir sobre lo que la pregunta mide, y la cobertura curricular quedaría mal calculada.
En consecuencia, pregunta_atributo tiene que guardar el objetivo
con su nivel, no deducirlo de la prueba. Y hoy no lo guarda, verificado
en el código del producto: el INSERT es
(pregunta, eje, tipo, atributo) y el nivel sale de
prueba.sector → sector.nivel. Así que esto es un cambio de
modelo, no sólo de pantalla, y es el único de todo el documento:
está encabezando el §11.
Cuando la pregunta se aparta del nivel o la asignatura de la evaluación, la pantalla lo dice en naranjo: es una decisión válida, pero no debe pasar por accidente.
Cambiar el nivel o la asignatura limpia eje, objetivo e indicador, y se avisa: apuntan a un catálogo que ya no es el vigente, y dejarlos produciría combinaciones que no existen en ningún currículo. Por lo mismo, al cambiar el OA se limpia el indicador.
Al revés, elegir un objetivo completa el eje solo: el eje es un dato del objetivo, no una etiqueta que el profesor tenga que recordar.
6.5.b Una pregunta puede medir varios objetivos funcionalidad nueva
Hoy la pantalla deja declarar un objetivo por pregunta, y eso no alcanza. Un problema de área que se resuelve con una ecuación cuadrática mide geometría y álgebra; una pregunta de un recuperativo mide un objetivo del año anterior junto con el del año en curso. Con un solo casillero, el profesor tiene que elegir cuál declarar, y la tabla de especificaciones queda contando de menos justamente en las preguntas más ricas.
El cajón pasa a tener una tarjeta por objetivo, cada una con su nivel, asignatura, eje, objetivo, indicador y habilidad completos, más un botón «+ otro objetivo» y una × por tarjeta. Todas las reglas de §6.5 —el eje filtra, cambiar el nivel limpia lo de abajo, elegir el objetivo completa el eje, lo ajeno se marca en naranjo— siguen valiendo dentro de cada tarjeta, por separado.
- Cada tarjeta puede ser de otro nivel y otra asignatura. Una pregunta de 2° Medio puede declarar un objetivo de 1° Medio sin dejar de declarar el suyo.
- La dificultad y el puntaje quedan fuera de las tarjetas, una sola vez al final. Son propiedades de la pregunta, no del objetivo que mide: repetirlas por tarjeta invitaría a ponerles valores distintos, que no significan nada.
- El objetivo nuevo hereda el nivel y la asignatura del anterior, no los de la evaluación. Si el profesor está categorizando contenido de otro nivel, lo probable es que el siguiente también lo sea.
- Una pregunta cuenta como categorizada con que al menos un objetivo tenga objetivo e indicador. Empezar a escribir un segundo no puede devolver a «sin categorizar» una pregunta que ya lo estaba.
- El carril muestra las etiquetas de todos los objetivos, no sólo del primero: si no se ven, la categorización múltiple existe pero nadie la revisa.
Una pregunta de 3 puntos que mide dos objetivos aporta 1,5 a cada uno en la tabla de especificaciones. Sumarla entera en los dos haría que la columna de puntos diera más que el total de la prueba y que los porcentajes pasaran de 100: la tabla dejaría de servir para ver el equilibrio, que es para lo único que existe.
En la planilla exportada eso se ve como una fila por objetivo, con el puntaje de la pregunta y el que le toca a ese objetivo en columnas distintas. La segunda es la que suma el total.
pregunta_atributo y pregunta_indicador son tablas de
relación N:M —llave compuesta, una fila por pregunta y atributo—.
Siempre admitieron varios atributos por pregunta. El límite de uno solo
estaba en la interfaz, no en el modelo.
Lo que hay que cambiar, entonces, no es el esquema sino el guardado: hoy se escribe
una fila y se reemplaza; tiene que escribirse el conjunto de filas de la
pregunta y borrarse las que ya no están. La única pregunta abierta es la
de §6.5: si el nivel del atributo se guarda o se deduce de
prueba —con varios objetivos de niveles distintos, deducirlo deja de
ser posible—.
6.5.c El objetivo propio, fuera del catálogo
No es nuevo en WebClass: hoy el profesor le puede poner a una pregunta un objetivo
que no está en el catálogo, y queda en
pregunta_atributo_adicional (id, pregunta_id, tipo, caracteristica) con
caracteristica en texto libre. Verificado en el vanilla: los informes
lo leen (test_informe, informepme), el logro lo cuenta
—EvaluacionDao tiene la misma consulta con esta tabla en vez de
pregunta_atributo— y se copia al duplicar la pregunta. Lo que faltaba
era que el generador lo ofreciera.
En el cajón, junto a «+ Otro objetivo», va «+ Objetivo propio». La tarjeta que agrega pide dos cosas y nada más:
- Tipo — objetivo de aprendizaje, habilidad o actitud. Son los códigos
3,4y7que la tabla ya usa, los mismos depregunta_atributo.tipo. - Qué mide — el texto.
Sin nivel, sin eje, sin indicador: la tabla no tiene esas columnas y pedirlos sería inventarlas. Por lo mismo un objetivo propio nunca se marca como ajeno: su nivel es el de la prueba.
atributosDao::mostrarAtributosAdicionalesDeLasPreguntasDeLaEvaluacion hace
GROUP BY paa.caracteristica. «Comunica su procedimiento» y «comunica su
procedimiento.» son, para el informe, dos objetivos con la mitad de las preguntas
cada uno, y el logro de los dos es mentira. Con texto libre eso no es un caso raro: es lo
que pasa por defecto.
Por eso la tarjeta ofrece los que el colegio ya usa —los de la prueba primero, después los de otras preguntas del mismo nivel y asignatura— para elegirlos con un clic, y si se escribe uno que sólo difiere en mayúsculas, tildes, espacios o el punto final, se adopta el existente y se avisa. La comparación es ésa y no más: «modela funciones» y «modela con funciones» siguen siendo dos, porque decidir que son el mismo ya es corregirle el objetivo al profesor.
- Cuenta como categorizada una pregunta cuyo único objetivo es uno propio de tipo objetivo: el producto lo mide, así que la tabla de especificaciones también. Los de tipo habilidad o actitud acompañan —como la habilidad del catálogo— pero no categorizan solos.
- En la tabla de especificaciones cada objetivo propio es una fila, después de los del catálogo y antes de «sin categorizar», y se lleva su parte del puntaje como cualquier otro (§6.5.b): una pregunta de 3 puntos con dos OA y uno propio le da 1 a cada uno. Las habilidades y actitudes propias no reparten puntaje y van en una lista aparte, con sus preguntas.
- En la planilla exportada el objetivo propio sale como una fila más, con «Propio: …» en la columna de objetivo y sin nivel ni eje; las habilidades y actitudes propias van en la columna de habilidad.
- El carril los muestra con su propio color, y el resumen de la barra los cuenta aparte: «3 OA + 1 propio».
- Si la IA propone la categorización, completa el primer objetivo del catálogo; si el primero es propio, no le escribe un código de OA encima.
El guardado es el mismo cambio que pide §6.5.b para pregunta_atributo:
escribir el conjunto de filas de la pregunta y borrar las que ya no están.
La lista de «ya usados» sale de un
SELECT DISTINCT tipo, caracteristica sobre las preguntas del colegio en ese
nivel y asignatura —el nivel se deduce de la prueba, porque la tabla no lo
guarda—. Conviene normalizar al guardar (espacios repetidos y en los
extremos): es gratis y ya evita la mitad de los duplicados.
6.6 Retroalimentación
La pestaña se llamaba «Explicación» y ofrecía un campo de texto.
Al revisar el producto resultó que WebClass ya guarda siete textos de
retroalimentación por pregunta, y que el nombre correcto es el suyo. Relevado en
App\Pregunta, Api/ScormController y los
Objetos/Respuesta_*.php del vanilla:
| Columna | Cuándo se muestra |
|---|---|
pregunta.retroalimentacion | Siempre, gane o pierda. Es el «por qué» de la pregunta y lo que va en la pauta del docente. |
pregunta.retrocorrecta | Si responde correcto. |
pregunta.retroparcial | Si responde parcialmente correcto. |
pregunta.retroincorrecta | Si responde incorrecto. |
respuesta_vof.retroalimentacionVrespuesta_vof.retroalimentacionF | Según marque Verdadero o Falso. Dos textos distintos, no uno. |
respuesta_alternativa.retroalimentacion | Por cada alternativa, incluida la correcta. |
respuesta_corta.retroalimentacion | Por cada respuesta aceptada. |
La maqueta tenía una pestaña Distractores para anotar, por cada alternativa incorrecta, qué error comete quien la elige. Se quitó: se buscó la palabra en todo el producto y no hay ninguna funcionalidad con ese nombre.
Peor: donde sí aparece, significa una cosa distinta. En el editor de
términos pareados (editarPreguntas.php,
controladorPregunta.php) un «distractor» es un
concepto de la columna B que no tiene pareja — una opción señuelo
en un emparejamiento, que se guarda con vinculo_a = -2. Nada que ver con
analizar el error de una alternativa. Y en varios archivos el control está
comentado, así que ni siquiera se usa completo.
Lo que sí se conserva es la retroalimentación por alternativa,
porque respuesta_alternativa.retroalimentacion es una columna real. Vive
ahora dentro de esta misma pestaña, como un grupo más: es el mismo dato,
llamado como lo llama el producto. También se fue la herramienta de IA
«Proponer distractores».
El distractor de verdad —el señuelo sin pareja— sí entra
al gadget. Es el único de los dos sentidos que existe en el producto, hace
más exigente el ejercicio, y el control ya está a medias en
editarPreguntas.php: hay que descomentarlo y terminarlo, no
inventarlo. Ver Términos pareados para el
comportamiento y el modelo de datos.
1. La retroalimentación ya es condicional en la base, pero no en la
pantalla. Tener retrocorrecta, retroparcial y
retroincorrecta significa que el producto ya contempla que el
alumno lea algo distinto según lo que respondió, que es lo que convierte a
la retroalimentación en algo formativo y no en una pauta escondida. Ofrecer un
solo campo dejaba tres columnas sin usar.
2. retroparcial confirma el puntaje parcial. Que la columna
exista es evidencia de que la corrección parcial está contemplada — lo
que sostiene el tipo de varias correctas con porcentaje (§6.3.a). En la
maqueta ese campo sólo aparece en los tipos que reparten puntaje: varias
correctas, pareados y respuesta corta. Mostrarlo en una de una sola correcta
sería pedir un texto que nunca se va a mostrar.
En pregunta hay además tres columnas que parecían gobernar
el puntaje. Se fueron a mirar al código y ninguna lo hace:
penalizacionse escribe siempre en 0 ($pregunta->setPenalizacion(0), en los dos lugares que guardan una pregunta). La penalización de verdad es del test, no de la pregunta:test.penalizacionjunto atest.buenaspormalas—el descuento clásico de «buenas por malas»—, y se decide al asignar la prueba, que es otra pantalla.parcialno aparece en elINSERTdepreguntani en ninguna consulta: sólo tiene setter y getter en los objetos. Columna muerta.correccionno es un modo ni un número: es texto con formato. Sale de un CKEditor (id_correccion) y es la pauta de corrección que el profesor escribe para sí mismo.
Lo último deja un hueco chico en este gadget: correccion es
un campo por pregunta que el producto ya tiene y que el editor no ofrece. Para
las de desarrollo lo cubre la rúbrica (§6.4), que es mejor; para los
demás tipos, hay que decidir si se rescata o se da por reemplazado. No se
inventó nada para llenarlo: escribir ahí sin saber quién lo
lee sería peor.
- La retroalimentación de cada alternativa va en la misma pestaña, como un grupo más, y también la correcta tiene campo: en la base la columna es por alternativa, sin excepción, y «por qué esta es la correcta» es justo lo que conviene mostrarle a quien acertó.
- Es lo que después permite el análisis de resultados — saber qué no entendió el curso, no sólo cuántos fallaron.
- La herramienta de IA escribe los tres textos de una vez y cobra una sola vez: pedirlos por separado serían tres cobros para una sola lectura de la pregunta.
- La marca del carril se enciende con cualquiera de los textos: una pregunta con retro de correcto e incorrecto está trabajada aunque no tenga la general.
6.7 Dos pestañas
| Pestaña | Contenido |
|---|---|
| Contenido | El editor. Es la pestaña por defecto y donde se pasa el 95% del tiempo. |
| Especificaciones | Se arma sola con lo categorizado: OA → indicador → nº de preguntas, puntos y % del total. Las preguntas sin categorizar salen destacadas en una fila propia, no escondidas. |
Tenía título, nivel, asignatura, tipo, exigencia e instrucciones. Al revisarla campo por campo, casi nada correspondía estar ahí:
- Nivel, asignatura y tipo sí se pueden cambiar después, pero no merecen una pestaña: son tres selectores y viven en ⚙ Opciones, junto con lo demás que configura la prueba. Ver más abajo.
- El título se edita sobre la hoja (§6.8.b). Estaba duplicado.
- Las instrucciones ahora se escriben sobre la hoja (§6.8.b).
- La exigencia se fue del gadget entero. No es un dato de la prueba sino de su aplicación: se define al asignarla a un curso, y una misma prueba puede aplicarse a varios cursos con distinta exigencia. Tenerla acá obligaría a decidir cuál de las dos manda.
- Con eso, de la pestaña no quedaba ningún campo que justificara una pestaña propia.
- El resumen de puntajes que mostraba abajo ya está en el botón (i) de la barra.
6.9.b El banco de items funcionalidad nueva
Es lo que justifica económicamente el gadget. Un profesor escribe unas 40 preguntas al año y al año siguiente las vuelve a escribir. Reusar gana lejos sobre generar, y hoy el camino más rápido para armar una prueba es digitalizar el PDF del año pasado —teniendo esas preguntas en la base de datos—.
- Se busca por atributos: nivel, asignatura, eje, objetivo, indicador, habilidad, tipo y dificultad. Arranca con el nivel y la asignatura de la evaluación. Ver la caja de abajo.
- Se eligen varias de una vez y el botón dice cuántas.
- Llegan ya categorizadas: OA, eje, indicador, habilidad y dificultad viajan con la pregunta. No hay que volver a clasificarlas.
- Un item de otro nivel o asignatura se marca como ajeno en la lista, antes de traerlo.
Cada item muestra cuántas veces se aplicó y su % de logro. Eso
es lo que permite armar una prueba equilibrada en vez de una donde todo resultó
difícil, y es información que ya existe: sale de las respuestas de
alumnos que el producto guarda en respuesta_*_alumno. Un banco sin esa
columna es sólo una carpeta de preguntas viejas.
El campo de búsqueda por texto se sacó. Nadie recuerda con
qué palabras redactó una pregunta hace un año —y si las
recordara, no necesitaría buscarla—. Lo que el profesor sí tiene
claro es qué quiere medir, y eso es justamente lo que el banco guarda
en pregunta_atributo y pregunta_indicador.
Los filtros encadenan igual que la categorización: el eje acota los objetivos, el objetivo acota los indicadores, y cambiar uno de arriba suelta los de abajo. Un profesor que ya sabe categorizar no tiene que aprender otra mecánica.
Cada opción dice cuántos items tiene detrás —«MA2M OA 03 — Ecuaciones cuadráticas (5)»— y las que tendrían cero no se ofrecen. Un selector con los 30 objetivos del año, de los cuales 26 no tienen ni una pregunta, obliga a ir probándolos uno por uno; con la cuenta al lado, el profesor ve de una dónde hay material y dónde va a tener que escribir.
Consecuencia para el desarrollo: la consulta del banco necesita un conteo agrupado por cada atributo, no sólo la lista filtrada. Son dos consultas, no una.
6.10 Cambiar el nivel, la asignatura o el tipo después de crear
Los tres se eligen al crear la evaluación y quedan en ⚙ Opciones › La evaluación, arriba de todo. Equivocarse de nivel y tener que rehacer la prueba entera es el problema más caro de los que hay en juego acá, más caro que cualquiera de los que trae el cambio.
Esta era una pregunta abierta y ahora tiene respuesta. Las tres salidas posibles eran descategorizar, bloquear el cambio u ofrecer un mapeo. La que se toma es una cuarta, que el gadget ya habilitó sin querer: conservar y avisar.
Desde que la categorización de cada pregunta admite atributos de otros niveles y asignaturas (§6.5), una pregunta con un OA de 2° Medio dentro de una prueba de 1° Medio no es un error: es un caso que ya se soporta y se muestra marcado como ajeno. Cambiar el contexto, entonces, no rompe nada.
- Al cambiar, Opciones dice cuántas preguntas quedaron con objetivos de otro nivel o asignatura. No se toca ninguna: el profesor revisa o deja, porque una prueba puede medir un objetivo de un nivel anterior a propósito.
- El catálogo de OA que se ofrece al categorizar pasa a ser el del nivel nuevo, y el cajón de la pregunta abierta se repinta solo.
- El tipo de evaluación no toca la categorización: se cambia y listo.
Detalle de implementación, y no es menor. Una pregunta guarda su nivel y asignatura sólo cuando son distintos de los de la prueba; si no, los hereda. Al cambiar el contexto hay que fijárselos antes, con el valor viejo. Sin eso, todas las preguntas pasan a «pertenecer» al nivel nuevo en silencio —aunque su OA siga siendo del anterior— y el descalce que se quiere avisar desaparece justo en el momento en que aparece. Es un fallo que no da ningún síntoma: se ve todo bien y la tabla de especificaciones queda mintiendo.
Generaba formas equivalentes barajando el orden de preguntas y alternativas, con su pauta. Se sacó del alcance de este gadget.
No es que sobre: es que es otra funcionalidad. Barajar tiene sentido cuando la prueba se aplica, y la aplicación —asignar a un curso, fijar fecha y hora, corregir— vive en otra parte de WebClass. Mezclarla con la autoría hacía que este gadget tuviera dos dueños y dos momentos de uso distintos.
También desapareció la herramienta de IA «Generar una forma equivalente», que apuntaba a esa pestaña.
6.8 La barra del editor: una sola línea
Al centro, en la misma línea, las cuatro pestañas y después de un separador los dos botones que abren cajón: ⚙ Opciones y ✨ Herramientas de IA. A la derecha, Descargar y Guardar — son lo que se hace al terminar y la relación entre ellas importa (§6.9).
No hay una segunda fila de menú. Es alto robado a la hoja, que es lo único que el profesor necesita mirar. El separador marca la diferencia entre las dos mitades: a la izquierda se cambia de vista, a la derecha se abre un cajón. Cuando la ventana es angosta, pestañas y botones bajan juntos a una segunda fila: separarlos reinventaría el menú que se acaba de eliminar.
| Entrada | Qué tiene |
|---|---|
| ⚙ Opciones |
Encabezado de la primera hoja: insignia del establecimiento y casillas de la
ficha del alumno — nombre y apellido, curso y fecha (§6.8.b). Vista del editor: ver saltos de página. Texto: tipografía y tamaño base. La hoja: tipo de hoja (A4, Carta, Oficio), márgenes (1,5 / 2 / 2,5 cm) y columnas para las alternativas. |
| ✨ Herramientas de IA | §7. |
- No hay «Compartir». WebClass no permite compartir una evaluación fuera del establecimiento, así que ofrecerlo sería prometer algo que el producto no hace.
- No hay «Portada». Misma razón: ofrecía una página inicial que el producto no genera.
- No hay «Encabezado» aparte. Sus cuatro interruptores son el primer grupo de Opciones. Eran dos puertas para configurar la misma hoja, y obligaban a recordar en cuál estaba cada cosa.
- No hay «Formato» aparte. Lo que contenía (papel, márgenes, columnas) vive en Opciones, junto con los dos interruptores de vista. Dos menús para configurar la misma hoja obligaban a adivinar en cuál estaba cada cosa.
- Los interruptores de vista salieron de la barra superior. Estaban a la vista permanentemente y le quitaban alto a la hoja, que es lo único que el profesor necesita mirar.
«Ver saltos de página» apagado muestra una tira continua, cómoda para escribir seguido. La pantalla lo advierte: con los saltos apagados el editor deja de coincidir con la impresión.
6.8.b El encabezado de la hoja
| Qué lleva | Dónde |
|---|---|
| Insignia del establecimiento | Arriba a la izquierda. |
| Título de la evaluación | Centrado, y nada debajo. |
| Ficha del alumno | Configurable: qué casillas hay, cómo se llaman y en qué orden. Ver §6.8.c. |
| Instrucciones | En su recuadro, editables sobre la hoja. |
- Los dos códigos QR. WebClass no tiene hoy lectura óptica de la hoja impresa, así que no codificaban nada que alguien leyera: eran decoración ocupando las dos esquinas superiores, que es el mejor espacio del papel. Si alguna vez se implementa la corrección por escaneo, vuelven — pero entonces con una especificación de qué codifican.
- La línea de asignatura, nivel, tipo y puntaje bajo el título, que dejó de venir de fábrica. Son datos del sistema, no de la hoja: el alumno que rinde la prueba ya sabe de qué asignatura es, y el puntaje total ahí arriba sólo compite con el puntaje de cada pregunta, que es el que sí necesita ver. Vuelve como interruptor —«Datos bajo el título», en Opciones— porque hay colegios que la exigen impresa. Apagada por defecto. Se arma sola con lo que dice Opciones y con las preguntas que hay —asignatura, nivel, tipo, cuántas preguntas y el puntaje total—; no se escribe a mano y se actualiza al agregar una pregunta o al cambiar la asignatura.
- El botón «Portada». Prometía una página inicial que WebClass no genera. Una opción de menú que no hace nada es peor que no tenerla.
6.8.c Las casillas que llena el alumno son configurables funcionalidad nueva
Eran tres interruptores fijos —nombre, curso, fecha— y cada colegio pide alguno más: RUT, sala, número de lista, firma del apoderado, puntaje obtenido. Con una lista cerrada, el que necesita otra casilla la dibuja a mano sobre la fotocopia.
Ahora es una lista: se ocultan las que no se usan, se agregan otras del catálogo de WebClass, se crean propias con el nombre que se quiera, se reordenan arrastrando y cada una elige su ancho.
Un clic sobre las casillas de la hoja abre el modal. Es el lugar donde el profesor está mirando justo cuando se da cuenta de que le falta el RUT; un interruptor guardado en otro cajón no se encuentra. En Opciones queda sólo un atajo, para quien lo busque ahí.
Los campos de fábrica —Nombre, Apellido, Curso, Fecha, Puntaje, Nota, Profesor, N° de lista— llevan un id estable y se marcan en el modal como «de WebClass». Los que crea el profesor son texto libre y no lo llevan.
Importa porque el día que WebClass imprima una copia por alumno con el nombre y el curso ya puestos, sólo va a poder rellenar los que reconoce. Un campo propio siempre va a quedar en blanco: es una casilla dibujada. Eso se dice en el modal, no se deja para que lo descubran.
Con más de tres casillas la ficha pasa a dos filas y el rótulo se corre al costado izquierdo, que es como se llena una ficha en papel: en una sola fila, cuatro campos quedan tan angostos que el alumno escribe encima del de al lado.
prueba, no una tablaALTER TABLE prueba ADD COLUMN encabezado TEXT NULL DEFAULT NULL;
// App\Prueba
protected $casts = ['encabezado' => 'array'];
Esto no son datos de la evaluación: es cómo se imprime el
documento. Nadie va a consultar nunca «dame todas las pruebas que tienen campo RUT»,
ni cruzarlo con nada. Normalizarlo en
prueba_campo_encabezado(id, id_prueba, etiqueta, orden, ancho, visible)
cuesta una tabla, un modelo, un join en cada lectura y un borrado en cascada, y
no compra ninguna consulta que se vaya a escribir. Es la clase de tabla que se
crea por prolijidad y después nadie usa.
NULL significa «los de siempre», así que la gran mayoría de
las filas queda vacía y no ocupa nada.
{"logo":true,
"datos":false, <-- la linea bajo el titulo
"campos":[
{"id":"nombre","visible":true,"ancho":"ancho"},
{"id":"curso","visible":false},
{"id":"c1","etiqueta":"RUT","ancho":"corto"}
]}
Los dos interruptores del encabezado —la insignia y la línea de datos bajo el título— van en el mismo JSON y por la misma razón: describen cómo se ve esta hoja y no se consultan nunca. Nadie va a preguntar «cuántas pruebas llevan la insignia».
- Guardar la foto, no la referencia. Va a querer existir una plantilla por establecimiento —el colegio entero usa el mismo encabezado—, pero la prueba tiene que guardar el resultado ya resuelto, no un puntero a la plantilla. Si el año que viene UTP la cambia, una prueba de 2026 que se reabre para duplicar no puede cambiar de forma sola: el documento impreso es un hecho histórico.
- Va como
JSONnativo. Producción corre MySQL 8.4 —confirmado por WebClass el 23-09—, así que no hay que elegir: el tipoJSONvalida al escribir y rechaza un encabezado corrupto en vez de guardarlo. ConTEXTel error aparecería recién al leerlo, que es cuando el profesor abre la prueba.
El nombre y las instrucciones se editan en la hoja
El nombre de la evaluación tenía un campo en la barra superior y se quitó. Era el mismo dato en dos lugares, y el de arriba ni siquiera lo mostraba con la tipografía con que se va a imprimir: se escribía a ciegas. Ahora se edita sobre el título de la hoja, que es donde el profesor lo va a leer. La miga de pan lo sigue mientras se escribe.
Ese campo no abre el editor de texto: se escribe directo sobre la hoja. Un nombre es un rótulo, no un párrafo —ofrecerle negrita, tipografía, fórmulas, tablas y gráficos es ruido— y abrir un modal para teclear cuatro palabras sería peor que el problema que resuelve. Lo mismo vale para los términos pareados y las respuestas aceptadas. Ver §6.2.
Es el texto que más se retoca —cambia con cada prueba— y mandarlo a un formulario aparte era un rodeo para tres palabras. Ahora se escriben sobre la hoja, igual que el enunciado de una pregunta, y ese es el único lugar donde se editan.
Cuando quedan vacías, en el editor se ve un texto guía en gris —si no, no habría dónde hacer clic para volver a escribirlas— pero al imprimir el recuadro desaparece.
6.9 Guardar y Descargar
El botón principal dice Guardar, no «Publicar»: en WebClass una evaluación no se publica — se guarda, y después se asigna a un curso, que es otra acción y de otro módulo. Al lado va Descargar.
Al guardar hay dos niveles, y la diferencia importa:
| Qué falta | Qué pasa |
|---|---|
| Alguna pregunta sin la clave completa (§8.b) | No deja guardar. No hay «guardar igual». |
| No hay ninguna pregunta | No deja guardar. |
| Preguntas sin objetivo de aprendizaje o indicador | Avisa y guarda igual; la prueba queda marcada como incompleta y no entra al banco de items. |
| Preguntas generadas por IA sin revisar | Igual que la anterior. |
Una evaluación sin respuestas correctas no se puede corregir, y una evaluación que no se puede corregir no sirve de nada guardada: no tiene pauta y no se puede aplicar en línea. Es la única regla del gadget que no admite «guardar igual».
Para que no sea una pared ciega, el aviso es accionable:
- Dice cuáles preguntas son, por número, y qué le falta a cada una — no el mismo texto genérico para todas.
- Tiene un botón «Ir a la primera» que baja hasta ella y la resalta.
- Cada pregunta sin clave lleva una etiqueta roja «sin clave» en su tarjeta, así se ve antes de apretar Guardar y no después.
8.b Qué es «clave completa» en cada tipo
Cada tipo tiene su propia idea de estar listo, así que la regla vive en el
catálogo de tipos y no repartida en condiciones sueltas por el
código. Agregar un tipo nuevo es agregar una fila acá, no buscar todos los
if que hablaban de «desarrollo».
| Tipo | Está listo cuando… |
|---|---|
| Selección múltiple · V/F · V/F con justificación · recorte | Hay una alternativa marcada correcta. |
| Selección múltiple con varias correctas | Hay al menos una correcta y los porcentajes suman 100%. |
| Términos pareados | Hay al menos dos pares, ninguno tiene una columna vacía y ningún distractor quedó sin texto. |
| Respuesta corta | Hay al menos una respuesta aceptada con texto. |
| Desarrollo sin rúbrica | Siempre. Se corrige a mano; no hay clave que exigir. |
| Desarrollo con rúbrica | Los criterios suman el puntaje de la pregunta, ninguno está sin nombre y ninguna celda sin descriptor. |
La descarga se genera desde la versión guardada, no desde lo que hay en pantalla. Con cambios sin guardar, el PDF no coincidiría con lo que el profesor está viendo — y ese PDF es el que se imprime y se le pasa al curso.
- Mientras haya cambios pendientes, Guardar lleva un punto y Descargar se ve apagado.
- Descargar no se deshabilita: al pulsarlo explica por qué no puede todavía y ofrece «Guardar y descargar» en un paso. Un botón muerto no enseña nada; este encadena la acción que falta.
- Cualquier edición posterior vuelve a marcar la prueba como no guardada, incluidas las de Opciones: cambiar el tamaño de hoja cambia el PDF.
Al pulsar Descargar hay que elegir entre dos archivos:
- Para el estudiante — sin ninguna marca. Es la que se imprime y se reparte en la sala. Va preseleccionada: es la que se genera casi siempre, y si alguien acepta sin leer, el error es inofensivo.
- Pauta de corrección — con la respuesta correcta destacada en cada pregunta. Es para el docente.
Antes esto era un interruptor de Opciones («marcar respuesta correcta») que apagaba las marcas en pantalla. Era el control equivocado en el lugar equivocado: mientras arma la prueba el docente siempre quiere ver cuál es la correcta —es lo que está decidiendo— y lo que en realidad necesita elegir es qué sale en el papel.
Y tenía un modo de fallo caro: dejarlo encendido y olvidarlo significaba imprimirle al curso la prueba con las respuestas. Un interruptor persistente que hay que acordarse de apagar antes de cada impresión es una trampa; una pregunta en el momento de generar el archivo, no.
En el editor la clave se ve siempre. Durante la generación se cambia la vista, se genera y se deja como estaba: si el editor quedara sin las marcas, el docente creería que se le borraron.
6.11 Qué le pareció la pregunta al profesor funcionalidad nueva
Cada pregunta que propuso la plataforma —traída del banco o generada por IA— muestra en su carril dos pulgares: 👍 la volvería a usar y 👎 no me gusta, cámbiala.
Hoy el banco crece sin que nadie sepa qué parte de él sirve: una pregunta mal redactada o con dos respuestas correctas sigue ofreciéndose a todos los profesores del país hasta que alguien la reporta por otro canal. Y la IA vuelve a proponer lo mismo que ya rechazaron, porque nadie le dijo que lo rechazaron.
Con el pulgar, esa señal queda: qué preguntas se reusan y cuáles se descartan, quién lo dijo y para qué objetivo.
Lo elegido queda a la vista, no sólo hundido
Dos pulgares grises uno al lado del otro no dicen cuál se apretó: hay que acordarse. Con veinte preguntas en la prueba, eso es justo lo que no se puede pedir. Así que lo elegido se pinta: amarillo el pulgar arriba, rojo el pulgar abajo, el otro se apaga para que en el carril haya una sola respuesta a la vista, y el rótulo dice en palabras lo mismo que dice el color —«La volverías a usar» / «No te gustó»—, porque el color solo no basta para quien no lo distingue.
Sólo se pregunta por lo que la plataforma propuso
Una pregunta que el profesor escribió él, o que importó de su propio PDF, no pide valoración. Pedirle que califique lo suyo es pedirle que se califique solo: no dice nada de la plataforma y ensucia el dato justo donde se lo quiere limpio.
El pulgar abajo no es sólo una queja: viene con el reemplazo
- Si la pregunta vino del banco, se ofrece otra del banco del mismo objetivo —y que no esté ya en la prueba, porque cambiar una pregunta por otra que el alumno va a ver dos páginas más abajo no es un reemplazo—. Si el banco no tiene otra, se dice y se ofrece generarla.
- Si la pregunta la generó la IA, se ofrece generar otra para el mismo objetivo, y se cobra como cualquier generación.
- Siempre se puede dejarla como está. La opinión queda guardada igual: son dos cosas distintas y el profesor puede querer una sin la otra.
- El reemplazo conserva el puntaje y la posición: la prueba no cambia de forma porque una pregunta no gustara.
- Volver a apretar el mismo pulgar retira la opinión. Opinar por accidente y no poder deshacerlo ensucia exactamente el dato que se quiere limpio.
Lo que se cambia no se borra del banco. Que a un profesor no le sirva no es motivo para retirarla; que se lo digan varios, sí — y esa decisión no es de una prueba, es del establecimiento o de WebClass.
CREATE TABLE pregunta_valoracion (
id INT AUTO_INCREMENT PRIMARY KEY,
id_pregunta INT NOT NULL,
id_usuario INT NOT NULL,
id_prueba INT NULL, -- en qué prueba se opinó
valor TINYINT NOT NULL, -- 1 la volvería a usar · -1 no me gusta
creado DATETIME NOT NULL,
UNIQUE KEY uq_opinion (id_pregunta, id_usuario)
);
Contraste deliberado con §6.8.c, donde las casillas del encabezado van en una columna JSON: aquello es cómo se imprime un documento y nadie lo consulta; esto se consulta y se agrega —«las 20 preguntas más descartadas de Matemática 2° Medio»—. Un dato que se agrupa gana su tabla; uno que sólo se lee junto con su fila, no.
La clave única (id_pregunta, id_usuario) es lo que hace
utilizable el dato. Sin ella, un profesor que reusa la misma pregunta en cinco
pruebas cuenta cinco veces, y el ranking termina midiendo quién reusa
más, no qué pregunta es mejor. Volver a opinar actualiza su
opinión.
id_prueba queda como contexto —sirve para saber si la descartaron
en un recuperativo o en una prueba de unidad—, pero la opinión es
de la pregunta, no de la prueba: por eso no cuelga de ella.
Una pregunta generada todavía no existe en la base: no tiene
id_pregunta hasta que la prueba se guarda. Y la que el profesor descarta
nunca llegaría a guardarse — justo la que más interesa
registrar, porque es el único rastro de qué produjo la IA y fue
rechazado. Sin ella, la señal más valiosa se pierde en el momento
exacto en que se produce.
Se guarda igual, marcada como descartada y sin quedar colgada de la prueba: no es una pregunta de esa evaluación, es un registro de lo que la plataforma propuso. Con eso tiene id, la valoración apunta a algo inspeccionable, y se puede responder la pregunta que importa: qué está generando la IA que los profesores no aceptan.
pregunta.visible = 0 sí sirve para esconderla, verificado:
la consulta que arma la prueba del alumno filtra por p.visible = 1
(AlumnoTestDao::getPreguntasPorIdTest), así que una descartada no
llega a nadie. Lo que falta confirmar es si una pregunta sin fila en
prueba_preguntas rompe algo del módulo viejo —el listado del
banco, los informes—. Si rompiera, la salida es una tabla aparte para descartes,
con el texto y los atributos con que se pidió, sin tocar pregunta.
La marca de «descartada» no se muestra en pantalla: es un dato para la plataforma. Una pregunta que el profesor no sólo no volvería a usar sino que sacó de la prueba pesa más que un pulgar abajo, y esa diferencia sólo la puede usar quien revise el banco.
7Herramientas de IA y tokens
Todas las acciones de IA descuentan de una bolsa de tokens del establecimiento, que el WebClass manager del colegio reparte entre sus profesores (más abajo). Lo que el profesor ve en el cajón lateral, en todo momento, es su cupo.
| Herramienta | Qué hace | Costo de referencia |
|---|---|---|
| Generar preguntas desde un OA o una habilidad | Propone preguntas con sus alternativas, desde el cajón o desde la tabla (§5.2) | 40 por pregunta |
| Categorizar automáticamente | Asigna OA e indicador a las que no tienen | 25 por pregunta |
| Redactar la retroalimentación | Escribe la general y las de correcto e incorrecto, en un paso | 35 |
| Mejorar la redacción | Ajusta el enunciado al nivel lector del curso | 20 |
| Generar una imagen sólo desde la barra del editor de texto | Crea la figura, el esquema o la ilustración descrita y la inserta donde está el cursor | 150 |
7.a El generador de preguntas pregunta sobre qué
Antes tomaba «algún OA del nivel de la prueba» sin preguntar. Eso servía para una demo y para nada más: lo primero que hace un profesor es decidir sobre qué quiere las preguntas. El formulario pide nivel y asignatura —con los de la evaluación puestos por defecto—, después el objetivo, y opcionalmente el indicador, además de cuántas, de qué tipo y con qué dificultad.
- Cambiar el nivel o la asignatura cambia el catálogo de OA que se ofrece, y el eje del objetivo elegido se muestra bajo el selector.
- Se puede pedir de otro nivel a propósito: un recuperativo mide objetivos del año anterior tan seguido como los del propio. Esas preguntas entran con su nivel y asignatura explícitos, para que se marquen como ajenas al revisarlas.
- Todo lo generado entra como borrador, igual que antes.
- La correcta no cae siempre en la A. Ver la caja de abajo.
Un generador que deja la respuesta en la primera alternativa produce pruebas con la clave AAAA…, y eso el alumno lo descubre antes que el profesor. Las alternativas se revuelven después de armarlas: el texto de cada una dice qué error representa, así que el orden da lo mismo salvo por esto.
En V/F no se revuelve —«Verdadero» va primero, siempre— pero sí se alterna cuál es la correcta: si no, todas las generadas se responden «verdadero», que es el mismo vicio con otra forma.
El reparto es determinista, no al azar: sale del número de pregunta, para que dos miradas a la misma prueba den lo mismo. Y no basta con que «varíe»: alternar B, D, B, D también varía y sigue siendo un patrón. Con cuatro alternativas, la correcta tiene que recorrer las cuatro letras.
Este es el generador del cajón, para agregar preguntas a una prueba que ya existe: pide un objetivo y agrega unas pocas. La tabla de §5.2 es el mismo motor pero al crear, con varias filas, su reparto por tipo y la posibilidad de traer del banco. Conviene que compartan el endpoint y el registro de consumo, y que se diferencien sólo en el formulario. El endpoint tiene que aceptar además el caso sin objetivo —la fila comodín de §5.2—, donde el objetivo lo elige y devuelve el servidor: la pregunta vuelve categorizada, no en blanco.
7.b El generador de imágenes
No se lista en el cajón de Herramientas de IA. Vive sólo en el botón 🎨 de la barra del editor de texto, al lado del de subir una imagen. El motivo es concreto: una imagen se inserta donde está el cursor, y desde un cajón lateral no hay cursor al que apuntar —terminaba cayendo al final del enunciado—. Igual sigue en el catálogo de herramientas por dentro, porque el precio y el registro de consumo tienen que salir de un solo lugar.
El formulario pide qué se tiene que ver, un estilo (esquema o diagrama, ilustración, línea de tiempo, gráfico de datos) y una proporción. Genera, muestra la vista previa, y recién ahí se inserta.
- Cobra al generar, no al insertar. Regenerar vuelve a cobrar, y eso tiene que estar claro antes: es la acción más cara del gadget.
- Siempre pide revisarla. La IA se equivoca en los rótulos y en las proporciones, y una figura mal rotulada en una prueba de geometría invalida la pregunta.
- La imagen queda en el enunciado con
data-ia="1"ydata-peticion, que guarda el texto con el que se pidió. En el editor lleva una marca IA; en el papel no: una estampa sobre la figura no le sirve de nada al alumno. Lo que hace auditable la imagen es el registro, no el sello. - Se acota a 330 px de ancho. A ancho completo una figura generada se come media hoja y empuja la pregunta a la página siguiente.
El límite se declara antes de generar, en el propio formulario: no produce armas ni explosivos, violencia explícita, contenido sexual, drogas, autolesiones ni marcas comerciales, y no reproduce personas reales identificables. Declararlo antes evita que el profesor gaste 150 tokens en algo que no va a salir.
El filtro del navegador no es el filtro. En la maqueta la revisión corre en el cliente porque no hay servidor, pero cualquiera abre la consola y la saltea. En el producto el control va en tres capas, y las tres son necesarias:
- En el cliente, sólo como aviso temprano y ahorro de tokens.
- En el servidor, antes de llamar al proveedor. Es la que manda. La
petición rechazada no se cobra y queda registrada en
ia_consumoconexito = 0. - La política del proveedor, que rechaza por su cuenta. Hay que traducir su error a un mensaje que diga qué corregir, no un «solicitud rechazada» que deja al profesor adivinando.
Las personas reales son un caso aparte y se trata como aviso, no como veto: «un retrato de O’Higgins» es material de aula perfectamente válido y sale como ilustración, no como retrato fiel; una persona viva identificable no se genera. Meterlo en la lista de veto habría bloqueado medio programa de Historia.
Falta definir con el negocio: quién responde si igual pasa algo inapropiado —¿se revisa antes de imprimir, se puede reportar una imagen, queda un registro que UTP pueda mirar?—. Y si el establecimiento puede apagar el generador de imágenes dejando el resto de la IA encendida.
- El costo se muestra antes de gastar, y si no alcanza se dice cuánto falta en vez de fallar con un error genérico.
- Todo lo generado por IA nace marcado como borrador y la prueba no queda completa mientras haya borradores sin revisar. Una prueba mal generada que llega al curso es un problema del colegio, no del proveedor.
- El consumo se guarda por usuario, prueba y herramienta. Sin eso no se puede responder «¿en qué se nos fueron los tokens este mes?».
- El descuento y la llamada al proveedor van en la misma transacción: si la llamada falla, no se cobra.
- La clave del proveedor no llega nunca al navegador. El front llama a
/evaluaciones/ia/{herramienta}y el servidor habla con el proveedor.
La bolsa es del colegio, y el WebClass manager la reparte
Decidido: una bolsa por establecimiento. El WebClass manager del colegio la divide entre sus profesores —es él quien sabe quién está armando pruebas este mes y quién no—, y cada profesor gasta contra su cupo, no contra el total. Así un profesor no se lleva la bolsa entera en marzo.
- Al profesor se le muestra su saldo, no el del colegio: es el número sobre el que puede decidir.
- Cuando se acaba, se le avisa que no le quedan créditos y quién se los puede ampliar. No se falla con un error genérico ni se le cobra al colegio por fuera.
- Lo que no cuesta tokens sigue funcionando igual: el banco de preguntas, la lectura de PDF y el OCR (§6.3.b). Quedarse sin créditos no deja al profesor sin generador de pruebas.
- El manager ve el consumo por persona y puede mover cupo de uno a otro dentro del período.
Tablas nuevas (las únicas del gadget)
ia_bolsa_tokens
id, colegio, tokens_asignados, tokens_consumidos,
periodo_inicio, periodo_fin, activo
ia_cupo_profesor <-- el reparto que hace el manager
id, bolsa, usuario, tokens_asignados, tokens_consumidos
UNIQUE (bolsa, usuario)
ia_consumo
id, colegio, usuario, prueba, pregunta (nullable),
herramienta, tokens, exito, mensaje_error, created_at
ia_cupo_profesor es tabla y no una columna en usuario porque
el reparto cambia cada período y hay que poder mirar el anterior: un cupo
guardado encima del usuario no tiene historia. La suma de
tokens_asignados de los cupos no puede pasar el de la bolsa, y esa
validación es del servidor.
- ¿Se renueva mensualmente, se acumula, o se compra? Cambia el modelo de datos: si se acumula, el saldo no puede vivir en el período.
- ¿Qué pasa con el cupo que un profesor no gastó al cerrar el período: vuelve a la bolsa o se pierde?
- ¿Qué proveedor de IA y con qué acuerdo de tratamiento de datos? Van enunciados de pruebas del colegio en cada llamada.
7.cDeshacer y borrador automático
El editor está lleno de acciones destructivas de un solo clic: quitar una pregunta, quitar un par, quitar la rúbrica, y sobre todo «Revolver B», que cambia la clave de un pareado que quizá ya se imprimió. Sin deshacer, cada una es un camino de ida.
- Se guarda el estado entero antes de cada cambio, hasta 50 pasos. Se puede porque el editor ya repinta toda la pantalla desde ese objeto: no hay nada que restaurar aparte de él. Es de las pocas veces en que lo más valioso es además lo más barato.
- Cada paso lleva nombre: el aviso dice «Deshecho: quitar la pregunta 6», no un genérico, y el botón lo adelanta en su tooltip.
- Escribir en un campo no deja un paso por tecla: se anota uno al entrar al campo.
- Dentro del editor de texto, Ctrl+Z es el del navegador —deshace lo que se escribió, que es lo que uno espera con el cursor puesto ahí—.
- Entrar al editor vacía la pila: si no, se podría «deshacer» hasta una prueba en blanco sin que se entienda por qué.
Cuarenta minutos escribiendo y un cierre del navegador se llevaba todo. El borrador no reemplaza a Guardar: cubre lo escrito entre dos guardados. Al volver, se ofrece; no se aplica solo, porque recuperar en silencio un borrador de ayer encima de lo que el profesor viene a hacer hoy es peor que perderlo.
- Guardar de verdad lo borra: dejarlo ahí confunde la próxima vez.
- Si no cabe —típicamente por imágenes subidas— se avisa una sola vez y se detiene. Repetirlo en cada cambio sería peor que el problema.
- En el producto esto es un borrador en el servidor, no en el navegador: así sobrevive a cambiar de computador.
Una trampa que costó encontrar, porque no da síntoma. Entrar al editor dispara un repintado, y ese repintado guardaba el estado recién abierto encima del borrador, antes de alcanzar a ofrecerlo: el modal aparecía igual, pero recuperaba lo que acababa de pisar. El borrador hay que leerlo antes de tocar nada, y no escribir ninguno mientras haya uno esperando respuesta. Y la lectura va en el embudo por el que pasan todos los caminos de entrada: uno solo que se lo saltee deja el borrador perdido sin que se note.
8Reglas y validaciones
- Una pregunta de selección múltiple tiene exactamente una alternativa correcta: marcar otra desmarca la anterior. En la variante de varias correctas, la letra alterna y los porcentajes tienen que sumar 100 %.
- El puntaje total se recalcula solo. El puntaje para el 4,0 no se calcula acá: depende de la exigencia, que se fija al asignar la prueba a un curso.
- Al guardar se avisa de: opciones repetidas, preguntas sin categorizar, sin respuesta correcta, y borradores de IA sin revisar. Se guarda igual — el profesor manda — pero la prueba queda marcada como incompleta y no entra al banco de items.
- Una prueba ya rendida por alumnos no se edita. Se duplica y se edita la
copia. Las tablas
respuesta_*_alumnoapuntan a la pregunta por id: editarla cambia retroactivamente lo que se le tomó al curso. - Todo contenido que vuelva al navegador se escapa. Los enunciados aceptan HTML acotado (negrita, cursiva, sub/superíndice, imágenes) y hay que filtrarlo con lista blanca, no confiar en el editor.
8.a Opciones repetidas funcionalidad nueva
Dos alternativas iguales no son un descuido de forma: cambian lo que la pregunta mide. Si la repetida es la correcta, la pregunta tiene dos correctas y se corrige mal —el alumno que marcó la otra pierde puntaje por una respuesta que era cierta—. Si es incorrecta, el alumno las descarta las dos de una sola vez y la pregunta mide menos de lo que dice medir.
Y no es un caso raro: pasa solo, copiando una alternativa para editarla y olvidándose de cambiarla. Nadie relee las cuatro opciones de las treinta preguntas antes de imprimir.
- Se avisa al guardar, diciendo qué pregunta y cuál es el texto repetido, con un botón que lleva a la primera.
- No bloquea. Puede haber un motivo —una prueba de atención, un formato heredado— y bloquear obligaría a discutir con el sistema. Lo que no puede pasar es que se imprima sin que nadie se haya dado cuenta.
Se compara el texto visible: sin etiquetas HTML, sin distinguir mayúsculas, con los espacios colapsados y sin el punto final. «Verdadero» y «verdadero.» son la misma opción para quien responde, y comparar el HTML crudo dejaría pasar justo el caso que importa —la alternativa copiada y reformateada—. Las vacías se ignoran: de esas ya reclama la clave.
Se mira en los tres lugares donde el alumno elige entre opciones, no sólo en las alternativas:
- Alternativas de selección múltiple, varias correctas y V/F.
- Columna B de términos pareados, incluidos los distractores: dos opciones iguales hacen que dos filas distintas tengan la misma respuesta válida, y el corrector sólo acepta una. También la columna A, donde dos términos iguales son directamente un error de redacción.
- Respuestas aceptadas de respuesta corta: una repetida no rompe nada, pero suele ser la señal de que se quiso escribir una variante y se pegó la misma.
9Fuera de alcance
- Rendición en línea y corrección automática (ya existen en el producto).
- El análisis de resultados posterior, aunque este gadget genere los datos que lo alimentan.
- Migrar las pruebas históricas: se trabaja sobre las mismas tablas, así que no hay migración.
- Rúbricas para preguntas de desarrollo. Aparecen mencionadas en la maqueta como pendiente explícito.
- Apagar el módulo viejo de vanilla. Conviven hasta que este pruebe estar completo.
- GeoGebra. Se evaluó y se descartó por licencia (§6.2.c): es gratis sólo para uso no comercial y esto vive dentro de un producto que se vende. No queda como opción ni como interruptor.
- El análisis del error por alternativa, que es el otro sentido de la palabra «distractor» y no existe en WebClass (§6.6). Lo que sí queda es la retroalimentación por alternativa, que es una columna real. El señuelo sin pareja de los términos pareados —el único «distractor» que el producto tiene— sí está en el alcance.
10Criterios de aceptación
- No se puede llegar al editor sin nivel y asignatura elegidos.
- Arrastrar una pregunta a otra posición renumera la prueba y el orden sobrevive a recargar la página.
- Una pregunta se puede arrastrar de una hoja a otra, y la prueba se repagina sola.
- Arrastrar una alternativa reasigna las letras y la respuesta correcta sigue siendo la misma alternativa, no la misma letra.
- El número de hojas del editor es igual al número de páginas del PDF, y el corte cae entre las mismas preguntas.
- Ninguna pregunta queda partida entre dos páginas.
- Cambiar el tipo de hoja o los márgenes vuelve a paginar en el momento, y el PDF sale en ese tamaño.
- Una fórmula insertada se puede volver a editar: al abrir el campo y hacerle clic dentro del editor reaparece su LaTeX original, no el HTML renderizado.
- Escribir en un enunciado no rompe una fórmula vecina: se selecciona y se borra entera.
- Las fórmulas salen bien en el PDF, no sólo en pantalla.
- El botón flotante de agregar está siempre visible sin scrollear, responde al clic en toda su superficie, agrega la pregunta, baja la vista hasta ella y abre el editor de texto en su enunciado.
- Cambiar la tipografía o el tamaño base repagina la prueba, y el PDF sale con esa letra.
- Una tabla insertada en un enunciado se imprime con sus bordes y no se parte entre dos páginas.
- Pegar una tabla de especificaciones copiada de Excel identifica sola las columnas, y un indicador con coma adentro no descuadra la fila.
- Las preguntas creadas desde la especificación llegan con su OA e indicador puestos, y esos valores siguen ahí al abrir la categorización aunque no estén en el catálogo.
- Un bloque de gráfico aparece en el PDF como imagen, no como un hueco en blanco.
- Un PDF de varias páginas se muestra y se puede navegar; dos recortes de páginas distintas se acumulan en una pregunta.
- Cada recorte de un PDF con texto entra como una pregunta distinta, en texto editable, con sus alternativas separadas y sus tablas como
<table>. - Una pregunta numerada sin separador —el número dentro de un círculo, que en la capa de texto es un
4suelto— se reconoce igual, y también cuando el número va solo en su línea. Un3 metros más que su alturano se confunde con una numeración. - Los recortes sin capa de texto se cuentan aparte y ofrecen reconocer el texto; lo reconocido entra como texto editable, marcado como borrador, y conserva el recorte original al lado.
- Reconocer el texto no descuenta tokens ni aparece en el consumo: no es una llamada a un proveedor de IA.
- Una tabla cuyas celdas ocupan varias líneas entra como
<table>con sus columnas correctas y cada celda entera —no aplanada como párrafo, ni con las tres columnas intercaladas—. - Una raíz, un exponente, un subíndice o una fracción apilada del PDF entran como fórmula reeditable: al hacerle clic dentro del editor reaparece su LaTeX.
- En
∛2⁷el exponente queda dentro de la raíz, y en2^{7/3}la fracción queda dentro del exponente. - Una frase con números no se convierte en fórmula.
- Una línea con varias fracciones apiladas entra con cada fracción entera y en su lugar —no con los numeradores y denominadores barajados—, y un párrafo de dos líneas no se convierte en fracción.
- Un PDF con la capa de texto ilegible se detecta, se dice por qué, y se ofrece reconocer el texto en vez de importar cuadraditos.
- Las rayas de una tabla no se importan como si fueran una figura: no aparecen recuadros vacíos montados sobre el texto.
- El recortador ocupa el 90% de la pantalla y trae un selector de zoom; recortar sigue cayendo donde corresponde en cualquier zoom.
- Un recorte con texto e imagen trae las dos cosas, y la imagen queda en el mismo lugar que ocupaba respecto del texto.
- La imagen importada llega sin el blanco sobrante alrededor.
- Un recorte sin capa de texto entra como imagen, y la pantalla lo dice antes y después de importar.
- El número de la pregunta del documento original no queda dentro del enunciado.
- Esa pregunta nace sin clave, muestra la etiqueta «sin clave», y Guardar se bloquea sin ofrecer «guardar igual».
- Marcada la clave, la etiqueta desaparece y Guardar deja de bloquearse por ese motivo.
- Cambiar el número de alternativas (2 a 6) conserva la clave si sigue existiendo esa letra.
- Al insertar una fórmula, tabla o gráfico, el contenido entra donde estaba el cursor: abrir el diálogo no puede perder el punto de inserción.
- Después de insertar un gráfico se puede seguir escribiendo debajo.
- Un ejemplo de jsxgraph.org pegado tal cual se reconoce como código y se dibuja, deslizadores y 3D incluidos; el bloque lo dice y la cabecera muestra cuántas líneas, no el código entero encima del dibujo.
- Un texto que no se entiende en el campo del gráfico avisa por qué y deja el motivo escrito en el bloque: no dibuja una cuadrícula vacía que parece correcta.
- En el modal del gráfico, la ayuda no se monta sobre el campo, ni siquiera después de estirarlo.
- El diálogo se llama «Digitalizar desde un archivo» y acepta PDF y
.docx; el reconocimiento de preguntas y alternativas es el mismo para los dos. - Un
.docxse lee sin internet y sin librería, con sus imágenes puestas en la pregunta que las contiene. - Las tablas de Word entran como una línea por fila sin perder datos, y el resumen avisa que hay que rehacerlas.
- Un
.docantiguo dice qué hacer —guardarlo como .docx—, no «formato no soportado». - Un Word sin texto manda a recortar a mano, no ofrece OCR: el OCR es para escaneos.
- Una imagen del enunciado se puede recortar desde su propio marco: se arrastra un rectángulo, lo de afuera se oscurece y se dice qué porcentaje se va a ver.
- Lo que queda es exactamente la parte marcada, en el tamaño del recorte y no en el de la imagen entera.
- El original se conserva y «Quitar el recorte» lo devuelve entero; recortar dos veces seguidas no pierde el archivo de partida.
- Descargar con cambios sin guardar no descarga: explica por qué y ofrece guardar y descargar en un paso.
- La tabla de especificaciones cuadra: la suma de puntos por indicador es el puntaje total, y las sin categorizar aparecen en su propia fila.
- Al cambiar el OA de una pregunta, el indicador queda vacío y sólo ofrece los del OA nuevo.
- El eje aparece sobre el objetivo y lo filtra; elegir un objetivo completa el eje solo.
- Una pregunta puede categorizarse con un objetivo de otro nivel o asignatura, y la pantalla lo advierte.
- Cambiar el nivel o la asignatura de la pregunta limpia eje, objetivo e indicador y lo avisa.
- Una pregunta admite varios objetivos, cada uno con su propio nivel y asignatura, y el carril los muestra todos.
- Un objetivo agregado sobre otro nivel ofrece el catálogo de ese nivel y se marca como ajeno.
- La dificultad y el puntaje aparecen una sola vez, fuera de las tarjetas de objetivo.
- El puntaje de una pregunta con dos objetivos se reparte entre ellos: la tabla de especificaciones sigue sumando 100 %.
- Una pregunta con un objetivo completo y otro a medias sigue contando como categorizada.
- Si los tipos no suman las preguntas que va a generar la IA, se dice cuántas faltan o sobran y Crear queda deshabilitado; «Repartir automáticamente» lo resuelve.
- Cada fila entrega la cantidad pedida de preguntas, con su objetivo o su habilidad puesta.
- Marcar crear imágenes suma su costo al total antes de generar, y las preguntas generadas llegan con imagen.
- En una prueba generada, la respuesta correcta recorre las cuatro letras: ni todas en la A, ni alternando entre dos.
- Las de V/F generadas no se responden todas «Verdadero».
- Cada pregunta del banco o generada muestra los dos pulgares en su carril; una escrita a mano no los muestra.
- Volver a apretar el mismo pulgar retira la opinión.
- El pulgar abajo ofrece el reemplazo del mismo origen: del banco si vino del banco, generada si la generó la IA — y siempre deja dejarla como está.
- El reemplazo conserva puntaje y posición, y no cambia cuántas preguntas tiene la prueba.
- La del banco que se ofrece no está ya en la prueba.
- Una pregunta generada que se descarta se guarda igual, marcada como tal: la opinión sobre ella no se pierde al reemplazarla.
- Al guardar no se cuentan las opiniones ni se pide nada por ellas: el profesor ya vio el pulgar que apretó.
- Una línea con las cuatro alternativas juntas (
A) 2 B) 4 C) 6 D) 8) entra como cuatro alternativas, no como una. - Alternativas en dos columnas —A y C arriba, B y D abajo— entran en orden A–D.
A.2, sin espacio tras el punto, entra como alternativa; «El vértice A. Se ubica…» y «a) y b) son paralelas» no.- Si a las alternativas les falta una letra, se dejan en el orden del documento en vez de reordenarse a medias.
- El pie que se repite en todas las páginas no queda pegado al final de ninguna alternativa.
- Las instrucciones numeradas de la portada no entran como preguntas, y las preguntas 1 a 5 de verdad sí.
- Dos celdas de una tabla, o dos alternativas consecutivas, no se unen en una fracción; una fracción de verdad sí se reconoce.
- Una alternativa con signos matemáticos —
A) 56 ÷ 0 = 56— sigue siendo una alternativa, no parte del enunciado. - La prosa que sigue a una fórmula no queda dentro de ella.
- Una prueba con los ejercicios pegados como imagen entrega todas sus preguntas, cada una con su imagen y la clave para marcar.
- El resumen distingue las que traen su texto de las pegadas como imagen, y explica por qué.
- Se ofrece OCR también en el camino del PDF completo; lo reconocido entra como borrador y conserva la imagen original.
- El detector de pies repetidos no elimina números de pregunta aunque caigan en la banda del borde.
- Un recorte de un plano o cuadrícula con rótulos adentro entra como una sola imagen con sus rótulos dentro, no como palabras sueltas.
- Un párrafo enmarcado y una tabla reconocida no se convierten en imagen: siguen siendo editables.
- Un subrayado o la raya para responder no disparan la detección de dibujo.
- Cada recorte ofrece «Como texto» / «Como imagen» en el panel de revisión, y lo elegido manda sobre lo detectado.
- Un recorte marcado como imagen deja de aparecer en la oferta de OCR.
- Hay cuatro caminos de creación: no existe ya uno para «con ayuda de la IA» aparte de la tabla de especificaciones.
- Los caminos van en filas agrupadas en dos bloques —«empezar a escribir» y «partir del currículo»—, sin iconos y sin fondo de color; los dos que consumen tokens lo dicen.
- «A partir de tabla de especificaciones» y «a partir de la situación del curso» abren una pantalla propia —no un panel bajo las filas, y no el editor—, con su miga de pan y un Volver.
- La tabla tiene dos pestañas, Objetivos y Habilidades; cambiar de una a otra no borra lo pedido en la otra, y cada rótulo lleva la cuenta de lo pedido ahí.
- La fila «Cualquiera del nivel» va primera en Objetivos y no aparece en Habilidades; ofrece el banco del nivel entero, no entra en las cuentas del currículo y «Proponer» no la llena.
- Lo pedido en esa fila llega con un objetivo distinto por pregunta, tomado del catálogo del nivel: ninguna entra sin categorizar, y el enunciado dice que el objetivo lo eligió la plataforma.
- «Proponer» no borra lo pedido a mano en el comodín ni en los objetivos propios.
- Los objetivos propios del colegio aparecen después del currículo, con su logro en el camino del curso, sin entrar en las cuentas del nivel. Agregar uno casi igual a uno existente usa el existente y lo avisa.
- En el cajón, «+ Objetivo propio» agrega una tarjeta de tipo y texto, sin nivel, eje ni indicador, que ofrece los que el colegio ya usa. Un texto que sólo difiere en mayúsculas, tildes, espacios o punto final queda escrito como el existente.
- Una pregunta con sólo un objetivo propio de tipo objetivo cuenta como categorizada; en la tabla de especificaciones es una fila que se lleva su parte del puntaje, y los puntos siguen sumando el total. Las habilidades y actitudes propias van aparte, sin puntaje.
- La valoración elegida se ve de lejos: amarillo el pulgar arriba, rojo el pulgar abajo, el otro apagado, y el rótulo dice en palabras lo mismo que el color.
- Un texto compartido se imprime una sola vez, antes de sus preguntas, con el rótulo «responde las preguntas N a M» armado solo.
- Las preguntas de un recurso quedan siempre contiguas y detrás de él: meter una la mueve a ella junto al bloque, no mueve el bloque hacia ella.
- El rótulo del rango se actualiza al agregar, sacar o reordenar preguntas.
- Al paginar, el recurso no queda separado de su primera pregunta por un salto de hoja.
- Separar el recurso deja las preguntas y borra el texto, avisando antes; borrar la última pregunta de un recurso avisa que el texto se va con ella.
- La prueba guardada deja el bloque declarado, para que quien la baraje al asignarla baraje bloques y nunca deje una pregunta antes de su recurso.
- Elegido un curso, se avisa cuántos de sus alumnos están en el PIE, separando permanentes de transitorias, y cada diagnóstico trae su adecuación.
- Los alumnos del PIE van marcados en el listado de búsqueda y en su ficha una vez elegidos.
- Con alumnos elegidos el aviso habla de ellos; si ninguno es del PIE lo dice, sin dejar de recordar que el curso sí tiene.
- Un curso sin alumnos PIE también lo dice: el silencio se lee como «no se comprobó».
- Proponer rehace sólo la pestaña que se está mirando.
- Hay un reparto por tipo de pregunta; la cuenta que tiene que calzar es la de las generadas por IA, no el total, y se rehace sola al cambiar las cantidades.
- Las preguntas creadas respetan el reparto por tipo y salen intercaladas.
- El Excel de UTP se importa desde esta pantalla y llena la tabla; lo que no calza con el catálogo del nivel se dice, no se descarta en silencio.
- Sin curso, la tabla no muestra las columnas de logro ni el selector de curso, y queda en el orden del currículo.
- Con curso, sólo se ofrecen los cursos del nivel elegido arriba.
- Cada pantalla muestra su propio título: la tabla de especificaciones no se anuncia como «la situación del curso».
- Un clic sobre las casillas del alumno en la hoja abre el modal que las configura.
- Se puede ocultar una casilla sin perderla, agregar una del catálogo de WebClass, crear una propia con el nombre que sea y reordenarlas arrastrando.
- Las de WebClass se marcan como tales y no se pueden borrar, sólo ocultar; las propias sí.
- Con más de tres casillas visibles la ficha pasa a dos filas.
- Deshacer devuelve una casilla borrada.
- Elegir uno o varios alumnos cambia el logro de la tabla al de ellos, y el título y las migas dicen de quién es.
- El campo de alumnos ofrece el curso completo, filtra al escribir ignorando las tildes, agrega con Enter y quita la última ficha con Retroceso.
- Un alumno descendido muestra más objetivos bajos que el promedio de su curso; volver a «Todo el curso» restituye la tabla.
- Cambiar de curso limpia los alumnos elegidos: son de otro curso.
- En la tabla de especificaciones se puede cambiar de nivel y de asignatura, y lo ya pedido no se pierde: se acumula y se ve en el resumen, con lo de otro nivel marcado.
- Una prueba con filas de dos niveles trae preguntas del banco de cada nivel, y las del nivel ajeno llegan marcadas como tales.
- La cantidad se ajusta con botones −/+, y el origen con dos botones donde el del banco muestra cuántos items tiene.
- El pie queda fijo abajo: el total y el botón de crear se ven sin llegar al final de la tabla.
- La tabla trae todos los objetivos del nivel, no sólo los ya evaluados, y los nunca evaluados van primero y dicen «Nunca», no 0%.
- El selector de origen muestra cuántos items tiene el banco de ese objetivo, y queda deshabilitado cuando tiene cero.
- Pedir del banco más de las que hay se dice en la fila y se completa con IA; el costo cuenta sólo las de IA.
- Proponer no pide preguntas de los objetivos ya logrados.
- Cambiar de curso cambia el catálogo de objetivos y reinicia lo pedido; si el curso es de otro nivel, se avisa que manda el del curso.
- Lo traído del banco entra listo y lo generado como borrador, y todo llega categorizado.
- Guardar con dos alternativas iguales avisa, dice qué pregunta y qué texto, ofrece ir a ella y deja guardar igual.
- Ese aviso ignora mayúsculas, etiquetas, espacios de más y el punto final, y no se dispara con las alternativas vacías.
- También avisa de la columna B repetida en términos pareados —distractores incluidos— y de las respuestas aceptadas repetidas.
- El banco ya no tiene búsqueda por texto del enunciado: se filtra por eje, objetivo, indicador y habilidad.
- Cada opción del filtro dice cuántos items tiene detrás, y ninguna lleva a cero resultados.
- Elegir un eje acota los objetivos y elegir un objetivo acota los indicadores; cambiar el de arriba suelta los de abajo.
- Una acción de IA descuenta exactamente lo que anunció, y si el proveedor falla no descuenta nada.
- Con tokens insuficientes se explica cuántos faltan; no hay error genérico.
- El profesor gasta contra su cupo, no contra el total del colegio, y el saldo que se le muestra es el suyo.
- Al agotarse el cupo se le dice que no le quedan créditos y quién se los amplía; lo que no cuesta tokens —banco, lectura de PDF, OCR— sigue funcionando.
- La suma de los cupos repartidos no puede pasar la bolsa del colegio, y esa validación es del servidor.
- Guardar con preguntas sin categorizar avisa qué falta, guarda igual y deja la prueba fuera del banco.
- Cada forma generada trae su propia pauta, y la pauta de la forma A es la del orden original.
- Intentar editar una prueba ya rendida ofrece duplicarla en vez de permitir el cambio.
- El menú de agregar ofrece los siete tipos de WebClass, y cada uno se crea con un ejemplo utilizable, no vacío.
- En varias correctas: marcar una segunda alternativa reparte 100 % entre las marcadas; dejar la suma en otro valor avisa bajo la pregunta y bloquea Guardar diciendo cuánto suma.
- Escribir un porcentaje mayor que cero marca sola la alternativa como correcta, y bajarlo a cero la desmarca.
- La pauta de una pregunta de varias correctas es un grupo de letras; la de pareados no es una letra; la de desarrollo y respuesta corta es un guión.
- En pareados: la columna B se imprime revuelta, la clave se calcula sola y no cambia entre repintados; «Revolver B» la cambia y la clave se actualiza.
- Agregar o quitar un par renumera la columna A y vuelve a revolver la B.
- Un par con una columna vacía bloquea Guardar.
- «+ distractor» agrega a la columna B una opción sin fila en la A: la B queda más larga que la A y las letras siguen correlativas.
- El señuelo se revuelve junto con los pares —no queda fijo al final— y la clave de pantalla lo lista aparte como «sin pareja».
- En el papel el señuelo es indistinguible de las demás opciones de la B: no se imprime su rótulo ni su botón de quitar.
- Un señuelo sin texto bloquea Guardar; quitarlo no toca la columna A ni el puntaje de la pregunta.
- En respuesta corta: se pueden agregar varias respuestas aceptadas con su porcentaje, y sin ninguna Guardar se bloquea.
- Una pregunta de desarrollo nace con rúbrica: tres niveles de logro y criterios con descriptores, y cada celda muestra cuántos puntos vale.
- La rúbrica no se dibuja sobre la hoja: es una opción del carril lateral que sólo aparece en las preguntas de desarrollo, y al pincharla se abre en un modal ancho.
- Si los criterios no suman el puntaje de la pregunta, el modal lo dice, el carril muestra «rúbrica no suma» sin cerrar el modal, y Guardar se bloquea indicando cuánto suma. Un criterio sin nombre o una celda sin descriptor también lo bloquean.
- Cambiar el puntaje de un criterio o el % de un nivel recalcula las celdas en el momento.
- Un nivel nuevo entra antes del último, y todas las filas ganan su celda; quitarlo se la saca a todas.
- Al descargar Para el estudiante la hoja sale sin rúbrica; en la Pauta de corrección aparece bajo cada pregunta de desarrollo como una tabla sin campos ni botones, y al terminar la hoja vuelve a quedar limpia.
- La rúbrica se puede quitar y volver a poner desde el modal, sin tocar el puntaje de la pregunta, y la marca del carril pierde y recupera su ✓.
- El generador de imágenes declara su límite antes de generar, rechaza una petición fuera de ese límite sin cobrar tokens y diciendo cuál fue el motivo.
- Una petición válida cobra los tokens una sola vez, deja el consumo registrado, muestra la vista previa y pide revisarla antes de insertar.
- La imagen insertada conserva el texto con que se pidió (
data-peticion), lleva marca IA en el editor y no en el papel. - Desde la barra del editor, la imagen se inserta donde está el cursor.
- El aviso de Guardar dice qué le falta a cada pregunta, no un texto genérico igual para todas.
- La pantalla de creación muestra el título de la herramienta y, bajo él, el nombre del recurso con su etiqueta «Nombre:»; hacer clic en la etiqueta enfoca el campo.
- La barra del editor ocupa una sola línea: pestañas, Opciones y Herramientas de IA al mismo nivel, sin segunda fila de menú.
- Las cuatro opciones del encabezado se configuran dentro de Opciones, y cada cambio se ve en la hoja al instante.
- El encabezado de la hoja no trae QR, y la insignia va a la izquierda con el título centrado respecto de la hoja.
- La línea de datos bajo el título viene apagada; el interruptor de Opciones la enciende y muestra asignatura, nivel, tipo, cuántas preguntas y el puntaje total, una sola vez y en la primera hoja.
- Esa línea se arma sola: agregar una pregunta cambia la cuenta y el puntaje, y cambiar la asignatura en Opciones la actualiza. No se escribe a mano.
- Encenderla y apagarla es un cambio como cualquier otro: deshacer la repone.
- Activar la casilla de fecha pasa la ficha a dos filas y corre los rótulos al costado izquierdo.
- Las instrucciones se editan sobre la hoja y vacías no se imprimen, pero siguen siendo clickeables en el editor.
- El nombre de la evaluación se edita sobre el título de la hoja, la miga de pan lo sigue, y no hay campo de nombre en la barra.
- Un clic sobre el enunciado, sobre una alternativa o sobre las instrucciones abre el editor en un modal, con la barra de formato fija arriba del área de escritura, y el título dice qué se está editando.
- Aplicar vuelca el texto a la hoja y repagina; Cancelar y Esc lo descartan; clic fuera equivale a Aplicar.
- Con el editor abierto, Esc sobre un modal de fórmula, tabla o gráfico cierra sólo ese y devuelve al texto sin perderlo.
- Los campos de una sola línea (nombre de la prueba, pares, respuestas aceptadas) se siguen escribiendo sobre la hoja, sin modal y sin barra.
- Los cuatro botones de alineación actúan sobre la fila del cursor: alinear una no mueve a las demás, y el botón correspondiente queda hundido.
- Una imagen del texto se alinea a izquierda, centro o derecha, y se mueve de verdad dentro de su fila. Con el cursor en un párrafo, alinear ese párrafo no mueve la imagen.
- Se puede deshacer y rehacer con Ctrl+Z / Ctrl+Y, y el aviso dice qué se deshizo. Incluye «Revolver B», quitar una pregunta y quitar la rúbrica.
- Una pregunta se puede duplicar —la copia entra justo debajo y con ids propios: marcar una correcta en ella no toca al original— y eliminar, con confirmación.
- El borrador se guarda solo, se ofrece al volver con su fecha y su número de preguntas, y Guardar lo limpia.
- Las preguntas, alternativas y pares se reordenan con el teclado desde su asa (flechas arriba/abajo), y una imagen se redimensiona con las flechas izquierda/derecha.
- El banco filtra por nivel, asignatura, tipo y dificultad, busca por texto, muestra % de logro y las preguntas llegan ya categorizadas.
- El generador de preguntas pide nivel, asignatura y OA, con los de la evaluación por defecto, y el catálogo de objetivos cambia al cambiar el nivel.
- La tabla de especificaciones se descarga como planilla, con una fila por pregunta, y se abre en Excel en español sin quedar toda en una columna.
- Un PDF escaneado ofrece reconocer el texto además de recortar a mano, no descuenta tokens —el OCR es Tesseract, no un proveedor que cobre por uso—, y lo reconocido entra marcado como borrador.
- Una pregunta cuyas alternativas son dibujos entra como selección múltiple con cuatro imágenes, una por alternativa, con sus letras en orden y sin la figura entera duplicada. Se avisa en la lista previa.
- Cada recorte llega sin el rótulo dibujado —la alternativa no puede decir «A)» dos veces— y ajustado a su dibujo, no al alto de la banda completa.
- Una figura suelta no se parte en alternativas: si un trozo se lleva más de la mitad del ancho, o los blancos que separan apenas rozan el umbral, la pregunta sigue entrando con su figura entera.
- El ensayo SIMCE de referencia entra completo: 40 de 40 preguntas con sus 4 alternativas.
- La barra ofrece los dos caminos por separado: subir una imagen y generarla con IA.
- Una imagen de 2000 px entra achicada a 1400, con la proporción intacta, y el aviso dice cuánto se achicó y cuánto pesa.
- Un PNG sigue siendo PNG después de achicarse: no se le pone fondo blanco.
- La imagen subida se redimensiona y se alinea igual que la generada.
- Una imagen del texto se selecciona con un clic y muestra cuatro tiradores; arrastrando cualquier esquina cambia de tamaño manteniendo la proporción, con la medida a la vista.
- El ancho máximo al que se puede estirar es el de la columna de la hoja, no el del modal: el tamaño que se ve al dimensionar es exactamente el que sale impreso.
- No baja de 60 px ni pasa del ancho de la columna, y el tamaño sobrevive al Aplicar y sale igual en el PDF.
- Con la imagen seleccionada, los botones de alineación la mueven y los de formato de texto quedan desactivados.
- El HTML guardado no contiene ni el marco, ni los tiradores, ni la marca de selección.
- Una fórmula sigue siendo reeditable: al abrir el campo y hacerle clic dentro del editor, reaparece su LaTeX original.
- Elegir un camino de creación entra al editor sin botón «Crear»; sin nivel o asignatura avisa cuál falta.
- La pestaña Retroalimentación ofrece los cuatro textos de la pregunta, y el de parcial aparece sólo en los tipos que reparten puntaje.
- En verdadero o falso aparecen además los dos textos de V y de F.
- En Retroalimentación todas las alternativas tienen campo, incluida la correcta.
- La palabra «distractor» aparece sólo en el botón de los términos pareados —su único sentido en WebClass— y en ningún otro lugar de la interfaz.
- El editor no tiene pestaña General ni Formas, ni interruptor de «marcar respuesta correcta», ni icono de usuario. Nivel, asignatura y tipo viven en Opciones.
- Cambiar el nivel o la asignatura desde Opciones no borra ninguna categorización, y avisa cuántas preguntas quedaron con objetivos ajenos; volver al valor original apaga el aviso.
- Cambiar el tipo de evaluación no toca la categorización.
- El editor no pide ni muestra la exigencia, y el resumen dice que el puntaje del 4,0 se define al asignar la prueba a un curso.
- Descargar pregunta si el archivo lleva la clave; «para el estudiante» viene preseleccionado y el editor queda con las marcas después de generar el PDF.
11Qué hay que confirmar antes de programar
Esta lista se acorta leyendo el código del producto, no preguntando. Varios puntos
que estuvieron acá ya se cerraron así —el porcentaje por alternativa,
la fórmula del logro, las columnas de pregunta_atributo— y
quedaron escritos en su sección. Lo que sigue acá es lo que de
verdad no se puede resolver mirando: decisiones de negocio, y datos que sólo
están en la base en producción.
- Si se aprueba la rúbrica por pregunta funcionalidad nueva
— es lo único de este documento que no existe hoy
(§6.4). Si entra, hay que decidir tres cosas:
- ¿La rúbrica de una pregunta se puede guardar en el banco de
Rúbricas de aprendizaje para reutilizarla en otra prueba, o vive
sólo dentro de la evaluación? El modelo propuesto lo permite con
poner
id_preguntaenNULL. - ¿Es obligatoria en toda pregunta de desarrollo, o se puede quitar? La maqueta la crea sola y deja quitarla: la nota la pone el profesor, no el sistema.
- ¿La justificación de una V/F con justificación merece lo mismo? También se corrige a mano y tiene puntaje propio.
- ¿La rúbrica de una pregunta se puede guardar en el banco de
Rúbricas de aprendizaje para reutilizarla en otra prueba, o vive
sólo dentro de la evaluación? El modelo propuesto lo permite con
poner
- El logro por objetivo: sólo falta si cuentan las pruebas no
validadas. La fórmula está resuelta —es
EvaluacionDao::getPuntajePorAtributo, transcrita abajo— y la ventana de tiempo también: el año en curso solamente, decidido por WebClass el 23-09. Un objetivo medido hace dos años, con otra composición de curso, no dice lo mismo. Queda sólo:- ¿Cuentan las pruebas no validadas y los ensayos, o sólo las calificadas?
Conviene además reusar la consulta del informe de aprendizaje en vez de escribir otra: dos cálculos del mismo número terminan dando distinto, y el profesor va a comparar las dos pantallas.La fórmula del logro, tal cual está en el productoCASE WHEN r.puntaje >= tp.puntaje THEN 1 WHEN r.puntaje < tp.puntaje AND r.puntaje > 0 THEN r.puntaje / tp.puntaje ELSE 0 END FROM resultados r JOIN test_pregunta tp ON tp.test = r.test AND tp.pregunta = r.pregunta JOIN pregunta_atributo pa ON pa.pregunta = tp.pregunta WHERE pa.atributo = ?Dos cosas quedan respondidas de paso. El puntaje parcial ya existe: si el alumno obtuvo menos que el máximo, cuenta la fracción
r.puntaje / tp.puntaje. Y una pregunta con dos objetivos cuenta entera en cada uno —elJOINconpregunta_atributoproduce una fila por atributo y cada una se lleva la fracción completa—, que es justo lo que este documento suponía correcto. Ya no hay que decidirlo: está decidido. Y el puntaje parcial de los términos pareados también es real:DatosTestDaoacumula por cada par acertado, así querespuesta_enpareja_vinculo.puntajesí se usa —otra pregunta que este documento tenía abierta y ya no—.Hay una segunda versión de la misma consulta que usa
pregunta_atributo_adicionalen vez depregunta_atributo: los objetivos propios del profesor también cuentan para el logro. Ver abajo. - El nivel del objetivo hay que agregarlo: hoy
pregunta_atributono lo tiene. Ya no es una pregunta, es un hecho verificado en el código del producto:
Cuatro columnas, sin nivel. El nivel se deduce de la prueba (INSERT INTO pregunta_atributo (pregunta, eje, tipo, atributo)prueba.sector→sector.nivel). Con varios objetivos por pregunta y de niveles distintos (§6.5.b) esa deducción deja de ser posible, así que la categorización múltiple es un cambio de modelo y no sólo de pantalla. Lo que falta decidir es cómo: una columnanivelenpregunta_atributo, o que el catálogo al que apuntaatributoya lo traiga. - El objetivo propio del profesor:
pregunta_atributo_adicional(id,pregunta_id,tipo,caracteristica). Es el mecanismo con el que hoy se le pone a una pregunta un objetivo que no está en el catálogo:caracteristicaes texto libre. Lo confirmó WebClass, y en el código se ve que cuenta para el logro igual que un objetivo del catálogo, y que se copia al duplicar una pregunta.
Ya está incorporado, en la maqueta y en el documento: el cajón deja agregar un objetivo propio (§6.5.c) y la tabla de creación los muestra como filas (§5.2). Quedan dos cosas que el código no responde:- De dónde sale la lista de «ya usados»: de las preguntas del colegio, de las del profesor, o de todo WebClass. Es la misma pregunta que el banco de items (abajo), y conviene contestarlas juntas. La maqueta supone el colegio.
- Si los tipos 1 y 2 —contenidos mínimos y aprendizajes
esperados, del currículo anterior— se siguen usando en objetivos propios.
La maqueta ofrece sólo 3, 4 y 7. Un
select tipo, count(*) from pregunta_atributo_adicional group by tipolo responde.
- Si se habilita el tipo de varias correctas sin tocar el corrector. La corrección queda fuera del alcance de este gadget —decidido: el gadget crea preguntas y la aplicación sigue el camino actual de WebClass—, pero eso obliga a mirar qué hace ese camino hoy: lee el porcentaje como bandera y entrega el puntaje completo a quien marque cualquier alternativa con fracción mayor que cero (§6.3.a). Una pregunta 50/50 daría 100% por la mitad de la respuesta. O se ajusta el corrector, o no se habilita el tipo: publicarlo así es entregar notas mal calculadas en silencio.
- La tolerancia de la respuesta corta: mayúsculas, tildes, espacios sobrantes y coma vs. punto decimal. Sin una regla escrita, el mismo alumno con la misma respuesta acierta o falla según cómo la escriba. Es la única pregunta de corrección que queda.
- Si algún tipo está en desuso en la base de producción. Un
select tipo, count(*) from pregunta group by tipolo responde, y evita construir pantalla para algo que nadie usa hace diez años. - Cómo se generan los PDF con fórmulas: navegador headless o render de fórmulas a imagen desde el servidor (§6.2). Es la decisión técnica más cara de revertir de todo el gadget.
- Las plantillas de
home/importarpreguntasdel repo vanilla, antes de inventar un formato de Excel nuevo. - Las tres preguntas de tokens que quedan abiertas en el §7: renovación o compra de la bolsa, qué pasa con el cupo no gastado, y el proveedor de IA con su acuerdo de tratamiento de datos. La bolsa ya se definió: es por colegio y la reparte el WebClass manager.
- Si el banco de items es por establecimiento, por sostenedor o compartido con WebClass.
- Dónde se guarda el TEXTO de un recurso compartido
(§6.4.b). Verificado en el código del producto:
pregunta.idrecursoapunta aarchivo, o sea sirve para una imagen; para un texto falta dónde ponerlo. Hay dos salidas propuestas, y la decisión es de arquitectura. No guardarlo como archivo ni como imagen del texto. - Barajar por bloques: hay que escribirlo, no existe. Se buscó
expresamente y en los dos lugares que rinden una prueba el barajado es plano:
- Web —
AlumnoTestDao::getPreguntasPorIdTest: conbarajarencendido la consulta termina enORDER BY rand(), sin agrupar por nada. - App móvil —
MobileApp/Evaluations/EvaluationsController:$preguntas->shuffle(), también plano.
idrecurso. Hay que agrupar por recurso antes de revolver —revolver los grupos entre sí y las preguntas dentro de cada grupo— en los dos. Son pocas líneas, pero sin eso la funcionalidad no sirve: con el barajado encendido el texto queda separado de sus preguntas, que es justo lo que viene a resolver.
Si existe un tercer lugar que rinda pruebas y no esté en los repos que se revisaron, hay que mirarlo también. - Web —
- Dónde vive la nómina PIE y cómo se relaciona con
curso, y si el diagnóstico está codificado o es texto libre (§5.3). Es lo único que queda de este tema: mostrar los nombres ya está aprobado y las adecuaciones también, las dos cosas el 23-09. - Dónde se guardan las imágenes y su recorte (§6.2): el recorte tiene que viajar como cuatro números junto a la URL, no como una imagen nueva, para poder cambiarlo después y para que dos preguntas usen dos recortes del mismo archivo. Va con la pregunta ya abierta de dónde viven los archivos (§6.2).
La maqueta es HTML autónomo, sin build ni CDN, y no guarda nada: al recargar vuelve al estado inicial. Los datos son de ejemplo. Sirve para acordar el comportamiento — el arrastre, la paginación, el editor de fórmulas, el carril de categorización — no como código a copiar: está escrita en JavaScript plano y el producto usa Vue 2.
Dos cosas de la maqueta que no hay que replicar: el renderizador de LaTeX es
un subconjunto escrito a mano para poder mostrar el flujo sin depender de un CDN
(en producción va KaTeX), y la barra de formato usa
document.execCommand, que está obsoleto — en producción
lo reemplaza el editor que ya viene con el producto.
Atajos para mostrarla en una reunión, agregados a la URL:
?editor=1 entra directo al editor con la prueba de ejemplo cargada,
?crear=tabla abre ese camino con la tabla ya analizada, y
?tokens=0 arranca sin créditos de IA, para poder enseñar
qué ve el profesor cuando se le acaba el cupo sin tener que gastar 1.250 tokens
de mentira de a 20.