78 lines
3.4 KiB
JSON
78 lines
3.4 KiB
JSON
{
|
|
"feature_id": "F-136",
|
|
"agent": "reviewer",
|
|
"stage": "review_gate",
|
|
"verdict": "APPROVED",
|
|
"reviewed_at": "2026-08-21T19:09:30Z",
|
|
"summary": "Cambio limpio y bien acotado: helper puro con tests + migración idempotente de datos. El helper maneja correctamente Title Case con regla española de conjunciones (y/e/o/u), preserva puntuación y respeta mixed-case. La migración normalizó 28/33 marcas, dejó 5 mixed-case intactas, y re-ejecución es no-op.",
|
|
"checks": [
|
|
{
|
|
"item": "Helper toTitleCase implementado y exportado",
|
|
"ok": true,
|
|
"evidence": "src/shared/text.ts: nueva función pura con JSDoc + ejemplos"
|
|
},
|
|
{
|
|
"item": "Helper cubre los edge cases del operador: ALL CAPS, multi-word, dot/ampersand, acentos",
|
|
"ok": true,
|
|
"evidence": "15/15 tests pass en src/shared/tests/text.test.ts; casos incluyen A.VOGEL, COMPLEMENTOS Y NUTRICIÓN, EL GRANERO INTEGRAL, etc."
|
|
},
|
|
{
|
|
"item": "Regla de conjunciones españolas (y/e/o/u lowercase) aplicada",
|
|
"ok": true,
|
|
"evidence": "Tests 'AGUA Y SAL' → 'Agua y Sal' y 'PADRE E HIJO' → 'Padre e Hijo'; output DB muestra 'Complementos y Nutrición'"
|
|
},
|
|
{
|
|
"item": "Helper idempotente: no destruye mixed-case",
|
|
"ok": true,
|
|
"evidence": "Test 'BioSana' → 'BioSana'; DB muestra BioSana, EcoVida, NaturGreen, SolNatural, TierraNatural sin tocar"
|
|
},
|
|
{
|
|
"item": "Migración 042 aplica correctamente la transformación",
|
|
"ok": true,
|
|
"evidence": "Output: 'F-136: updated 28 brand row(s) (of 33 total)'; SELECT muestra 0 ALL CAPS y 0 seo_title vacíos"
|
|
},
|
|
{
|
|
"item": "Slugs preservados (lowercase)",
|
|
"ok": true,
|
|
"evidence": "SELECT slug,name muestra pares como ('a-vogel','A.Vogel'), ('biocop','Biocop'), ('complementos-y-nutricion','Complementos y Nutrición')"
|
|
},
|
|
{
|
|
"item": "Migración idempotente",
|
|
"ok": true,
|
|
"evidence": "node-pg-migrate up (re-run) reporta 'No migrations to run!' — pgmigrations ya tiene la fila"
|
|
},
|
|
{
|
|
"item": "Migración self-contained (no depende de build)",
|
|
"ok": true,
|
|
"evidence": "migrations/042_brand_title_case.js inline la lógica de toTitleCase con comentario explicando el duplicado deliberado"
|
|
},
|
|
{
|
|
"item": "Backend typecheck verde",
|
|
"ok": true,
|
|
"evidence": "npx tsc --noEmit → exit 0"
|
|
},
|
|
{
|
|
"item": "ESLint verde (helper + tests + migration)",
|
|
"ok": true,
|
|
"evidence": "npx eslint src/shared/text.ts src/shared/tests/text.test.ts migrations/042_brand_title_case.js → exit 0, 0 warnings"
|
|
},
|
|
{
|
|
"item": "Tests verdes",
|
|
"ok": true,
|
|
"evidence": "npx vitest run src/shared/tests/text.test.ts → 15/15 passed"
|
|
},
|
|
{
|
|
"item": "Sin cambios de API ni de tipos exportados al admin",
|
|
"ok": true,
|
|
"evidence": "git diff solo toca src/shared/text.ts, src/shared/tests/text.test.ts, migrations/042_brand_title_case.js"
|
|
},
|
|
{
|
|
"item": "Sin código del admin modificado (auto-fill ya funcionaba)",
|
|
"ok": true,
|
|
"evidence": "apps/admin/src/app/(dashboard)/brands/page.tsx no aparece en el diff"
|
|
}
|
|
],
|
|
"issues": [],
|
|
"notes": "Migración destructiva en sentido figurado (ALL CAPS → Title Case) sin rollback automático. Documentado en el implementer.md. Si el operador pide revertir, sería con script ad-hoc usando el log de git."
|
|
}
|