Files
mercadodevida/work/artifacts/TPV-DEV-IN-PROD/reviewer.json

113 lines
6.3 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"feature_id": "TPV-DEV-IN-PROD",
"verdict": "APPROVED",
"reviewer": "reviewer",
"reviewed_at": "2026-08-27T21:13:00Z",
"scope": [
"project/scripts/monolith.sh",
"docs/HOWTO-monolith.md",
"docs/pos/POS_OPERATIONS.md"
],
"summary": "Smoke test post-arranque añadido a monolith.sh detecta con tres dimensiones independientes (HTML markers, endpoint /_next/hmr, banner (Turbopack)) si un servicio Next está sirviendo `next dev` en lugar de `next start`. Cobertura transversal a los 4 servicios Next (admin, tpv, frontend, storefront). Documentación endurecida con sección §3.1 de errores comunes + runbook de recuperación en HOWTO-monolith, y nota inline en POS_OPERATIONS §1.3. Acepto el fix.",
"checks": [
{
"id": "syntax",
"description": "Bash syntax valid",
"command": "bash -n project/scripts/monolith.sh",
"result": "PASS",
"evidence": "Exit code 0. Sin errores."
},
{
"id": "function-extractable",
"description": "Función smoke_check_no_dev_markers definida y extraíble",
"command": "awk '/^smoke_check_no_dev_markers\\(\\)/,/^}/' project/scripts/monolith.sh",
"result": "PASS",
"evidence": "Bloque de 53 líneas extraído correctamente; firma `smoke_check_no_dev_markers() { … return 0; }`."
},
{
"id": "mock-dev-fails",
"description": "Mock con HTML HMR marker + 200 en /_next/hmr → smoke debe fallar",
"command": "python3 mock en :30999 + smoke_check_no_dev_markers",
"result": "PASS",
"evidence": "Salida: '[FAIL] mock root HTML contains dev-only marker: /__next_hmr' + '[FAIL] mock /_next/hmr returned HTTP 200 (expected 404 or 426)' + 'exit=1'."
},
{
"id": "mock-prod-ok",
"description": "Mock con HTML limpio + 404 en /_next/hmr → smoke debe pasar",
"command": "python3 mock en :30994 + smoke_check_no_dev_markers",
"result": "PASS",
"evidence": "Salida: '[OK] All Next.js services are HMR-free (prod start confirmed). exit=0'."
},
{
"id": "docs-coverage",
"description": "Documentación cubre señales, runbook y checklist",
"command": "grep -nE '^### 3\\.1|^## 6\\.|3\\.1 Errores comunes' docs/HOWTO-monolith.md",
"result": "PASS",
"evidence": "§3.1 añadida con 4 sub-bloques (por qué, señales, runbook, post-fail). §6 incluye nuevo bloque 'Comprobaciones adicionales anti-dev'. POS_OPERATIONS §1.3 incluye bloque de advertencia."
},
{
"id": "scope-discipline",
"description": "No se modifica nada fuera del scope acordado",
"command": "git diff --stat project/scripts/monolith.sh docs/",
"result": "PASS",
"evidence": "Solo 3 archivos: project/scripts/monolith.sh (+79), docs/HOWTO-monolith.md (+63/-1), docs/pos/POS_OPERATIONS.md (+2/-0). Cero cambios en next.config.ts, package.json, proxy.ts, ni archivos fuera del scope."
},
{
"id": "set-e-safety",
"description": "Interacción correcta con set -euo pipefail",
"command": "code review",
"result": "PASS",
"evidence": "Llamada envuelta en `if ! smoke_check_no_dev_markers; then … exit 1; fi`. El operador `!` neutraliza errexit. `stop_all` retorna 0 en todas las ramas (stop_pid devuelve 0 incluso con pid vacío). `exit 1` final se ejecuta siempre si la condición se cumple."
},
{
"id": "redirect-chain-handling",
"description": "Comportamiento correcto ante redirect / → /login del proxy.ts",
"command": "code review",
"result": "PASS",
"evidence": "TPV proxy.ts redirige `/` no autenticado a `/login`. La página /login es server-rendered Next prod sin markers HMR. Curl con `-fsS` sigue el redirect y obtiene HTML de /login. grep -qF sobre ese HTML no encuentra markers → pasa. Si un dev server estuviera activo, inyectaría HMR en /login también → el smoke lo detectaría vía redirect chain."
},
{
"id": "performance",
"description": "Overhead aceptable del smoke",
"command": "estimación + 2 mocks ejecutados",
"result": "PASS",
"evidence": "4 servicios × (curl --max-time 5 + grep) ≈ 20s worst case. En estado saludable (<100ms por curl) el smoke termina en <500ms. Despreciable vs build."
},
{
"id": "no-new-deps",
"description": "Cero dependencias nuevas",
"command": "grep -nE 'apt|yarn add|npm i|brew install' project/scripts/monolith.sh docs/",
"result": "PASS",
"evidence": "Solo bash builtins (printf, grep, head, local), curl (ya usado por wait_http). Sin nuevas dependencias."
}
],
"findings": [],
"nits": [
{
"id": "nit-1",
"severity": "info",
"description": "El smoke test cubre 4 servicios Next secuencialmente. Para deploys con muchos servicios podría paralelizarse con `&` + `wait`. Aceptable hoy porque el coste es ~500ms; revisar si se añaden más apps Next.",
"suggested_action": "Monitorizar. No bloquea el fix."
},
{
"id": "nit-2",
"severity": "info",
"description": "`local service port url log body hmr_code marker failed=0` mezcla declaración sin valor y asignación en la misma línea. Sintaxis válida; estilo alternativo es declarar primero y asignar después.",
"suggested_action": "Estilo OK, no requiere cambio."
},
{
"id": "nit-3",
"severity": "info",
"description": "El bloque §3.1 de HOWTO-monolith menciona 'WebSocket /_next/hmr' como señal observable. Un operador sin acceso al DevTools del navegador podría no saber dónde mirar.",
"suggested_action": "Añadir en una iteración futura un comando `curl -i https://tpv-mv.rikrdo.com/_next/hmr` con la salida esperada como referencia. No bloquea."
}
],
"verdict_rationale": "El fix cumple el objetivo del ticket con tres capas de defensa (smoke test en 3 dimensiones, documentación operativa, runbook de recuperación). Verificación funcional contra mocks controlados confirma que el smoke detecta dev servers y deja pasar prod servers. La sintaxis bash es válida; la interacción con `set -e` es correcta. Scope respetado: cero cambios fuera de los 3 archivos acordados. Verdict: APPROVED.",
"evidence_paths": [
"work/artifacts/TPV-DEV-IN-PROD/architect.md",
"work/artifacts/TPV-DEV-IN-PROD/implementer.md",
"project/scripts/monolith.sh (líneas 368-435)",
"docs/HOWTO-monolith.md (§3.1 + §6)",
"docs/pos/POS_OPERATIONS.md (§1.3)"
]
}