From 0e3e0505e7847dce710280d5379f588ea974db6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manzo=20Olivares=20C=C3=A9sar=20Alberto?= Date: Sat, 12 Sep 2026 22:17:04 -0600 Subject: [PATCH 1/2] fix(ci): usa Node 24 para soportar node:sqlite El nuevo runtime SQL (src/lib/executor/sql-node-runtime.ts) requiere node:sqlite, no disponible en Node 20. CI fallaba con "Error: No such built-in module: node:sqlite". Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_015jsRquT4TUC9Wug9MMaPnR --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7db303..5be3eb7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 cache: npm - name: Install dependencies From 5e1d41953e26cbb8d2ed79cd2c75d2d6cabe8d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manzo=20Olivares=20C=C3=A9sar=20Alberto?= Date: Sat, 12 Sep 2026 22:17:09 -0600 Subject: [PATCH 2/2] test(content): actualiza contrato de Base de Datos II tras el handoff de Sprint 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sprint 2 agregó deliberadamente un step de handoff a 8 lecciones de S5 (create-procedure-mysql, jobs, grant-revoke, analizar-mysql, parametros, insert-mongodb, find-mongodb, update-delete-mongodb), llevando S5 de 180 a 188 steps y el curso completo de 368 a 376. El contrato seguía esperando los totales viejos y una regla ciega de "4 steps en toda lección", así que fallaba contra el contenido ya aprobado. Reemplaza esa regla ciega por una lista explícita de las 8 lecciones con handoff aprobado: esas deben tener exactamente 5 steps, y el resto de S5 conserva la exigencia original de exactamente 4. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_015jsRquT4TUC9Wug9MMaPnR --- tests/content/course-contract.test.ts | 31 +++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/tests/content/course-contract.test.ts b/tests/content/course-contract.test.ts index 4d45368..30d34de 100644 --- a/tests/content/course-contract.test.ts +++ b/tests/content/course-contract.test.ts @@ -767,19 +767,38 @@ describe("curso: Bases de datos (S4 Base de Datos I + S5 Base de Datos II)", () } }); - it("totales EXACTOS: 45 lessons, 180 steps, 15 practices", () => { + it("totales EXACTOS: 45 lessons, 188 steps, 15 practices", () => { expect(s5.unitSlugs.length).toBe(10); expect(bdLessonsOf(s5.unitSlugs)).toBe(45); - expect(bdStepsOf(s5.unitSlugs)).toBe(180); + expect(bdStepsOf(s5.unitSlugs)).toBe(188); expect(bdPracticesOf(s5.unitSlugs)).toBe(15); }); - it("cada lección tiene EXACTAMENTE 4 steps", () => { + /** + * Sprint 2 agregó un step de handoff a estas 8 lecciones puntuales + * (188 = 180 + 8). El resto de S5 conserva el contrato original de + * EXACTAMENTE 4 steps; sólo estas lecciones pueden tener 5. + */ + it("sólo las lecciones con handoff aprobado tienen 5 steps; el resto EXACTAMENTE 4", () => { + const HANDOFF_LESSONS = new Set([ + "bd2-11-procedimientos/create-procedure-mysql", + "bd2-12-triggers-jobs/jobs", + "bd2-14-usuarios-permisos/grant-revoke", + "bd2-15-mantenimiento/analizar-mysql", + "bd2-16-conexiones/parametros", + "bd2-19-mongodb-crud/insert-mongodb", + "bd2-19-mongodb-crud/find-mongodb", + "bd2-19-mongodb-crud/update-delete-mongodb", + ]); + let handoffSeen = 0; for (const slug of s5.unitSlugs) { for (const lesson of bdUnitBySlug.get(slug)!.lessons) { - expect(lesson.steps.length, `${slug}/${lesson.slug}`).toBe(4); + const key = `${slug}/${lesson.slug}`; + if (HANDOFF_LESSONS.has(key)) handoffSeen += 1; + expect(lesson.steps.length, key).toBe(HANDOFF_LESSONS.has(key) ? 5 : 4); } } + expect(handoffSeen).toBe(HANDOFF_LESSONS.size); }); it("sólo las 4 unidades con práctica independiente la declaran (triggers, transacciones, crud-interfaz, integrador)", () => { @@ -868,7 +887,7 @@ describe("curso: Bases de datos (S4 Base de Datos I + S5 Base de Datos II)", () ]); }); - it("totales del curso completo: 20 units, 92 lessons, 368 steps, 51 practices", () => { + it("totales del curso completo: 20 units, 92 lessons, 376 steps, 51 practices", () => { const lessons = bd.units.flatMap((u) => u.lessons); const steps = lessons.flatMap((l) => l.steps); const totalPractice = allPracticeSets @@ -877,7 +896,7 @@ describe("curso: Bases de datos (S4 Base de Datos I + S5 Base de Datos II)", () expect(bd.units.length).toBe(20); expect(lessons.length).toBe(92); - expect(steps.length).toBe(368); + expect(steps.length).toBe(376); expect(totalPractice).toBe(51); });