ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
Simulador educativo independiente de evaluaciones de Matemática, estilo Pruebas Aprender, para estudiantes de 6.º año. Instituto Arte Nuevo.
Translation pending
EducationTypeScript · PLpgSQLGitHub @NovaSystems32OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Simulador educativo independiente de evaluaciones de Matemática, con formato similar al de las
Pruebas Aprender, para estudiantes de 6.º año de la escuela secundaria de Argentina. Identidad
visual del Instituto Arte Nuevo (logo en public/images/logo-arte-nuevo.png, tokens de color en
src/app/globals.css).
Simulador educativo independiente del Instituto Arte Nuevo. No pertenece ni representa a organismos gubernamentales. Todas las actividades son originales.
Este proyecto es una versión completamente independiente de Simulador_Aprender (Instituto
Santiago Ramón y Cajal): mismo código, componentes, diseño y funcionalidades, pero con una base de
datos nueva y vacía, repositorio propio e identidad visual propia. No comparte datos, usuarios,
proyecto de Firebase ni proyecto de Neon con el original (que además usaba Supabase, no Firebase).
react-katex) para fórmulas matemáticas@react-pdf/renderer y exceljs para informes en PDF/ExcelLa autenticación y los datos viven en dos sistemas distintos:
uid de cada usuario es el único dato
que la app lee de Firebase.db/migrations/. perfiles.id guarda el mismo uid que el usuario en Firebase
Auth — una columna text (los uid de Firebase no tienen formato UUID), sin FK entre
sistemas (no es posible cruzando bases distintas).src/app/login/actions.ts) verifica el usuario/contraseña contra la API
REST de Firebase (src/lib/firebase/rest.ts) y cambia el token de corta duración por una
cookie de sesión de Firebase (src/lib/firebase/session.ts, httpOnly, hasta 14 días). El
middleware (src/proxy.ts) y src/lib/auth.ts verifican esa cookie contra el SDK de
administrador de Firebase (src/lib/firebase/admin.ts) en cada request.auth.uid() fuera de Supabase/Firebase, las políticas usan
current_setting('app.usuario_id', true) — una variable de sesión que src/lib/db/contexto.ts
fija con SET LOCAL en cada transacción, con el uid ya verificado. El rol de runtime
(app_runtime2, ver db/migrations/0002_rol_runtime.sql) está sujeto a esas políticas; el rol
administrador de Neon solo se usa para migraciones y el alta del primer admin.No hay trigger de alta de usuario entre sistemas: cuando un admin/docente crea un usuario, la app
primero lo crea en Firebase Auth y recién después inserta su perfil en Neon
(src/lib/db/usuarios.ts), revirtiendo el alta en Auth si el segundo paso falla.
Requisitos: Node.js 20+, una cuenta gratuita de Firebase (Google) y un proyecto en neon.tech.
npm install
https://tu-dominio/recuperar-contrasena/nueva-clave (en desarrollo,
http://localhost:3000/recuperar-contrasena/nueva-clave). Sin este paso, el enlace del correo
de "olvidé mi contraseña" lleva a una página genérica de Firebase en vez de la propia del
simulador.NEXT_PUBLIC_FIREBASE_API_KEY en .env.local..env.local:
project_id → FIREBASE_PROJECT_IDclient_email → FIREBASE_CLIENT_EMAILprivate_key → FIREBASE_PRIVATE_KEY (pegalo tal cual, con los \n literales)Copiá .env.example a .env.local (cp .env.example .env.local) antes de completar estos
valores.
Creá un proyecto nuevo en neon.tech.
Copiá el connection string del rol por defecto (el "owner" del proyecto) a
DATABASE_URL_ADMIN en .env.local.
Corré las migraciones (crean toda la estructura: tablas, enums, índices, funciones y políticas
RLS; cero INSERT de datos):
npm run db:migrate
En el panel de Neon, creá un segundo rol llamado app_runtime2 (Project → Roles → Add role).
Neon genera su propio connection string/contraseña: copialo a DATABASE_URL en .env.local
(este es el que usa la app en runtime, sujeto a RLS; nunca el del rol administrador).
Volvé a correr npm run db:migrate — 0002_rol_runtime.sql es idempotente y, ahora que el rol
existe, le otorga los permisos necesarios.
Con .env.local completo (Firebase + Neon):
npm run db:crear-admin
Pide el email y la contraseña por línea de comandos (no quedan escritos en ningún archivo), crea el
usuario en Firebase Auth y su perfil con rol admin en Neon. A partir de ahí, el resto de los
usuarios se crean desde el panel de administración de la propia aplicación.
npm run dev
Abrí http://localhost:3000.
Para producción:
npm run build
npm run start
npm test # corre una vez
npm run test:watch
Cubren la lógica de corrección automática (src/lib/scoring.ts), la selección aleatoria y el
armado de intentos (src/lib/randomization.ts), la generación/parseo de CSV y las reglas de
permisos por rol (src/lib/permisos.ts). Antes de dar por terminado un cambio, corré también:
npm run lint
npx tsc --noEmit
npm run build
db/
migrations/ DDL de Neon: tablas, enums, índices, funciones, RLS (sin datos)
scripts/
apply-migrations.mjs Aplica db/migrations/ contra DATABASE_URL_ADMIN
crear-primer-admin.mjs Alta manual del primer administrador (Auth + perfil en Neon)
src/
app/
login/ Inicio de sesión
estudiante/ Área del estudiante (rutas protegidas por rol)
docente/ Área docente (y admin, para banco/evaluaciones/reportes)
admin/ Administración (usuarios, cursos, configuración)
api/intentos/ Route handlers server-only: rendición y corrección de exámenes
api/reportes/ Exportación CSV/PDF/Excel
components/ Componentes de UI compartidos
lib/
db/ Capa de datos Neon (Drizzle): schema, contexto de sesión/RLS,
un módulo por dominio (cursos, preguntas, evaluaciones, intentos…)
firebase/ SDK de administrador, cookie de sesión y llamadas REST de Auth
scoring.ts Corrección automática (función pura)
randomization.ts Selección aleatoria y barajado (función pura)
intentos-server.ts Arma el snapshot de preguntas y corrige intentos (solo servidor)
permisos.ts Reglas de acceso por rol y ruta (función pura)
proxy.ts Protección de rutas por rol (runtime Node: el SDK de Firebase Admin
necesita módulos de Node, no funciona en el runtime Edge)
tests/unit/ Tests de Vitest
Las políticas RLS no pueden ocultar columnas específicas de una fila. Por eso, todo el flujo de
"rendir una evaluación" (iniciar intento, obtener preguntas, autoguardar respuestas, entregar y
corregir) pasa por Route Handlers (src/app/api/intentos/...) que leen la fila completa de
Neon (incluida respuesta_correcta) y arman manualmente la respuesta JSON, quitándola mientras el
intento está en_curso. El resto de la aplicación usa la misma capa de datos, siempre dentro de una
transacción con RLS activo para el usuario autenticado.
Administrador: usuarios, cursos, banco completo de preguntas, configuración general, todos los resultados.
Docente: banco de preguntas propio (y consulta de las preguntas activas de otros docentes), evaluaciones manuales o automáticas, asignación a cursos, incorporación de estudiantes, reportes (CSV/PDF/Excel) filtrados por curso/evaluación.
Estudiante: evaluaciones asignadas, rendición cronometrada con guardado automático, marcado de preguntas para revisar, resultados (cuando el/la docente los habilita), revisión de respuestas con resolución paso a paso, historial de intentos.
.env.local (ver arriba).npm run db:migrate (dos veces: antes y después de crear el rol app_runtime2 en Neon).npm run db:crear-admin para tener el primer usuario administrador.