ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Plataforma educativa abierta con IA para estudiantes de colegio público en Costa Rica (MVP: III Ciclo — 7.º, 8.º y 9.º). Antes se llamaba Edukemonos; la mascota y tutor, Kemo, conserva el nombre original. Guía de marca: docs/brand.md. Eduka es una iniciativa independiente. No es una plataforma oficial del Ministerio de Educación Pública. • Alcance y reglas: docs/SPEC.md • Plan por fases, riesgos y preguntas abiertas: PLAN.md • Qué contienen realmente las fuentes del MEP: docs/sources-inventory.mdREADME 전문 보기 ↗
Plataforma educativa abierta con IA para estudiantes de colegio público en Costa Rica (MVP: III Ciclo — 7.º, 8.º y 9.º).
Antes se llamaba Edukemonos; la mascota y tutor, Kemo, conserva el nombre original. Guía de marca:
docs/brand.md.
Eduka es una iniciativa independiente. No es una plataforma oficial del Ministerio de Educación Pública.
docs/SPEC.mdPLAN.mddocs/sources-inventory.mdapps/web Next.js 16 (App Router, TS), Tailwind v4 + shadcn/ui
packages/ai Capa de IA intercambiable (Anthropic / OpenAI), registro de uso, prompts versionados
packages/curriculum Tipos y esquema del manifiesto de fuentes
scripts/ingest Programas de estudio oficiales del MEP: manifiesto (sources.json), descarga respetuosa, verificación
supabase/migrations Esquema, funciones y RLS
supabase/tests Pruebas de RLS contra Postgres (intentan romper cada política)
config/ help-resources.json (lo completa el fundador con números verificados)
corepack enable)TEST_DATABASE_URL)pnpm install
cp .env.example apps/web/.env.local # complete los valores
pnpm dev # http://localhost:3000
Todas están documentadas en .env.example. Lo importante:
| Variable | Para qué |
|---|---|
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY | Cliente de Supabase en el navegador |
SUPABASE_SERVICE_ROLE_KEY | Solo servidor y scripts. Nunca en el navegador |
AI_PROVIDER | anthropic u openai |
ANTHROPIC_API_KEY | Clave de Anthropic. En sesiones de Claude Code en la nube use EDUKEMONOS_ANTHROPIC_API_KEY: la plataforma retira ANTHROPIC_API_KEY del entorno |
MODEL_BULK, MODEL_TUTOR, MODEL_VERIFY | Identificadores de modelo. No están en el código: tómelos de la documentación vigente del proveedor |
AI_PRICES_JSON | Precios por modelo para estimar costos en ai_usage |
RETENTION_DAYS_CHAT | Días que se guardan las conversaciones con el tutor (30 por defecto; pendiente de revisión legal). Las borra cada día /api/cron/purge |
CRON_SECRET | Secreto de Vercel Cron para /api/cron/purge; sin él, la limpieza diaria no corre |
eval "$(supabase/tests/start-local-pg.sh)" # Postgres desechable en el puerto 54329
pnpm lint && pnpm typecheck && pnpm test
pnpm test:rls corre solo las pruebas de RLS. Crean una base nueva, aplican un shim mínimo de Supabase (supabase/tests/supabase-shim.sql: roles anon/authenticated/service_role, auth.uid()), todas las migraciones y la semilla, y luego actúan como cada rol.
pnpm exec supabase link --project-ref <ref>
pnpm exec supabase db push # aplica supabase/migrations
psql "$DATABASE_URL" -f supabase/seed.sql
Después de crear su cuenta de correo en la app, conviértase en admin desde el SQL editor:
update public.profiles set role = 'admin' where id = '<su user id>';
Puntos de diseño:
cycles, grades, subjects): sumar I/II Ciclo es insertar filas.join_section(código, nombre, consentimiento).submit_attempt().La app vive en apps/web dentro de un monorepo pnpm. En Project Settings → Build and Deployment:
| Ajuste | Valor |
|---|---|
| Root Directory | apps/web |
| Include files outside the root directory | Activado (por defecto) — necesario para el workspace |
| Framework Preset | Next.js (se detecta solo con el Root Directory correcto) |
| Install / Build / Output | Sin override |
| Node.js Version | 22.x |
Si Root Directory queda en la raíz del repo, Vercel no encuentra next en package.json, trata el proyecto como estático y falla con "No Output Directory named "public" found".
Variables de entorno: las de .env.example (las de Supabase e IA son necesarias a partir de la Fase 1; la página inicial no las usa).
pnpm sources:verify # comprueba que los 6 programas del manifiesto siguen disponibles
El cliente respeta robots.txt, se identifica y espera ~2,5 s entre peticiones al mismo dominio.
Requiere pdftotext (poppler-utils) y las variables de Supabase e IA. Lee apps/web/.env.local si existe.
pnpm ingest db-check # ¿están las tablas?
pnpm ingest structure --source mep-prog-matematicas --grade 7 # muestra el costo estimado, NO gasta
pnpm ingest run --source mep-prog-matematicas --grade 7 --yes # descarga, extrae, estructura y carga
Extraer, no inventar: cada habilidad, contenido y extracto que propone la IA se verifica textualmente contra la página citada. Lo que no aparece queda marcado "por verificar" y la unidad no se puede publicar hasta corregirlo.
Todo entra como borrador. Volver a correr reemplaza los borradores de ese programa y grado, pero nunca toca unidades revisadas o publicadas.
pnpm ingest coverage … lista las páginas del grado que ninguna unidad cita, para revisarlas.
En Español el programa no trae habilidades específicas: sus criterios de evaluación se cargan como habilidades, cada uno con la página donde aparece textualmente.
Solo para unidades publicadas. Requiere la migración 20261003000100_content_generation.sql.
pnpm content generate --subject matematicas --grade 7 # muestra el costo estimado, NO gasta
pnpm content generate --subject matematicas --grade 7 --yes # genera, verifica y carga como borrador
pnpm content publish --subject matematicas --grade 7 # publica solo lo que pasó todas las verificaciones
pnpm content status --subject matematicas --grade 7
Por unidad se generan resumen, explicación paso a paso, ejemplos resueltos, glosario y unos 3 ítems por habilidad (entre 6 y 12). En Español se agregan ítems de lectura inferencial y crítica y 2 consignas de escritura.
MODEL_VERIFY busca errores conceptuales, de cálculo y contenido fuera de la unidad. Si encuentra uno, ese material no se publica.MODEL_VERIFY resuelve cada ítem sin ver la respuesta. Si la respuesta es un cálculo, además se recalcula con mathjs, y debe coincidir con la opción marcada y solo con ella. verified = true solo si todo coincide. Solo los ítems verificados entran al diagnóstico.publish deja lo publicado como "Generado con IA · pendiente de revisión". En /revisar/<unidad>/contenido un revisor lo aprueba (pasa a "revisado por docente"), lo edita o lo rechaza.pnpm content repair corrige el material que la revisión retuvo: lo reescribe con los problemas señalados y lo vuelve a revisar antes de publicarlo.generate salta las unidades que ya tienen material en Supabase: un fallo, el fusible de gasto o un contenedor reciclado nunca hacen pagar dos veces.Sin registro: el estudiante elige año → materia → unidad (/estudiar/7/matematicas, /unidad/<id>) con pestañas Aprender, Practicar y Preguntar al tutor (Fase 4). La primera vez que responde, recibe una sesión anónima de Supabase que guarda su avance en ese dispositivo.
submit_attempt) y muestra por qué cada opción es correcta o no. Si no se puede abrir sesión (por ejemplo, el límite por IP de Supabase en un colegio), igual califica con check_answer, sin guardar, y lo avisa./estudiar/<año>/<materia>/diagnostico): 10 preguntas verificadas que se adaptan a las respuestas; nivel de 1 a 5 y ruta sugerida. Algoritmo y justificación: docs/diagnostic.md./unirme): código + nombre + consentimiento. El nombre nunca va a la IA.Configuración necesaria en Supabase: Authentication → Sign In / Providers → activar Allow anonymous sign-ins. Conviene subir el límite de inicios anónimos por IP (Authentication → Rate Limits) para que una clase entera, detrás de una sola IP, pueda guardar su avance.
Pestaña Preguntar al tutor de cada unidad (POST /api/tutor, respuesta en streaming). Modelo: MODEL_TUTOR.
packages/ai/src/prompts/tutor.ts.mathjs) para toda operación en Matemáticas.config/help-resources.json) y le indican al tutor responder con cuidado.TUTOR_MAX_MESSAGES_PER_SESSION y TUTOR_MAX_MESSAGES_PER_DAY (contadores en Postgres), máximo de tokens por respuesta y el fusible de gasto.ai_usage guarda los tokens de caché aparte y el costo usa la tarifa real.writing_feedback). Límite WRITING_FEEDBACK_MAX_PER_DAY (20).Evaluaciones: pnpm eval:tutor (sin --yes solo estima) corre 60 casos (packages/ai/evals/tutor/cases.json) y escribe el reporte en docs/evals/.
Variables necesarias en el servidor (Vercel): SUPABASE_SERVICE_ROLE_KEY, ANTHROPIC_API_KEY, AI_PROVIDER, MODEL_TUTOR, MODEL_BULK, MODEL_VERIFY, AI_PRICES_JSON, AI_BUDGET_DAILY_USD, AI_BUDGET_MONTHLY_USD, TUTOR_MAX_MESSAGES_PER_SESSION, TUTOR_MAX_MESSAGES_PER_DAY, CRON_SECRET (limpieza diaria de conversaciones).
/docente: presentación del panel para quien no ha entrado; con sesión, las secciones del docente y el formulario
para crear una. Cualquier cuenta de correo (no anónima) es docente. Al entrar con el enlace del correo se llega aquí./docente/demo: sección de demostración sin necesidad de cuenta, con 26 estudiantes ficticios sobre los temas
reales de 7.º, etiquetada como tal. Los datos son deterministas (buildDemoSection en packages/curriculum) y el
dominio sale del mismo algoritmo que usa la práctica real./docente/seccion/<id>: código para dictar (copiar, cambiar, desactivar), indicadores, hallazgos con «¿Cómo se
calculó?», resumen con IA, estudiantes que podrían necesitar apoyo, mapa de calor estudiantes × temas, actividad,
diagnóstico, errores de escritura, temas consultados a Kemo, tabla de estudiantes y CSV. Registro de accesos al pie./docente/seccion/<id>/estudiante/<id>: detalle por estudiante (nivel por materia, dominio e intentos por tema,
errores de escritura, línea de tiempo) y la opción de sacarlo de la sección.teacher_audit_log.computeSectionMetrics en packages/curriculum/src/teacher.ts). El resumen con IA
recibe solo los hallazgos (conteos y títulos de temas, sin nombres), usa MODEL_BULK (prompt
teacher-summary-system), se guarda en teacher_summaries por hash de los hallazgos y tiene un límite de 10
generaciones por docente al día (6 para la demostración). Necesita la migración 20261007000100_teacher_panel.sql;
sin ella el panel funciona, pero el resumen no se guarda./revisar)/entrar con tu correo (enlace mágico).update public.profiles set role = 'reviewer' where id = '<user id>';/revisar eliges materia y grado. En cada unidad ves el texto de la página oficial al lado, editas, guardas (se verifica de nuevo) y la marcas como revisada, la publicas o la rechazas. Todo queda en review_log.En Supabase → Authentication → URL Configuration, agrega la URL de Vercel en Site URL y https://<tu-dominio>/auth/confirm en Redirect URLs.
import { createAI } from "@edukemonos/ai";
const ai = createAI({ sink: (row) => saveToAiUsage(row) });
const { data } = await ai.generateStructured(
{ role: "bulk", purpose: "structure_curriculum" },
{ system, messages, schema, schemaName: "units" },
);
AI_PROVIDER y los MODEL_*.MODEL_* acepta una cadena de respaldo (MODEL_TUTOR=claude-haiku-4-5,claude-sonnet-5-5): si un modelo falla, se usa el siguiente, salvo que haya rechazado el pedido (eso se respeta). Cada intento fallido queda en ai_usage.AI_BUDGET_DAILY_USD y AI_BUDGET_MONTHLY_USD (día y mes de Costa Rica). Antes de cada llamada se suma ai_usage; al llegar al tope no se llama a la IA. Si el gasto no se puede leer, la llamada se rechaza. Con tope configurado, todo modelo debe tener precio en AI_PRICES_JSON o la app no arranca.pnpm ai:diagnose prueba cada modelo configurado con una llamada mínima y muestra el gasto de hoy y del mes.packages/ai/src/prompts/ con id y versión, que se guardan junto al contenido generado.