ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 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.md檢視完整 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.
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.