11 KiB
11 KiB
Resumen de Cambios (25/02/26)
Marcelo
Fecha de trabajo: 2026-02-25
Proyecto: /opt/ACVE
1) Objetivo de la sesion
Implementar el backlog solicitado:
- Mas mini-games con calificacion ligada al perfil.
- Recomendaciones de estudio por perfil/progreso.
- Certificados al completar curso.
- Ver cursos inscritos (
enrolled). - Cambiar
Start CourseporContinuecuando ya esta inscrito. - Actualizar Case Studies con contenido de Andres.
Tambien se resolvio operativa de entorno para Prisma/Node y baseline de migraciones sobre Supabase.
2) Features implementadas
2.1 Mini-games (3 interactivos) + persistencia + perfil
- Se expandieron los mini-games a 3 modulos interactivos:
translationterm-matchingcontract-clauses
- Se paso de historial localStorage a acciones server-side con persistencia DB (si tablas ya migradas).
- Se agrego calculo de calificacion global de mini-games para perfil (promedio de ultimo intento por juego).
Archivos:
lib/data/mockPractice.tstypes/practice.tsapp/(protected)/practice/[slug]/actions.tsapp/(protected)/practice/[slug]/page.tsxlib/recommendations.tsapp/(protected)/profile/page.tsx
2.2 Recomendaciones de estudio (deterministicas)
- Se implemento motor de recomendaciones por reglas:
- basado en score de mini-games y progreso/cursos.
- prioriza cursos ya inscritos e incompletos.
- fallback por nivel objetivo (beginner/intermediate/advanced).
- Se muestra bloque “Recommended next” en perfil.
Archivos:
lib/recommendations.tsapp/(protected)/profile/page.tsxapp/(protected)/courses/[slug]/learn/actions.ts(refresh de recomendaciones al completar leccion)
2.3 Certificados automáticos + descarga PDF
- Emision automatica al llegar a 100% de lecciones completadas (idempotente por curso/usuario).
- Endpoint de descarga PDF:
/api/certificates/[id]/pdf
- Integracion en:
Profile(listado de certificados)My Courses(download cuando existe certificado)
Archivos:
lib/certificates.tsapp/api/certificates/[id]/pdf/route.tsapp/(protected)/courses/[slug]/learn/actions.tsapp/(protected)/profile/page.tsxapp/(protected)/my-courses/page.tsx
2.4 UX: completion modal + confetti + CTA de certificado
- Al completar curso por primera vez (cuando se emite certificado nuevo):
- aparece modal de “Course completed”
- animacion de confetti
- boton
Download PDF - boton
Open Profile
Archivo:
components/courses/StudentClassroomClient.tsx
2.5 Vista de cursos inscritos
- Nueva ruta protegida:
/my-courses
- Muestra progreso por curso, CTA
Continue/Review, y descarga de certificado si aplica.
Archivo:
app/(protected)/my-courses/page.tsx
2.6 Cambio Start -> Continue
- En detalle de curso (
/courses/[slug]):- si usuario inscrito:
Continue - si no inscrito:
Start Course - no autenticado:
Login to start
- si usuario inscrito:
Archivo:
app/(public)/courses/[slug]/page.tsx
2.7 Profile del alumno
- Nueva ruta protegida:
/profile
- Incluye:
- score mini-games
- desglose latest/best por mini-game
- recomendaciones
- certificados + descarga
Archivo:
app/(protected)/profile/page.tsx
2.8 Navbar
- Se agregaron enlaces para usuario autenticado:
My CoursesProfile
Archivo:
components/Navbar.tsx
2.9 Case Studies actualizados con Andres
- Se reemplazo contenido mock por:
- Marbury v. Madison
- Miranda v. Arizona
- Brown v. Board of Education
- Se modelaron campos nuevos:
summaryEslegalOutcomeEscategorydifficultykeyTermsestructurado (termino + definicion)quizPrompt
- Se actualizaron lista y detalle para mostrar contenido legal en espanol.
Archivos:
types/caseStudy.tslib/data/mockCaseStudies.tsapp/(public)/case-studies/page.tsxapp/(public)/case-studies/[slug]/page.tsx
3) Cambios de datos (Prisma schema)
Se actualizaron modelos en prisma/schema.prisma:
-
Nuevos:
MiniGameMiniGameQuestionMiniGameAttemptStudyRecommendation- enum
MiniGameDifficulty
-
Ajustes:
Certificate:certificateNumber(unique)pdfVersion@@unique([userId, courseId])
Profile:- relaciones a mini-games/recomendaciones
Course:- relacion inversa
recommendations StudyRecommendation[](se corrigio tras error P1012)
- relacion inversa
Seed actualizado:
prisma/seed.tspara sembrar 3 mini-games y preguntas.
4) Node 24+ / Prisma / Supabase (incidentes y fix)
4.1 Problema detectado
- En Node
18.19.1, Prisma CLI (v7.3.0) fallaba con:ERR_REQUIRE_ESM(zeptomatch / @prisma/dev)
- Resultado:
- no funcionaba correctamente
prisma generate/migrate.
- no funcionaba correctamente
4.2 Fix aplicado
- Se trabajo con Node
24.14.0. - Se agrego
.nvmrccon24. - Se reinstalaron dependencias (
npm ci). - Se agregaron scripts Prisma en
package.json:prisma:generateprisma:statusprisma:migrate:devprisma:migrate:deployprisma:seed
- Se corrigio
prisma.config.tsseed command:npx ts-node prisma/seed.ts
4.3 Baseline y drift en Supabase
- No existia
prisma/migrationshistorico en repo. - Se intento baseline inicial con comando viejo (
--to-url) y genero SQL vacio. - Se corrigio usando Prisma 7:
--to-config-datasource
- Se genero baseline real (
~8148 bytes) y se marco aplicado. - Estado final reportado:
Database schema is up to date!
Nota:
- Hubo dos carpetas baseline:
20260225_baseline(invalida / vacia)20260225_baseline_v2(valida)
5) Archivos nuevos creados
task_implementation.mdresumen_cambios.mdapp/(protected)/my-courses/page.tsxapp/(protected)/profile/page.tsxapp/(protected)/practice/[slug]/actions.tsapp/api/certificates/[id]/pdf/route.tslib/certificates.tslib/recommendations.ts
6) Validaciones ejecutadas
Se ejecutaron en distintos momentos:
npm run lint-> OKnpx tsc --noEmit-> OKnpm run build-> compilacion/lint/types OK en varios intentos; hubo un fallo intermitente de worker de Next durante static generation sin stack especifico en esta sesion.npm run prisma:generate-> OK (Node 24)npm run prisma:status-> OK tras baseline correcto
7) Estado funcional actual
- Certificado automatico: funcionando.
- Descarga PDF: funcionando.
- Modal de finalizacion + confetti: funcionando.
- Profile muestra certificados/recomendaciones: implementado.
- My Courses: implementado.
- Case Studies actualizados: implementado.
Observacion de UX:
- El diseno del certificado actual es basico/tecnico (no final de branding visual).
8) Implicaciones y pendientes recomendados
-
Limpiar migracion baseline invalida:
- revisar si se debe eliminar
prisma/migrations/20260225_baselinedel historial.
- revisar si se debe eliminar
-
Confirmar estrategia de migraciones por entorno:
migrate devsolo en DB de desarrollo.migrate deployen staging/prod.
-
Mejorar UI de certificado/modal:
- plantilla de certificado con branding final.
- polish de animacion/confetti.
-
QA end-to-end:
- flujo completo desde completar curso hasta ver certificado en
ProfileyMy Courses.
- flujo completo desde completar curso hasta ver certificado en
-
Verificar consistencia en Supabase:
- mantener
DATABASE_URL(pooler) para runtime app. - mantener
DIRECT_URL(5432) para Prisma migrate.
- mantener
9) Resumen ejecutivo
- Se implementaron todos los ejes funcionales del backlog.
- Se desbloqueo el problema estructural de Prisma (Node 18 -> Node 24).
- Se normalizo flujo de migraciones con baseline real en Supabase.
- Ya existe flujo real de completion + certificado + descarga + visibilidad en perfil/cursos.
Daniel
Resumen de cambios (sesión 25/02/26)
1) Catálogo y publicación de cursos
- Problema: Los cursos publicados no aparecían de inmediato en el catálogo y hacía falta refrescar la página a mano.
- Causa: No se revalidaba la ruta pública
/coursesal guardar un curso. - Solución: En la acción
updateCoursese agregórevalidatePath("/courses")y revalidación con"page"y"layout"para la página de edición del curso, para que el catálogo y el formulario de edición muestren datos actualizados sin refrescar.
2) Estado y nivel del curso que volvían a valores anteriores al guardar
- Problema: Al cambiar Estado (Borrador → Publicado) o Nivel (p. ej. Intermedio → Principiante) y dar "Guardar Cambios", el formulario seguía mostrando el valor anterior hasta hacer un refresco manual.
- Causas: (1) Los inputs de nivel y estado son no controlados (
defaultValue); React no actualiza el valor en re-renders. (2)router.refresh()a veces seguía sirviendo una versión en caché del RSC. - Soluciones:
- En la página de edición del curso se puso
export const dynamic = "force-dynamic"para no cachear la ruta. - Al componente
TeacherEditCourseFormse le pasó unkeyque incluyecourse.updatedAtpara forzar un nuevo montaje cuando cambian los datos del curso y así aplicar los nuevosdefaultValue. - Tras guardar con éxito se reemplazó
router.refresh()porrouter.push(\/teacher/courses/${course.slug}/edit`)` para forzar una navegación y cargar datos frescos.
- En la página de edición del curso se puso
- Archivos:
app/(protected)/teacher/actions.ts,app/(protected)/teacher/courses/[slug]/edit/page.tsx,components/teacher/TeacherEditCourseForm.tsx.
3) Vista previa gratuita para usuarios sin sesión
- Objetivo: Que los usuarios no autenticados puedan ver lecciones marcadas como "free preview" y que en la ficha del curso se indique cuáles son y se ofrezca un CTA para verlas.
- Cambios:
- Se movió la ruta de aprendizaje de
app/(protected)/courses/[slug]/learnaapp/(public)/courses/[slug]/learn(page + actions) para que no quede detrás de un layout que exija autenticación. - Se actualizó el import en
StudentClassroomClientpara usar las acciones en la nueva ruta pública. - En la página de detalle del curso (landing):
- Se incluyó
isFreePreviewen la consulta de lecciones. - En "Course structure preview" se muestra un indicador "Free preview" (pill amarillo) en las lecciones que lo son.
- Para invitados: si hay al menos una lección en free preview, se muestra el botón principal "Watch free preview" con enlace a
/courses/[slug]/learn?lesson=[id], y como secundario "Login to unlock all lessons" conredirectTo=/courses/[slug]para que tras iniciar sesión vuelvan a la ficha y puedan inscribirse/comprar.
- Se incluyó
- Se movió la ruta de aprendizaje de
- Archivos:
app/(public)/courses/[slug]/learn/page.tsx,app/(public)/courses/[slug]/learn/actions.ts,app/(public)/courses/[slug]/page.tsx,components/courses/StudentClassroomClient.tsx. Eliminados los archivos bajoapp/(protected)/courses/[slug]/learn/.
4) Botón "Editar Título" en módulos
- Problema: El botón "Editar Título" en cada módulo del plan de estudios no hacía nada.
- Solución:
- Nueva acción de servidor
updateModuleTitle(moduleId, title)en teacher actions: valida que el módulo sea del profesor, actualiza el título en BD y revalida las rutas correspondientes. - En el formulario de edición del curso: al hacer clic en "Editar Título" se muestra un campo de texto inline con el título actual y botones "Guardar" y "Cancelar"; Enter guarda, Escape cancela. Tras guardar se navega a la misma página de edición para ver el título actualizado.
- Nueva acción de servidor
- Archivos:
app/(protected)/teacher/actions.ts,components/teacher/TeacherEditCourseForm.tsx.