Files
ACVE/resumen_cambios.md
2026-03-15 13:52:11 +00:00

298 lines
11 KiB
Markdown

# 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 Course` por `Continue` cuando 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:
- `translation`
- `term-matching`
- `contract-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.ts`
- `types/practice.ts`
- `app/(protected)/practice/[slug]/actions.ts`
- `app/(protected)/practice/[slug]/page.tsx`
- `lib/recommendations.ts`
- `app/(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.ts`
- `app/(protected)/profile/page.tsx`
- `app/(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.ts`
- `app/api/certificates/[id]/pdf/route.ts`
- `app/(protected)/courses/[slug]/learn/actions.ts`
- `app/(protected)/profile/page.tsx`
- `app/(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`
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 Courses`
- `Profile`
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:
- `summaryEs`
- `legalOutcomeEs`
- `category`
- `difficulty`
- `keyTerms` estructurado (termino + definicion)
- `quizPrompt`
- Se actualizaron lista y detalle para mostrar contenido legal en espanol.
Archivos:
- `types/caseStudy.ts`
- `lib/data/mockCaseStudies.ts`
- `app/(public)/case-studies/page.tsx`
- `app/(public)/case-studies/[slug]/page.tsx`
---
## 3) Cambios de datos (Prisma schema)
Se actualizaron modelos en `prisma/schema.prisma`:
- Nuevos:
- `MiniGame`
- `MiniGameQuestion`
- `MiniGameAttempt`
- `StudyRecommendation`
- 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)
Seed actualizado:
- `prisma/seed.ts` para 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`.
## 4.2 Fix aplicado
- Se trabajo con Node `24.14.0`.
- Se agrego `.nvmrc` con `24`.
- Se reinstalaron dependencias (`npm ci`).
- Se agregaron scripts Prisma en `package.json`:
- `prisma:generate`
- `prisma:status`
- `prisma:migrate:dev`
- `prisma:migrate:deploy`
- `prisma:seed`
- Se corrigio `prisma.config.ts` seed command:
- `npx ts-node prisma/seed.ts`
## 4.3 Baseline y drift en Supabase
- No existia `prisma/migrations` historico 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.md`
- `resumen_cambios.md`
- `app/(protected)/my-courses/page.tsx`
- `app/(protected)/profile/page.tsx`
- `app/(protected)/practice/[slug]/actions.ts`
- `app/api/certificates/[id]/pdf/route.ts`
- `lib/certificates.ts`
- `lib/recommendations.ts`
---
## 6) Validaciones ejecutadas
Se ejecutaron en distintos momentos:
- `npm run lint` -> OK
- `npx tsc --noEmit` -> OK
- `npm 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
1. Limpiar migracion baseline invalida:
- revisar si se debe eliminar `prisma/migrations/20260225_baseline` del historial.
2. Confirmar estrategia de migraciones por entorno:
- `migrate dev` solo en DB de desarrollo.
- `migrate deploy` en staging/prod.
3. Mejorar UI de certificado/modal:
- plantilla de certificado con branding final.
- polish de animacion/confetti.
4. QA end-to-end:
- flujo completo desde completar curso hasta ver certificado en `Profile` y `My Courses`.
5. Verificar consistencia en Supabase:
- mantener `DATABASE_URL` (pooler) para runtime app.
- mantener `DIRECT_URL` (5432) para Prisma migrate.
---
## 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 `/courses` al guardar un curso.
- **Solución:** En la acción `updateCourse` se 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 `TeacherEditCourseForm` se le pasó un `key` que incluye `course.updatedAt` para forzar un nuevo montaje cuando cambian los datos del curso y así aplicar los nuevos `defaultValue`.
- Tras guardar con éxito se reemplazó `router.refresh()` por `router.push(\`/teacher/courses/${course.slug}/edit\`)` para forzar una navegación y cargar datos frescos.
- **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]/learn`** a **`app/(public)/courses/[slug]/learn`** (page + actions) para que no quede detrás de un layout que exija autenticación.
- Se actualizó el import en `StudentClassroomClient` para usar las acciones en la nueva ruta pública.
- En la página de detalle del curso (landing):
- Se incluyó `isFreePreview` en 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" con `redirectTo=/courses/[slug]` para que tras iniciar sesión vuelvan a la ficha y puedan inscribirse/comprar.
- **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 bajo `app/(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.
- **Archivos:** `app/(protected)/teacher/actions.ts`, `components/teacher/TeacherEditCourseForm.tsx`.