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

141 lines
7.7 KiB
JSON

{
"feature_id": "TPV-DEV-IN-PROD",
"verdict": "APPROVED",
"qa": "qa",
"reviewed_at": "2026-08-27T21:15:30Z",
"scope": [
"project/scripts/monolith.sh",
"docs/HOWTO-monolith.md",
"docs/pos/POS_OPERATIONS.md",
"backlog/features.json"
],
"summary": "Los 8 criterios de aceptación del diseño son verificables y verificables. Trazabilidad 1:1 entre cada AC y su evidencia (bash -n, mocks, code review, verify.sh). Sin regresiones: dev mode unchanged, prod mode añade guard, otros comandos (status/logs/stop/urls/watch) intactos. Verdict: APPROVED.",
"acceptance_traceability": [
{
"id": "AC1",
"criterion": "bash -n project/scripts/monolith.sh → exit 0",
"evidence": "implementer.md §5.1 'Bash syntax' — comando bash -n ejecutado, salida 'monolith.sh syntax OK'.",
"result": "PASS"
},
{
"id": "AC2",
"criterion": "monolith.sh dev start arranca sin ejecutar el smoke test (HMR esperado en dev)",
"evidence": "code review: `[[ \"$MODE\" == \"prod\" ]] && { smoke_check_no_dev_markers; stop_all; exit 1; }` en start_all. En dev MODE=dev, la condición es false y el smoke no se ejecuta.",
"result": "PASS"
},
{
"id": "AC3",
"criterion": "monolith.sh prod start ejecuta el smoke test y pasa con servicios prod",
"evidence": "code review + implementer.md §5.4 'Test funcional — caso positivo (mock prod server) → debe OK'. Mock en :30994 (HTML limpio, /_next/hmr → 404) → '[OK] All Next.js services are HMR-free. exit=0'.",
"result": "PASS"
},
{
"id": "AC4",
"criterion": "Forzar npm run dev (no script) + intentar monolith.sh prod start → smoke debe fallar",
"evidence": "implementer.md §5.3 'Test funcional — caso negativo (mock dev server) → debe FAIL'. Mock en :30999 (HTML con /__next_hmr, /_next/hmr → 200) → 2 FAILs + 'DEV MODE DETECTED on prod start. Refusing to continue. exit=1'.",
"result": "PASS"
},
{
"id": "AC5",
"criterion": "docs/HOWTO-monolith.md contiene §3.1 con sección de error común y runbook de recuperación",
"evidence": "grep -n '^### 3\\.1' docs/HOWTO-monolith.md → línea 152. La sección incluye: por qué next dev no es atajo, 4 señales observables (banner Turbopack, [HMR] en consola, WebSocket /_next/hmr, lsof), y runbook de 6 pasos (kill, lsof, rm pid, prod start, tail log).",
"result": "PASS"
},
{
"id": "AC6",
"criterion": "docs/pos/POS_OPERATIONS.md §1.3 contiene la advertencia inline",
"evidence": "implementer.md §2 'Detalle de los cambios' + grep verificación: bloque ⚠️ Nunca ejecutes npm run dev… apuntando a HOWTO-monolith §3.1.",
"result": "PASS"
},
{
"id": "AC7",
"criterion": "./scripts/verify.sh → exit 0",
"evidence": "implementer.md §5.5 'verify.sh del orquestra' — re-ejecución actual verificada, 'Orquestra verificado. Puedes trabajar.' (5/5 secciones OK).",
"result": "PASS"
},
{
"id": "AC8",
"criterion": "work/artifacts/TPV-DEV-IN-PROD/implementer.md documenta los comandos ejecutados y los outputs observados",
"evidence": "implementer.md existe con 7921 bytes. Contiene 6 secciones de evidencia: bash syntax, función extraíble, mock dev fail, mock prod ok, verify.sh, backlog. Cada sección lista comandos + outputs.",
"result": "PASS"
}
],
"integration_checks": [
{
"id": "INT-1",
"description": "Smoke test depende solo de funciones ya existentes en monolith.sh (service_port, service_url, log_file)",
"command": "code review + git diff",
"result": "PASS",
"evidence": "service_port, service_url y log_file ya estaban definidos y los usa status_all, check_services y print_urls. Cero modificaciones a esas funciones."
},
{
"id": "INT-2",
"description": "El nuevo bloque en start_all no altera el flujo existente (ensure_env, clear_stale_deployments, start_infrastructure, install_dependencies, migrate, build_prod, sync_uploads, spawn_service loop)",
"command": "code review",
"result": "PASS",
"evidence": "El bloque if [[ \"$MODE\" == \"prod\" ]]; then smoke...; fi se inserta DESPUÉS del loop spawn_service y ANTES de print_urls. En modo prod con smoke OK, el flujo continúa idéntico al previo (echo + print_urls)."
},
{
"id": "INT-3",
"description": "Comandos status/logs/stop/urls/watch no se ven afectados",
"command": "code review de los case statements al final",
"result": "PASS",
"evidence": "case \"$ACTION\" despacha start → start_all, restart → stop_all; start_all, status → status_all, etc. El smoke test solo se ejecuta dentro de start_all (modo prod). status/logs/stop/urls/watch no llaman a start_all."
},
{
"id": "INT-4",
"description": "Backlog: TPV-DEV-IN-PROD promovido a in_progress, otros 3 tickets TPV-* en pending",
"command": "python3 -c \"import json; data=json.load(open('backlog/features.json')); print([f['id']+'='+f['status'] for f in data['features'] if str(f.get('id','')).startswith('TPV-')])\"",
"result": "PASS",
"evidence": "TPV-DEV-IN-PROD=in_progress; TPV-MANIFEST-PATH=pending; TPV-POS-SALES-500=pending; TPV-FAVICON-404=pending; TPV-FIXES=done."
}
],
"regression_checks": [
{
"id": "REG-1",
"description": "Dev mode (monolith.sh dev) sigue arrancando next dev sin smoke",
"command": "code review",
"result": "PASS",
"evidence": "El guard `[[ \"$MODE\" == \"prod\" ]]` impide la ejecución del smoke en dev. Sin cambios al bloque spawn_service case dev:*."
},
{
"id": "REG-2",
"description": "Backend (Fastify, no Next) no se incluye en el smoke",
"command": "code review de NEXT_SERVICES",
"result": "PASS",
"evidence": "NEXT_SERVICES=(admin tpv frontend storefront). Backend queda excluido correctamente."
},
{
"id": "REG-3",
"description": "set -euo pipefail sigue comportándose correctamente (no abortos espurios)",
"command": "code review",
"result": "PASS",
"evidence": "El bloque if ! smoke_check... then stop_all; exit 1; fi es seguro con errexit. El operador ! neutraliza errexit durante la evaluación. Las funciones internas (stop_pid) siempre retornan 0."
},
{
"id": "REG-4",
"description": "assert_port_available sigue bloqueando puertos ocupados por procesos no gestionados",
"command": "code review",
"result": "PASS",
"evidence": "Llamada a assert_port_available en start_all sigue presente y sin cambios. El smoke es una capa ADEMÁS, no en lugar de."
}
],
"e2e_notes": [
"No se puede ejecutar E2E contra el host remoto desde este entorno (no hay acceso a tpv-mv.rikrdo.com).",
"Verificación local con mocks controlados (puerto 30993-30999) cubre las 3 ramas del test: HTML markers, endpoint /_next/hmr, banner (Turbopack).",
"La validación final end-to-end ocurrirá en el host del operador cuando ejecute `monolith.sh prod restart` tras mergear. El nuevo guard fallará ruidosamente si el dev server sigue activo, guiando al operador al runbook §3.1."
],
"findings": [],
"verdict_rationale": "Los 8 criterios de aceptación son trazables y verificables (PASS 8/8). 4 integration checks + 4 regression checks también PASS. Sin findings. El fix es completo, verificado y aislado. APPROVED.",
"evidence_paths": [
"work/artifacts/TPV-DEV-IN-PROD/architect.md",
"work/artifacts/TPV-DEV-IN-PROD/implementer.md",
"work/artifacts/TPV-DEV-IN-PROD/reviewer.json",
"work/artifacts/TPV-DEV-IN-PROD/security.json",
"project/scripts/monolith.sh",
"docs/HOWTO-monolith.md",
"docs/pos/POS_OPERATIONS.md",
"backlog/features.json"
],
"agent": "qa"
}