Aplicación que muestra tests para el estudio, que pueden ser Verdadero/Falso u Opción Múltiple. Los ficheros de preguntas están en formato JSON y se pueden editar fácilmente.
Usa Next.js con create-next-app y TypeScript, y la infrastructura en AWS usando S3, CloudFront y Cognito para autenticación.
La infrastructura contiene tests unitarios con Jest, y el frontend también contiene tests end-to-end con Playwright.
La aplicación incluye:
- Autenticación con Google OAuth para sincronizar progreso entre dispositivos
- Modo invitado para uso local sin registro
- Almacenamiento persistente del progreso del usuario
Los resultados se almacenan en el LocalStorage del navegador (modo invitado) o se sincronizan en la nube (usuarios autenticados).
npm run buildEsto generará un directorio out/ con todos los archivos estáticos que puedes subir al bucket S3. Excluye los siguientes archivos y directorios:
node_modules/
src/
data/
.git/
*.config.* (e.g., next.config.ts, postcss.config.mjs, etc.)
package.json, package-lock.json, tsconfig.json, README.md, etc.Las variables de entorno para cada proyecto se esperan en ficheros .env. env.development.local para desarrollo local, .env.production para producción, y .env.test para tests, incluidos los end-to-end con Playwright. Se incluye un fichero .env.example como referencia.
El contenido de los .env debería incluir al menos:
# Subcarpeta desde donde se sirve la aplicación web
NEXT_PUBLIC_BASE_PATH=/studio
# Base URL donde se sirven los JSON de datos (S3/CloudFront o servidor local)
# Ejemplos:
# - Producción: https://studio-data.humblyproud.com (o /studio-data si va bajo el mismo dominio)
# - Desarrollo local: http://localhost:4173
NEXT_PUBLIC_DATA_BASE_URL=
# Nombre del fichero JSON con las áreas de estudio, el punto de partida de las preguntas de test.
NEXT_PUBLIC_AREAS_FILE=areas.json
# Idioma por defecto de la UI (es | en | ca)
NEXT_PUBLIC_DEFAULT_LANGUAGE=es
# Habilita selector de idioma en UI (true | false)
# En Phase 1 se mantiene en false.
NEXT_PUBLIC_LANGUAGE_SELECTION_ENABLED=false
# Variables de entrorno para AWS Cognito (autenticación)
NEXT_PUBLIC_COGNITO_USER_POOL_ID=
NEXT_PUBLIC_COGNITO_CLIENT_ID=
NEXT_PUBLIC_COGNITO_DOMAIN=
NEXT_PUBLIC_REDIRECT_SIGN_IN=https://domain.com/studio
NEXT_PUBLIC_REDIRECT_SIGN_OUT=https://domain.com/studio
# Opcional: fuerza comportamiento de login (login, select_account)
NEXT_PUBLIC_COGNITO_PROMPT=
# El tracking ID de Google Analytics 4 o el texto 'disabled' para desactivar analytics
NEXT_PUBLIC_GA_TRACKING_ID=G-XXXXXXXXXX```NEXT_PUBLIC_DEFAULT_LANGUAGE: idioma inicial de la aplicación. Valores soportados:es,en,ca.
Si el valor es inválido o falta, se usaes.NEXT_PUBLIC_LANGUAGE_SELECTION_ENABLED: habilita o deshabilita el selector de idioma en la interfaz (true/false).
En la fase actual del rollout se recomiendafalse.
En desarrollo puedes servir los JSON de learning-studio-data con un servidor estático local y apuntar el frontend a ese host.
Ejecuta:
cd frontend
npm run dev:dataEsto sirve los datos en http://localhost:4173. En .env.development.local:
NEXT_PUBLIC_DATA_BASE_URL=http://localhost:4173En NODE_ENV=development, existe un endpoint local GET/PUT /api/learning-state implementado por Next.js para validar lectura/escritura real en DynamoDB sin desplegar CloudFront/Lambda@Edge.
El frontend permite activar/desactivar acceso a DynamoDB para controlar coste en desarrollo:
NEXT_PUBLIC_STORAGE_MODE=local|dynamodb|hybrid:localusa sololocalStorage,dynamodbusa lectura/escritura remota,hybridlee remoto y guarda local (escritura remota opcional).NEXT_PUBLIC_ENABLE_DYNAMODB=true|false: interruptor global para cortar cualquier llamada remota.NEXT_PUBLIC_SYNC_WRITES=true|false: enhybrid, habilita/deshabilita escrituras remotas.NEXT_PUBLIC_MAX_DDB_CALLS_PER_SESSION=<n>: presupuesto máximo de llamadas remotas por sesión de navegador.NEXT_PUBLIC_STUDIO_LEARNING_STATE_TABLE=<name>(opcional) : nombre de tabla solo para logging del cliente.NEXT_PUBLIC_DYNAMODB_LOG_ENABLED=true|false(opcional) : habilita logs de diagnóstico de llamadas DynamoDB en consola del navegador.
Por defecto:trueendevelopment,falseentestyproduction.
Ejemplo recomendado para desarrollo sin coste:
NEXT_PUBLIC_STORAGE_MODE=local
NEXT_PUBLIC_ENABLE_DYNAMODB=false
NEXT_PUBLIC_MAX_DDB_CALLS_PER_SESSION=50Ejemplo para experimentar lecturas reales sin escrituras:
NEXT_PUBLIC_STORAGE_MODE=hybrid
NEXT_PUBLIC_ENABLE_DYNAMODB=true
NEXT_PUBLIC_SYNC_WRITES=false
NEXT_PUBLIC_MAX_DDB_CALLS_PER_SESSION=100Si NEXT_PUBLIC_DYNAMODB_LOG_ENABLED=true, cada llamada remota queda trazada en consola con op, table, pk y sk.
Requisitos:
- Credenciales AWS válidas en tu entorno local.
- Variables para tabla/región (si no usas los defaults):
:
STUDIO_LEARNING_STATE_TABLE,STUDIO_LEARNING_STATE_REGION - Opcional para tabla admin de identidad:
:
STUDIO_USER_IDENTITY_ADMIN_TABLE,STUDIO_USER_IDENTITY_ADMIN_REGION
Fuera de development, este endpoint local devuelve 404.
Las áreas que ve un usuario invitado se pueden limitar desde el JSON de áreas (el fichero indicado por NEXT_PUBLIC_AREAS_FILE).
Campo opcional:
guestAllowedAreaShortNames: array ordenado deshortNamepermitidos para invitados.
Ejemplo:
{
"schemaVersion": 1,
"updatedAt": "2026-02-25",
"guestAllowedAreaShortNames": ["log1", "ipc"],
"areas": [
{
"area": "Lógica I",
"file": "questions-logica1.json",
"type": "True False",
"shortName": "log1"
},
{
"area": "Introducción al Pensamiento Científico",
"file": "questions-ipc.json",
"type": "Multiple Choice",
"shortName": "ipc"
},
{
"area": "Filosofía del Lenguaje I",
"file": "questions-fdl.json",
"type": "Multiple Choice",
"shortName": "fdl"
}
]
}Comportamiento:
- Si
guestAllowedAreaShortNamesexiste y tiene valores válidos, invitados verán solo esas áreas en ese orden. - Si no existe (o queda vacío), invitados verán todas las áreas definidas en
areas. - Usuarios autenticados no usan este campo: pueden configurar su propia lista y orden desde
Configurar áreas.
Si gestionas manualmente el App Client de Cognito y quieres versionar su configuración en el repo:
- Exportar configuración live a snapshot:
npm run cognito:pull- Ver diferencias snapshot vs live:
npm run cognito:diff- Aplicar snapshot al App Client live:
npm run cognito:pushDetalles:
- Snapshot por defecto:
infra/config/cognito-user-pool-client.json. - Los scripts leen por defecto
frontend/.env.production.localy luegofrontend/.env.production. - Reutiliza automáticamente
NEXT_PUBLIC_COGNITO_USER_POOL_ID,NEXT_PUBLIC_COGNITO_CLIENT_IDyNEXT_PUBLIC_AWS_REGION. - Variables de shell (
COGNITO_USER_POOL_ID,COGNITO_USER_POOL_CLIENT_ID,AWS_REGION) tienen prioridad si las defines. - Puedes cambiar la ruta con
COGNITO_SNAPSHOT_PATH. - Recomendado: después de cambios manuales en AWS Console, ejecutar
cognito:pully commitear el snapshot.
Para imprimir el pk exacto (USER#<sub>) del usuario actual y un comando de borrado:
npm run jwt:pk -- --jwt '<id_token>'También acepta un JSON con campo jwt, token o id_token:
npm run jwt:pk -- --file /ruta/al/archivo.jsonOpcionalmente, si usas tabla/región no estándar:
npm run jwt:pk -- --jwt '<id_token>' --table studio-learning-state --region eu-west-2El backend puede mantener una tabla de soporte con el último email conocido por sub para tareas administrativas (sin mezclarlo en el estado de aprendizaje del usuario).
Variables para runtime de edge auth:
STUDIO_USER_IDENTITY_ADMIN_TABLE(ejemplo:studio-user-identity-admin)STUDIO_USER_IDENTITY_ADMIN_REGION(ejemplo:eu-west-2)
- El tracking respeta la privacidad del usuario
- No se almacena información personal identificable