diff --git a/.env.example b/.env.example
index 6ada970..90fd36f 100644
--- a/.env.example
+++ b/.env.example
@@ -1,7 +1,7 @@
VITE_SUPABASE_URL=https://YOUR_PROJECT_REF.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_REPLACE_ME
# Optional. Include the leading and trailing slash.
-VITE_BASE_PATH=/tomatin-code-lab/beta/
+VITE_BASE_PATH=/tomatin-code-lab/
# Forces the static contribution sandbox and ignores Supabase credentials.
VITE_FRONTEND_ONLY=false
diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index 8e518c9..3b568cc 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -1,84 +1,51 @@
name: Reportar un error
-description: Informa un comportamiento incorrecto o una regresión reproducible.
+description: Cuéntanos qué no funcionó.
title: "[Bug]: "
-labels:
- - bug
-assignees:
- - eeminionn
+labels: [bug]
+assignees: [eeminionn]
body:
- - type: markdown
- attributes:
- value: |
- Gracias por ayudar a mejorar Tomatin Code Lab. No incluyas tokens, contraseñas, soluciones privadas ni datos personales de estudiantes.
- type: dropdown
id: area
attributes:
- label: Área afectada
+ label: ¿Dónde ocurrió?
options:
- - Aula del estudiante
- - Panel del mentor
- - Misiones o evaluador
- - Autenticación e invitaciones
- - Sincronización con GitHub
- - Accesibilidad o diseño responsive
- - Documentación o infraestructura
+ - Vista del estudiante
+ - Panel del profesor
+ - Editor o ejecución de código
+ - Inicio de sesión
+ - Documentación
+ - Otro
validations:
required: true
- type: textarea
- id: summary
+ id: problem
attributes:
- label: Descripción
- description: Explica qué ocurrió y cuál es el impacto.
- placeholder: Al intentar..., la aplicación...
+ label: ¿Qué pasó?
+ placeholder: Explica el problema con tus palabras.
validations:
required: true
- type: textarea
- id: reproduction
+ id: steps
attributes:
- label: Pasos para reproducir
- description: Incluye el recorrido mínimo y datos de ejemplo no sensibles.
- placeholder: |
- 1. Iniciar sesión como...
- 2. Abrir...
- 3. Presionar...
+ label: ¿Cómo podemos repetirlo?
+ placeholder: "1. Abrí...\n2. Presioné...\n3. Apareció..."
validations:
required: true
- type: textarea
id: expected
attributes:
- label: Resultado esperado
+ label: ¿Qué esperabas que ocurriera?
validations:
required: true
- type: textarea
- id: actual
+ id: evidence
attributes:
- label: Resultado actual y evidencia
- description: Puedes arrastrar capturas o pegar errores ya redactados.
- validations:
- required: true
- - type: input
- id: environment
- attributes:
- label: Entorno
- description: URL, navegador, sistema operativo y tamaño de pantalla.
- placeholder: Beta, Safari 18, macOS, 1440 × 900
- validations:
- required: true
- - type: textarea
- id: acceptance
- attributes:
- label: Criterios de aceptación sugeridos
- description: ¿Qué debería comprobarse para cerrar este issue?
- placeholder: |
- - [ ] El recorrido termina sin errores.
- - [ ] Existe una prueba de regresión.
+ label: Captura o información adicional
+ description: No incluyas contraseñas, tokens ni datos personales.
- type: checkboxes
- id: checks
+ id: privacy
attributes:
- label: Confirmaciones
+ label: Confirmación
options:
- - label: Busqué issues existentes y no encontré uno equivalente.
- required: true
- - label: Eliminé secretos y datos personales de la evidencia.
+ - label: Revisé que el reporte no contenga información privada.
required: true
-
diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml
index 9099567..b3108d7 100644
--- a/.github/ISSUE_TEMPLATE/feature.yml
+++ b/.github/ISSUE_TEMPLATE/feature.yml
@@ -1,74 +1,35 @@
name: Proponer una mejora
-description: Propón una capacidad nueva a partir de una necesidad concreta.
+description: Comparte una idea para hacer más útil o agradable la plataforma.
title: "[Mejora]: "
-labels:
- - enhancement
-assignees:
- - eeminionn
+labels: [enhancement]
+assignees: [eeminionn]
body:
- - type: markdown
- attributes:
- value: |
- Describe primero el problema. Una buena propuesta permite comparar alternativas antes de elegir una implementación.
- type: dropdown
id: audience
attributes:
- label: Persona beneficiada
+ label: ¿A quién ayuda?
options:
- - Estudiante
- - Mentor o administrador
- - Creador de contenido
- - Contribuidor
- - Varias de las anteriores
+ - Estudiantes
+ - Profesor
+ - Ambos
+ - Quienes contribuyen
validations:
required: true
- type: textarea
- id: problem
+ id: idea
attributes:
- label: Problema u oportunidad
- description: Explica qué necesidad existe y cómo se resuelve actualmente.
+ label: Tu idea
+ placeholder: Describe qué te gustaría cambiar o agregar.
validations:
required: true
- type: textarea
- id: proposal
- attributes:
- label: Propuesta
- description: Describe el resultado deseado sin asumir detalles técnicos innecesarios.
- validations:
- required: true
- - type: textarea
- id: alternatives
- attributes:
- label: Alternativas consideradas
- description: Incluye opciones descartadas y sus principales compromisos.
- - type: textarea
- id: acceptance
+ id: reason
attributes:
- label: Criterios de aceptación
- placeholder: |
- - [ ] ...
- - [ ] ...
+ label: ¿Por qué sería útil?
validations:
required: true
- type: textarea
- id: privacy
+ id: reference
attributes:
- label: Privacidad, seguridad y accesibilidad
- description: Indica si toca datos estudiantiles, permisos, autenticación o interacción por teclado.
- validations:
- required: true
- - type: textarea
- id: references
- attributes:
- label: Referencias o diseños
- description: Enlaces, capturas o productos de referencia.
- - type: checkboxes
- id: checks
- attributes:
- label: Confirmaciones
- options:
- - label: Busqué propuestas existentes y no encontré una equivalente.
- required: true
- - label: Entiendo que el proyecto está en desarrollo y la propuesta puede iterarse.
- required: true
-
+ label: Captura, dibujo o referencia
+ description: Opcional.
diff --git a/.github/ISSUE_TEMPLATE/task.yml b/.github/ISSUE_TEMPLATE/task.yml
index 5e3ff64..5689c18 100644
--- a/.github/ISSUE_TEMPLATE/task.yml
+++ b/.github/ISSUE_TEMPLATE/task.yml
@@ -1,59 +1,26 @@
-name: Registrar una tarea técnica
-description: Define mantenimiento, documentación, deuda técnica o trabajo interno verificable.
+name: Tarea del proyecto
+description: Registra una tarea concreta de mantenimiento o documentación.
title: "[Tarea]: "
-labels:
- - maintenance
-assignees:
- - eeminionn
+labels: [maintenance]
+assignees: [eeminionn]
body:
- - type: dropdown
- id: area
- attributes:
- label: Área
- options:
- - Frontend
- - Backend y Supabase
- - Contenido de misiones
- - Pruebas y accesibilidad
- - GitHub Actions y despliegue
- - Documentación y comunidad
- validations:
- required: true
- type: textarea
- id: context
+ id: goal
attributes:
- label: Contexto
- description: Explica por qué la tarea existe y qué riesgo o costo evita.
+ label: Objetivo
+ placeholder: Explica brevemente qué debe quedar listo.
validations:
required: true
- type: textarea
id: work
attributes:
- label: Tareas
- placeholder: |
- - [ ] ...
- - [ ] ...
+ label: Pasos
+ placeholder: "- [ ] Primer paso\n- [ ] Segundo paso"
validations:
required: true
- type: textarea
- id: acceptance
+ id: done
attributes:
- label: Criterios de aceptación
- placeholder: |
- - [ ] ...
- - [ ] ...
+ label: ¿Cómo sabremos que está listo?
validations:
required: true
- - type: textarea
- id: validation
- attributes:
- label: Validación prevista
- description: Comandos, recorridos o métricas que demostrarán que quedó terminado.
- validations:
- required: true
- - type: textarea
- id: rollout
- attributes:
- label: Despliegue y reversión
- description: Completa esta sección cuando la tarea cambie producción, datos o permisos.
-
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 729eda7..552a597 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,48 +1,18 @@
-## Issue relacionado
+## Issue
Closes #
-## Qué cambia
+## Qué cambié
-
+- Describe aquí el cambio.
--
+## Cómo lo probé
-## Por qué
+- [ ] Ejecuté `pnpm check:frontend`.
+- [ ] Revisé escritorio y móvil si cambié la interfaz.
+- [ ] Agregué una captura o no aplica.
-
-
-## Implementación
-
-
-
-## Evidencia visual
-
-
-
-## Validación
-
-- [ ] `pnpm check`
-- [ ] `pnpm test:e2e`
-- [ ] `supabase test db` o no aplica
-- [ ] Probé el recorrido afectado en local o beta
-
-## Privacidad, seguridad y accesibilidad
-
-- [ ] No añadí secretos, soluciones privadas ni datos personales al código, fixtures o logs.
-- [ ] Revisé RLS/permisos si cambié acceso a datos o autenticación.
-- [ ] Revisé teclado, nombres accesibles, contraste y responsive si cambié la interfaz.
-- [ ] Documenté cualquier riesgo residual.
-
-## Despliegue
-
-
-
-## Checklist de entrega
-
-- [ ] El PR tiene responsable, labels y milestone cuando corresponde.
-- [ ] Actualicé pruebas y documentación.
-- [ ] No contiene cambios ajenos al issue.
-- [ ] CI está en verde.
-- [ ] Está listo para revisión.
+## Antes de enviar
+- [ ] No incluí secretos, datos personales ni soluciones privadas.
+- [ ] El PR contiene solo cambios relacionados con el issue.
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index b0430f4..b686874 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -33,7 +33,7 @@ jobs:
node-version: 22
cache: pnpm
- - name: Verify beta configuration
+ - name: Verify production configuration
env:
VITE_SUPABASE_URL: ${{ vars.VITE_SUPABASE_URL }}
VITE_SUPABASE_PUBLISHABLE_KEY: ${{ vars.VITE_SUPABASE_PUBLISHABLE_KEY }}
@@ -47,11 +47,11 @@ jobs:
exit 1
}
- - name: Build beta
+ - name: Build application
env:
VITE_SUPABASE_URL: ${{ vars.VITE_SUPABASE_URL }}
VITE_SUPABASE_PUBLISHABLE_KEY: ${{ vars.VITE_SUPABASE_PUBLISHABLE_KEY }}
- VITE_BASE_PATH: /${{ github.event.repository.name }}/beta/
+ VITE_BASE_PATH: /${{ github.event.repository.name }}/
run: |
pnpm install --frozen-lockfile
pnpm build
@@ -59,9 +59,8 @@ jobs:
- name: Assemble static site
run: |
mkdir _site
- cp index.html 404.html styles.css manifest.webmanifest robots.txt sitemap.xml sw.js .nojekyll _site/
- cp -R assets js _site/
- cp -R dist-beta _site/beta
+ cp -R dist-app/. _site/
+ cp dist-app/index.html _site/404.html
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v4
@@ -82,25 +81,28 @@ jobs:
id: deployment
uses: actions/deploy-pages@v4
- - name: Smoke test beta
+ - name: Smoke test stable application
env:
PAGE_URL: ${{ steps.deployment.outputs.page_url }}
REPOSITORY_NAME: ${{ github.event.repository.name }}
run: |
- beta_url="${PAGE_URL%/}/beta/"
+ root_url="${PAGE_URL%/}/"
for attempt in {1..12}; do
curl \
--fail \
--silent \
--show-error \
- --output beta.html \
- "$beta_url"
- if grep -Fq "
Tomatin Code Lab 3.0" beta.html \
- && grep -Fq "/$REPOSITORY_NAME/beta/assets/" beta.html; then
- exit 0
+ --output app.html \
+ "$root_url"
+ if grep -Fq "Tomatin Code Lab" app.html \
+ && grep -Fq "/$REPOSITORY_NAME/assets/" app.html; then
+ curl --fail --silent --show-error --output redirect.html "${root_url}beta/"
+ if grep -Fq "Redirigiendo a Tomatin Code Lab" redirect.html; then
+ exit 0
+ fi
fi
echo "Waiting for GitHub Pages propagation ($attempt/12)."
sleep 5
done
- echo "::error::The deployed beta did not expose Tomatin Code Lab 3.0."
+ echo "::error::The stable Tomatin Code Lab application was not available at the root URL."
exit 1
diff --git a/.github/workflows/supabase.yml b/.github/workflows/supabase.yml
index 427e625..08cba4f 100644
--- a/.github/workflows/supabase.yml
+++ b/.github/workflows/supabase.yml
@@ -64,6 +64,9 @@ jobs:
- name: Link project
run: supabase link --project-ref "$PROJECT_ID" --password "$SUPABASE_DB_PASSWORD"
+ - name: Configure authentication URLs
+ run: supabase config push --project-ref "$PROJECT_ID" --yes
+
- name: Apply database migrations
run: supabase db push
diff --git a/.gitignore b/.gitignore
index 1df4495..895b7d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
coverage/
dist/
dist-beta/
+dist-app/
node_modules/
playwright-report/
test-results/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7faa446..0cd73c8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,57 +1,41 @@
# Contribuir
-Las contribuciones deben mantener el proyecto educativo, original, accesible y
-seguro. Lee el [código de conducta](CODE_OF_CONDUCT.md) antes de participar.
+Gracias por mejorar Tomatin Code Lab. La mayoría de las contribuciones están
+pensadas para estudiantes y deben ser pequeñas, claras y fáciles de revisar.
-## Issues
+## Antes de empezar
-Usa el formulario que corresponda y completa el contexto, las tareas, los
-criterios de aceptación y la validación prevista. Cada issue de implementación
-debe tener:
+1. Revisa si ya existe un issue parecido.
+2. Comenta que quieres trabajarlo o abre un issue breve.
+3. Crea una rama desde `main`.
-- Una persona responsable.
-- Labels de tipo y área.
-- Un milestone cuando forme parte de una entrega planificada.
-- Un GitHub Project solo cuando exista un tablero activo que aporte seguimiento
- adicional; no se crea uno para duplicar un milestone.
-- Una checklist actualizada durante el trabajo.
+Los forks pueden cambiar el frontend y su documentación. No deben modificar
+`supabase/`, workflows de producción, secretos ni datos de estudiantes.
-Las dudas abiertas pertenecen a Discussions. Nunca publiques secretos, tokens,
-soluciones privadas ni datos personales de estudiantes.
+## Trabajar en local
-## Flujo local
+```bash
+corepack enable
+pnpm install
+pnpm frontend:dev
+```
-Las contribuciones provenientes de forks son exclusivamente de frontend. Usa
-`pnpm frontend:dev` para trabajar sobre la interfaz actual de Aula 3.0 sin
-conectar Supabase. No cambies `supabase/`, secretos, migraciones ni workflows de
-producción; CI rechazará esos archivos en un PR desde fork.
+El modo local usa datos ficticios y no se conecta al backend. Antes de enviar:
-1. Crea una rama enfocada desde `main`.
-2. Realiza un cambio coherente y vinculado a un issue.
-3. Ejecuta `pnpm check:frontend` y
- `pnpm test:e2e:frontend`.
-4. Abre un pull request con `Closes #…`, impacto, validación, privacidad y
- despliegue.
-5. Completa responsable, labels y milestone antes de solicitar revisión.
-6. Fusiona solo con CI en verde y actualiza la checklist del issue.
+```bash
+pnpm check:frontend
+```
-## Misiones
+## Pull request
-- Escribe enunciados originales; no copies tareas de otros cursos.
-- Incluye objetivo, contrato, starter code, pistas progresivas y casos
- ejecutables.
-- Mantén las referencias locales acogedoras y comprensibles sin contexto
- adicional.
-- Prefiere un concepto claro antes que un chiste.
+Incluye solamente:
-## Privacidad
+- El issue relacionado.
+- Una explicación corta del cambio.
+- Cómo lo probaste.
+- Una captura si cambiaste algo visible.
-Las credenciales, tests ocultos y entregas estudiantiles son datos de servidor.
-No deben aparecer en el bundle, fixtures, logs ni historial de Git. El sandbox
-de contribución no debe enviar solicitudes a Supabase, Judge0 ni GitHub.
+GitHub Actions hará el resto de las comprobaciones. Nunca publiques tokens,
+contraseñas, datos personales ni soluciones privadas.
-## Accesibilidad
-
-Todos los controles necesitan una ruta de teclado y un nombre accesible. Revisa
-escritorio y móvil, foco visible, movimiento reducido, contraste y etiquetas
-largas en español.
+Participa con respeto y sigue el [código de conducta](CODE_OF_CONDUCT.md).
diff --git a/README.md b/README.md
index f321d8f..2d5081e 100644
--- a/README.md
+++ b/README.md
@@ -1,178 +1,72 @@
# Tomatin Code Lab
-Tomatin Code Lab es un aula multilenguaje, todavía en desarrollo, para enseñar
-y practicar Programación I y II mediante veinte misiones originales en
-JavaScript, Python y C++. Reúne enunciado, editor, ejecución, feedback,
-progreso y herramientas de mentor en una interfaz terminal.
+Tomatin Code Lab es un aula para aprender programación resolviendo misiones,
+recibir feedback y avanzar junto a un profesor.
-- **Versión estable:** [eeminionn.github.io/tomatin-code-lab](https://eeminionn.github.io/tomatin-code-lab/)
-- **Aula 3.0 beta:** [eeminionn.github.io/tomatin-code-lab/beta](https://eeminionn.github.io/tomatin-code-lab/beta/)
-- **Estado:** en desarrollo; no es un producto terminado.
+**Abrir la plataforma:**
+[eeminionn.github.io/tomatin-code-lab](https://eeminionn.github.io/tomatin-code-lab/)
-> Proyecto independiente. No está afiliado ni respaldado por MIT. Los
-> enunciados y recursos educativos de esta plataforma son originales.
+Los estudiantes trabajan desde el navegador, guardan su avance y entregan sus
+respuestas. El profesor crea tareas, revisa entregas, acompaña el progreso y
+administra el curso desde un panel propio.
-## Contribuciones de frontend
+## Contribuir al frontend
-Los forks de este repositorio se usan exclusivamente para mejorar el frontend:
-componentes, diseño, responsive, accesibilidad, redacción, navegación,
-visualizaciones y experiencia de uso. No necesitas Supabase, OAuth, tokens,
-base de datos ni acceso a la infraestructura oficial.
+Las contribuciones de forks se concentran en la interfaz: diseño, textos,
+accesibilidad, navegación, responsive y experiencia de uso. El modo local usa
+datos de ejemplo y mantiene el backend desactivado, por lo que no necesitas
+credenciales ni acceso a la clase real.
-El sandbox carga el código actual de [`v2/`](v2/), la misma aplicación React y
-TypeScript publicada como **Aula 3.0 beta**. No es una reconstrucción de la
-versión estable antigua ni una maqueta distinta.
+### Abrir el proyecto
-## Abrir Aula 3.0 localmente
-
-Requisitos: [Git](https://git-scm.com/), Node.js 22 o superior y
-[pnpm 11](https://pnpm.io/installation).
-
-1. Haz clic en **Fork** en GitHub.
-2. Clona tu fork y registra el repositorio original como `upstream`:
+Necesitas Git y Node.js 22 o superior.
```bash
git clone https://github.com/TU_USUARIO/tomatin-code-lab.git
cd tomatin-code-lab
-git remote add upstream https://github.com/eeminionn/tomatin-code-lab.git
-```
-
-3. Instala dependencias:
-
-```bash
corepack enable
pnpm install
-```
-
-4. Construye y abre el sandbox estático:
-
-```bash
-pnpm frontend
-```
-
-Se abrirá `http://127.0.0.1:4173/`. El comando genera HTML, CSS, JavaScript y
-assets en `dist-beta/`, y luego los sirve con el preview estático de Vite. Ese
-servidor solo entrega archivos: no implementa API, autenticación ni base de
-datos.
-
-Para trabajar con recarga inmediata durante el diseño:
-
-```bash
pnpm frontend:dev
```
-No abras `dist-beta/index.html` mediante `file://`: los módulos ES, Web Workers
-y assets de Monaco necesitan un origen HTTP local. Esto no activa un backend;
-solo evita las restricciones de seguridad que el navegador aplica a archivos
-abiertos directamente desde el disco.
-
-## Qué funciona en el sandbox
-
-- Las vistas reales de estudiante y mentor de Aula 3.0.
-- Navegación, filtros, pestañas, modales, responsive y vista estudiante.
-- Las veinte misiones y sus variantes JavaScript, Python y C++.
-- Monaco Editor, edición de código y borradores locales.
-- Ejecución de JavaScript en Web Worker.
-- Ejecución de Python en Pyodide Worker.
-- Redimensionado del workspace, resultados y estados visuales.
-- Personalización visual del avatar antes de guardar.
-- Datos ficticios de diez estudiantes para diseñar dashboards y rankings.
-
-## Qué queda desactivado
-
-- Inicio de sesión real con GitHub.
-- Lectura o escritura en Supabase.
-- Entregas, tests ocultos y sincronización de resoluciones.
-- Ejecución remota de C++ y cualquier llamada a Judge0.
-- Crear o modificar tareas, invitaciones y misiones.
-- Aprobar entregas, asignar XP o solicitar cambios.
-- Guardar perfiles, eliminar feedback o modificar datos del curso.
-- Edge Functions, Realtime y repositorios privados.
-
-Los controles siguen visibles para poder diseñar todos sus estados, pero las
-acciones que necesitan backend aparecen deshabilitadas. Además, el runtime
-ignora las credenciales Supabase aunque exista un `.env.local` por accidente.
-Una barra amarilla persistente identifica el sandbox.
-
-## Archivos permitidos
-
-Una contribución desde un fork debe concentrarse en:
-
-- `v2/src/components/`
-- `v2/src/pages/`
-- `v2/src/styles.css`
-- `v2/src/lib/`
-- `v2/src/data/` cuando el cambio sea exclusivamente de presentación
-- `v2/e2e/` y `v2/tests/`
-- `v2/public/` y assets visuales
-- `README.md`, `CONTRIBUTING.md`, `package.json` y `pnpm-lock.yaml`
-
-No modifiques desde un fork:
-
-- `supabase/`
-- `.github/workflows/pages.yml`
-- `.github/workflows/supabase.yml`
-- secretos, migraciones, RLS, Edge Functions o sincronización de entregas
-
-CI revisa este límite. Un pull request proveniente de un fork que cambie
-backend o workflows de producción fallará automáticamente. Los workflows de
-Pages y Supabase también están restringidos al repositorio oficial.
-
-## Enviar un cambio
-
-1. Sincroniza tu fork y crea una rama:
-
-```bash
-git fetch upstream
-git switch main
-git merge --ff-only upstream/main
-git switch -c frontend/descripcion-corta
-```
-
-2. Trabaja usando `pnpm frontend:dev`.
-3. Verifica el resultado:
+Abre [http://127.0.0.1:4173](http://127.0.0.1:4173). Verás las mismas pantallas
+de estudiante y profesor que están publicadas, con diez estudiantes ficticios.
+Los botones que necesitan el backend siguen visibles para poder diseñarlos,
+pero no realizan cambios reales.
-```bash
-pnpm frontend:build
-pnpm check:frontend
-pnpm test:e2e:frontend
-```
+### Qué puedes modificar
-4. Sube la rama:
+- Componentes, páginas, estilos, textos y recursos de `v2/`.
+- Pruebas relacionadas con tu cambio.
+- Documentación del frontend.
-```bash
-git push -u origin frontend/descripcion-corta
-```
+No modifiques `supabase/`, secretos ni workflows de producción desde un fork.
+GitHub Actions comprueba este límite automáticamente.
-5. Abre un pull request hacia `eeminionn/tomatin-code-lab:main`, enlaza un
- issue y explica el cambio observable. Para cambios visuales incluye una
- captura de escritorio y otra móvil.
+### Enviar un cambio
-Revisa también [CONTRIBUTING.md](CONTRIBUTING.md), el
-[código de conducta](CODE_OF_CONDUCT.md) y los issues abiertos.
+1. Crea una rama y realiza un cambio enfocado.
+2. Ejecuta `pnpm check:frontend`.
+3. Abre un pull request, enlaza el issue y agrega una captura si cambiaste la
+ interfaz.
-## Forks y `.gitignore`
+La guía corta está en [CONTRIBUTING.md](CONTRIBUTING.md). También aplican el
+[código de conducta](CODE_OF_CONDUCT.md) y la [política de seguridad](SECURITY.md).
-Un fork copia el historial y todos los archivos versionados. No copia secrets,
-variables de Actions, usuarios, datos de Supabase ni el repositorio privado de
-resoluciones.
+## Archivos locales
-`.gitignore` no es una caja fuerte: evita agregar archivos locales nuevos, pero
-no oculta archivos que ya estaban versionados. En este proyecto quedan fuera
-`node_modules/`, builds, reportes, cobertura y todos los `.env*`, excepto
-`.env.example`. Para el sandbox no debes crear ningún `.env`.
+Un fork contiene todos los archivos versionados, pero no copia secretos,
+variables de GitHub Actions, datos de Supabase ni entregas privadas. Los `.env`,
+dependencias, builds y reportes locales están excluidos mediante `.gitignore`.
-## Comandos
+## Comandos útiles
| Comando | Uso |
| --- | --- |
-| `pnpm frontend` | Construye y abre el sandbox estático |
-| `pnpm frontend:dev` | Sandbox con recarga inmediata |
-| `pnpm frontend:build` | Genera el frontend estático en `dist-beta/` |
-| `pnpm check:frontend` | Tipos, unidades y build desconectado |
-| `pnpm check` | Verificación integral reservada al repositorio oficial |
-| `pnpm test:e2e:frontend` | Recorrido del sandbox sin backend |
-| `pnpm test:e2e` | Recorridos completos de la aplicación demo |
+| `pnpm frontend:dev` | Abre el frontend local con recarga automática |
+| `pnpm check:frontend` | Revisa tipos, pruebas y build del frontend |
+| `pnpm test:e2e:frontend` | Prueba que el modo local no use el backend |
+| `pnpm check` | Ejecuta la verificación completa del repositorio oficial |
## Licencia
diff --git a/SECURITY.md b/SECURITY.md
index df88f3f..52da181 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,41 +1,25 @@
-# Security
+# Seguridad
-## Versiones publicadas
+La plataforma publicada usa GitHub para iniciar sesión y Supabase para proteger
+cuentas, tareas y progreso. El modo local de contribución usa datos ficticios y
+no se conecta al backend.
-La versión estable mantiene cuentas y progreso de demostración en
-`localStorage`. Sus credenciales públicas no protegen datos reales.
+## Datos y ejecución
-La beta 2.0 funciona en dos modos:
-
-- Sin variables Supabase usa datos ficticios locales para recorrer la interfaz.
-- Con Supabase usa OAuth o magic link, invitaciones de un uso, roles de servidor,
- RLS y Edge Functions para ejecutar entregas.
-
-No ingreses datos personales o soluciones reales en el modo demo.
-
-## Ejecución de código
-
-- El navegador limita el código a 64 KB y la salida a 32 KB.
-- JavaScript y Python se ejecutan en Web Workers para pruebas visibles.
-- C++ y todas las entregas verificadas pasan por una Edge Function y Judge0.
-- La Edge Function limita CPU a 2 segundos, pared a 5 segundos y memoria a
- 128 MB.
-- Los endpoints no aceptan tests enviados por el cliente. Resuelven la versión y
- los tests ocultos desde el esquema privado.
-- El límite inicial es de 20 ejecuciones remotas y 10 entregas por usuario/hora.
-
-La instancia pública de Judge0 sirve para el piloto y no ofrece un SLA. Para
-clases con requisitos de disponibilidad se debe configurar una instancia
-gestionada o propia mediante `JUDGE0_URL`.
+- Los estudiantes solo pueden leer su propio progreso y sus entregas.
+- Las soluciones, pruebas privadas y credenciales permanecen en el servidor.
+- JavaScript y Python pueden ejecutarse localmente para obtener feedback rápido.
+- C++ y las entregas verificadas pasan por un ejecutor remoto con límites de
+ tiempo, memoria, tamaño de código y frecuencia.
## Secretos
-Nunca confirmes `.env`, service-role keys, access tokens, contraseñas de base de
-datos ni claves de Judge0. La clave publicable de Supabase puede vivir en el
-frontend; la seguridad depende de RLS, no de ocultarla.
+Nunca confirmes `.env`, tokens, contraseñas, service-role keys ni claves del
+ejecutor. La clave publicable de Supabase puede aparecer en el frontend; los
+datos se protegen con políticas RLS.
## Reportar una vulnerabilidad
-Abre un security advisory privado en el repositorio. Incluye versión, pasos de
-reproducción, impacto y una prueba mínima. No publiques secretos ni datos
-personales en issues.
+Usa un
+[security advisory privado](https://github.com/eeminionn/tomatin-code-lab/security/advisories/new).
+No publiques secretos ni datos personales en un issue.
diff --git a/docs/BETA_ROLLOUT.md b/docs/BETA_ROLLOUT.md
deleted file mode 100644
index b084871..0000000
--- a/docs/BETA_ROLLOUT.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Lanzamiento beta 3.0
-
-Tomatin Code Lab 3.0 permanece en
-`https://eeminionn.github.io/tomatin-code-lab/beta/` durante el piloto. La
-versión estable de la raíz no se reemplaza todavía.
-
-## Barreras automáticas
-
-- CI ejecuta las pruebas heredadas, TypeScript, Edge Functions, las 60
- soluciones de referencia, el build y los recorridos Playwright.
-- pgTAP aplica todas las migraciones desde cero y verifica RLS, privacidad y
- contratos de versión.
-- GitHub Pages falla si faltan las variables públicas de Supabase.
-- Supabase falla si faltan los secretos de despliegue o de sincronización con
- el repositorio privado de resoluciones.
-- El deploy comprueba el acceso al issue de avisos. El secret de Actions
- `NOTIFICATION_REPOSITORY_TOKEN` debe seleccionar únicamente
- `eeminionn/tomatin-code-lab` y conceder `Issues: Read and write` junto con
- `Metadata: Read-only`; el workflow lo copia como
- `GITHUB_NOTIFICATION_TOKEN` a la Edge Function sin exponerlo. El nombre de
- Actions evita el prefijo `GITHUB_`, reservado por GitHub.
-- Después de publicar, Pages comprueba que `/beta/` responda y sirva la versión
- 3.0 desde la ruta correcta.
-
-## Piloto con dos estudiantes
-
-- [ ] Iniciar sesión con GitHub mediante dos invitaciones de un solo uso.
-- [ ] Confirmar que cada cuenta recibe únicamente rol `student`.
-- [ ] Abrir la Misión 01 en dos acciones y comprenderla sin revelar pistas.
-- [ ] Guardar código distinto en JavaScript, Python y C++ sin perder borradores.
-- [ ] Ejecutar al menos un caso correcto y uno incorrecto en cada lenguaje.
-- [ ] Entregar una misión y comprobar que cada estudiante actualice únicamente
- su carpeta dentro del repositorio privado central.
-- [ ] Revisar desde `/admin`, comentar una línea y solicitar cambios.
-- [ ] Confirmar que la reentrega usa la versión actual sin borrar el historial.
-- [ ] Aprobar una entrega y comprobar que el XP se emita una sola vez.
-- [ ] Entrar en `Ver como estudiante` y confirmar que todas las mutaciones estén
- deshabilitadas.
-- [ ] Validar la experiencia en notebook y una edición breve desde móvil.
-
-## Paso a diez estudiantes
-
-El piloto se amplía cuando ambos estudiantes completan el recorrido sin pérdida
-de código, filtración de datos privados ni bloqueos del ejecutor. Durante la
-primera clase se revisan el estado de Supabase, la cola de Judge0, los errores
-de sincronización y el tiempo medio de revisión desde `/admin`.
-
-La raíz se promueve solo cuando los diez estudiantes pueden iniciar sesión,
-trabajar y entregar, y eeminionn puede llegar a cualquier entrega en un máximo
-de tres acciones.
diff --git a/docs/RELEASE.md b/docs/RELEASE.md
new file mode 100644
index 0000000..0f509db
--- /dev/null
+++ b/docs/RELEASE.md
@@ -0,0 +1,23 @@
+# Publicación estable
+
+La aplicación vigente se publica en
+`https://eeminionn.github.io/tomatin-code-lab/`.
+
+## Comprobaciones automáticas
+
+- CI revisa tipos, pruebas, soluciones de referencia y recorridos del navegador.
+- pgTAP aplica las migraciones desde cero y verifica privacidad y permisos.
+- GitHub Pages falla si faltan las variables públicas de Supabase.
+- Supabase aplica migraciones, configuración de autenticación y Edge Functions.
+- El despliegue comprueba que la raíz sirva la aplicación actual.
+
+## Comprobación de una clase
+
+1. Iniciar sesión con una invitación de estudiante.
+2. Abrir, ejecutar y entregar una tarea en cada lenguaje permitido.
+3. Confirmar que el borrador no se pierde al recargar.
+4. Revisar la entrega, solicitar cambios y aprobarla desde el panel.
+5. Confirmar el XP, feedback y repositorio privado de resoluciones.
+6. Revisar una pantalla de notebook y otra de celular.
+
+`/beta/` se conserva únicamente como redirección para enlaces antiguos.
diff --git a/docs/UX_AUDIT_AULA_3_3.md b/docs/UX_AUDIT.md
similarity index 99%
rename from docs/UX_AUDIT_AULA_3_3.md
rename to docs/UX_AUDIT.md
index 10173b9..469f539 100644
--- a/docs/UX_AUDIT_AULA_3_3.md
+++ b/docs/UX_AUDIT.md
@@ -1,4 +1,4 @@
-# Auditoría de interacción: Aula 3.3
+# Auditoría de interacción
## Objetivo
diff --git a/index.html b/index.html
index 8e341bd..5e298ca 100644
--- a/index.html
+++ b/index.html
@@ -5,7 +5,7 @@
@@ -53,7 +53,7 @@
"@context": "https://schema.org",
"@type": "Course",
"name": "Tomatin Code Lab",
- "description": "Ruta original de Programacion I y II con veinte misiones autocorregibles.",
+ "description": "Aula para aprender programación resolviendo misiones junto a un profesor.",
"inLanguage": "es-CL",
"provider": {
"@type": "Person",
diff --git a/manifest.webmanifest b/manifest.webmanifest
index 5b9215b..5988957 100644
--- a/manifest.webmanifest
+++ b/manifest.webmanifest
@@ -1,7 +1,7 @@
{
"name": "Tomatin Code Lab",
"short_name": "Tomatin Lab",
- "description": "Misiones originales de Programacion I y II con humor chileno.",
+ "description": "Aula para aprender programación resolviendo misiones junto a un profesor.",
"lang": "es-CL",
"start_url": "./",
"scope": "./",
@@ -17,4 +17,3 @@
}
]
}
-
diff --git a/package.json b/package.json
index 7ae9f68..211a6f4 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0",
"private": true,
"type": "module",
- "description": "Aula multilenguaje para practicar Programacion I y II.",
+ "description": "Aula para aprender programación resolviendo misiones junto a un profesor.",
"scripts": {
"dev": "vite --config v2/vite.config.ts",
"frontend": "pnpm frontend:build && VITE_FRONTEND_ONLY=true VITE_BASE_PATH=/ vite preview --config v2/vite.config.ts --host 127.0.0.1 --port 4173 --open /",
diff --git a/supabase/config.toml b/supabase/config.toml
index 8f5abac..c3db6ea 100644
--- a/supabase/config.toml
+++ b/supabase/config.toml
@@ -17,9 +17,11 @@ port = 54323
[auth]
enabled = true
-site_url = "http://localhost:5173/tomatin-code-lab/beta/"
+site_url = "https://eeminionn.github.io/tomatin-code-lab/"
additional_redirect_urls = [
- "http://localhost:5173/tomatin-code-lab/beta/",
+ "http://127.0.0.1:4173/tomatin-code-lab/",
+ "http://localhost:5173/tomatin-code-lab/",
+ "https://eeminionn.github.io/tomatin-code-lab/",
"https://eeminionn.github.io/tomatin-code-lab/beta/"
]
diff --git a/supabase/functions/notify-assignment/index.ts b/supabase/functions/notify-assignment/index.ts
index dd4e3c9..3bf3018 100644
--- a/supabase/functions/notify-assignment/index.ts
+++ b/supabase/functions/notify-assignment/index.ts
@@ -5,7 +5,7 @@ const DEFAULT_GITHUB_OWNER = "eeminionn";
const DEFAULT_GITHUB_REPOSITORY = "tomatin-code-lab";
const DEFAULT_GITHUB_ISSUE_NUMBER = "59";
const DEFAULT_APP_BASE_URL =
- "https://eeminionn.github.io/tomatin-code-lab/beta/#";
+ "https://eeminionn.github.io/tomatin-code-lab/#";
type DeliveryStatus = "pending" | "sent" | "partial" | "failed";
@@ -97,7 +97,7 @@ function commentBody(
assignmentUrl(slug, assignment.id)
})`,
"",
- "Tomatin Code Lab Aula 3.1 beta está en desarrollo.",
+ "Tarea enviada desde Tomatin Code Lab.",
]
.filter((line, index, lines) => line !== "" || lines[index - 1] !== "")
.join("\n")
diff --git a/v2/e2e/frontend-only.spec.ts b/v2/e2e/frontend-only.spec.ts
index 507b267..51f2b81 100644
--- a/v2/e2e/frontend-only.spec.ts
+++ b/v2/e2e/frontend-only.spec.ts
@@ -27,7 +27,7 @@ test("frontend sandbox keeps the current student UI without backend calls", asyn
const backendRequests = watchBackendRequests(page);
await page.goto("./");
- await expect(page.getByText("Sandbox local de Aula 3.0")).toBeVisible();
+ await expect(page.getByText("Sandbox local para contribuir")).toBeVisible();
await page.getByRole("button", { name: "Ver interfaz de estudiante" }).click();
await page.getByRole("button", { name: "Omitir", exact: true }).click();
await expect(
diff --git a/v2/index.html b/v2/index.html
index 5f513c7..3309fe6 100644
--- a/v2/index.html
+++ b/v2/index.html
@@ -5,12 +5,12 @@
- Tomatin Code Lab 3.0
+ Tomatin Code Lab
diff --git a/v2/playwright.config.ts b/v2/playwright.config.ts
index 11bd7fa..6227eb7 100644
--- a/v2/playwright.config.ts
+++ b/v2/playwright.config.ts
@@ -4,7 +4,7 @@ import { fileURLToPath, URL } from "node:url";
const frontendOnly = process.env.VITE_FRONTEND_ONLY === "true";
const serverUrl = frontendOnly
? "http://127.0.0.1:4173/"
- : "http://127.0.0.1:4173/tomatin-code-lab/beta/";
+ : "http://127.0.0.1:4173/tomatin-code-lab/";
export default defineConfig({
testDir: "./e2e",
diff --git a/v2/public/beta/index.html b/v2/public/beta/index.html
new file mode 100644
index 0000000..ab64874
--- /dev/null
+++ b/v2/public/beta/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ Redirigiendo a Tomatin Code Lab
+
+
+
+