FOLIO: AUD-20261001-002 Secuencia: Informe #002 del día 2026-10-01
📅 2026-10-01 20:00:00 COT 👤 Auditor: Anderson Mares (AMR TECH) ● VIGENTE
APLICADO: REPLICAR R1·R3·R7·R8·R9 + P0 + CSP 6 archivos · +448 / −41 · 1 commit (74dbfac) Suite 26/26 (100%) · Deploy 0 borrados

Aplicación de ítems REPLICAR del benchmark KF, P0 de la home y fix crítico de CSP que rompía las imágenes en producción

Continuación directa del informe AUD-20260930-003 (archivo 44 · veredicto REPLICAR 9 · SUPERAR 6 · OMITIR 7). Este documento certifica la implementación, verificación y despliegue en producción de los ítems REPLICAR priorizados (R1, R3, R7, R8, R9) en las tres demos del portafolio + el P0 de la home de revendedores, junto con la corrección de un bug de CSP que dejaba las miniaturas S3 rotas en vivo. Todo verificado con suite PHP, requests HTTP y navegador real (Playwright) contra streamingapps.online.

5 / 5
Ítems REPLICAR aplicados (R1, R3, R7, R8, R9) en amrstore, productos-dropi y cuentas-streaming
12/12
Imágenes S3 cargando en navegador real tras el fix de CSP (antes: 0 — bloqueadas por img-src)
26/26
Pruebas PHP aprobadas en host (100%) antes del commit
0
Archivos borrados en producción (rsync con excludes protectores validados por dry-run)
9
Capturas Playwright (desktop 1440 + móvil 390) revisadas una a una contra producción
0
Errores de consola y 0 referencias al carrito (rama ajena) en el código desplegado

1 · Fix crítico: CSP bloqueaba las imágenes S3 en producción

Síntoma: las miniaturas de cuentas (goplay-mypantalla.s3.amazonaws.com) aparecían rotas en cuentas-streaming.php en vivo. Causa: el dominio S3 no estaba listado en img-src de la política CSP, servida por doble cabecera que se interseca: PHP (env.php:103) + Apache (.htaccess:22, Header always set).
PasoAcciónResultado
1Agregar https://goplay-mypantalla.s3.amazonaws.com a img-src en ambas cabeceras (env.php y .htaccess)HECHO
2Verificación sandbox: 2 cabeceras CSP con el dominio; imágenes 200OK
3Verificación producción (headers): política servida contiene el dominio S3OK
4Navegador real en vivo: 13/13 imgs cargadas, de ellas 12/12 del S3, 0 errores de consolaOK

En producción llega 1 sola cabecera CSP: header() de PHP reemplaza la entrada de igual nombre, por lo que prevalece la política de env.php — que sí incluye el S3. La copia en .htaccess queda como respaldo para archivos estáticos. Ambas mantienen el mismo img-src por diseño.

2 · Cambios por archivo (commit 74dbfac)

ArchivoÍtemsDetalleDiff
index.php P0 Barra de campaña (?t=ALD), $heroStats con métricas reales en .stat-strip (4 ítems: demos/clientes/revendedores/24-7), botón flotante .wa-float, .price-alt y scroll-spy en el FAQ +187/−26
cuentas-streaming.php R1·R3·R7·R9 Stats (12/2/24-7), steps ghost 01–04, ancla «Desde» + pill ● Disponible, grid 2-col ≤620 px, fallbacks de imagen +88/−5
productos-dropi.php R1·R3·R7·R9 Stats (12/8/24-7), steps ghost 01–04, «Desde» + «Precio sugerido +20%», chips con conteos, grid 2-col móvil +72/−4
amrstore.php R3·R7·R8·R9 Buscador (input + botón rojo «Buscar» + JS runSearch integrado con filtros), «Desde», pill ● Disponible, steps ghost 01–03, grid 2-col ≤980/≤640, icono de caja como fallback de cards sin imagen, .product-tag oculto ≤390 px (evitaba solape con «Disponible») +138/−4
env.php + .htaccess CSP Dominio S3 agregado a img-src en las dos cabeceras (deben mantenerse sincronizadas) +2/−2

3 · Mapeo ítems del benchmark (informe 44) → implementación

ÍtemQué copiaba de KFDónde quedóEstado
R1Stats numéricas en el primer pliegueHome (stat-strip), cuentas, productos, amrstore✓
R3«Desde» como ancla de precio + estado de disponibilidadLas 4 páginas (dot ● Disponible + pill)✓
R7Pasos «cómo funciona» con numeración ghostcuentas y productos 01–04 · amrstore 01–03✓
R8Buscador visible sobre el catálogoamrstore (input + botón rojo); cuentas/productos ya tenían buscador propio✓
R9Grid de 2 cards por fila en móvilamrstore ≤980/≤640 · cuentas ≤620 · productos móvil✓
R2Chips de filtroYa existían en las demos (no requería cambio)YA ESTABA
R4·R5·R6Volumen B2B, stepper vs mascota, nav con emojisNo aplicables a estas páginas (decisión de scope del benchmark)OMITIR
Fueras de scope (preexistentes, NO tocados): nav mobile apilada sin hamburguesa (igual en prod antes del cambio) · .stats{1fr} de amrstore ≤640 px · label de datos «STREAMING · STREAMING» (duplicado viene del dato, no del estilo).

4 · Hallazgo: mezcla de trabajo con la rama del carrito

La rama paralela feat/carrito-checkout (commit 396c93e) capturó en amrstore.php el trabajo KF anterior sin commitear junto con el código del carrito. Al restaurar el stash sobre dev quedó un archivo incompleto (CSS sin markup, JS sin HTML).

  1. Clasificación hunk por hunk de dev → 396c93e: 13 hunks → 7 míos (KF) vs 6 del carrito.
  2. Reconstrucción: base = stash@{0}:amrstore.php (trabajo KF completo) menos las piezas del carrito (CSS .add-cart-btn, header navCartBtn/cartBadge, markup condicional if/else, JS Cart).
  3. Verificación: 0 referencias a add-cart-btn|carrito.php|amrAddToCart|amrCart_v1|cartBadge, php -l OK, 0 conflict markers.
  4. En vivo: add-cart-btn=0, navCart=false — la rama del carrito no se filtró a dev/prod y podrá mezclarse después con diff limpio.

5 · Matriz de verificación (evidencia)

CheckMétodoResultado
Sintaxis PHPphp -l × 6 archivosNO ERRORS
Suite de pruebasphp tests/run_all_tests.php en host26/26 · 100% (JSON restaurado post-corrida)
Endpointscurl sobre /, /?t=ALD, cuentas, productos, amrstore5/5 HTTP 200
CSP servidacurl -I en cuentas-streamingimg-src con S3 presente
Imágenes en vivoPlaywright → naturalWidth13/13 ok · 12/12 S3
Buscador amrstorePlaywright → escribir «netflix» + click Buscar12 cards visibles (filtra)
Estructura amrstorePlaywright → DOMsearch ✓ · 3 steps · 105 avail · 0 cart
Estructura homePlaywright → DOM en /?t=ALD4 stat-strip · campaign ✓ · wa-float ✓
ConsolaPlaywright → console.error0 errores
Visual9 capturas 1440/390 px revisadas (banner PAGE=FILE como fuente de verdad)SIN REGRESIONES

6 · Deploy seguro a Hostinger (rsync con protectores)

Dry-run previo con --delete reveló archivos exclusivos de producción en riesgo; se añadieron excludes anclados con / y se re-validó hasta 0 borrados antes de transferir.

Archivo protegidoRiesgo si se borraba/sobrescribía
/database.sqliteCRÍTICO: prod más nuevo (Sep 24) que el local (Sep 1) — enviarlo habría revertido datos CRM live
/goplay_database.sqliteBase exclusiva de prod (solo existía en el servidor)
/whatsapp-crm/config.phpCredenciales de producción (no versionadas)
/producto.php · /index.html · /amrstore/Páginas/rutas legacy con posible tráfico o enlaces SEO
/whatsapp-crm/public/*.php · /whatsapp-crm/audit_licenses.phpScripts runtime creados directamente en prod
/error_log · /.old.-install.php · /14-amrstore-*.htmlLegacy — pendiente de aprobación para limpieza (no se borraron)

config.json verificado byte-a-byte idéntico local↔prod antes de transferirlo (diferencia solo de mtime).

7 · Registro de entrega (Git)

commit 74dbfac — feat(ui): replicate KF benchmark items R1/R3/R7/R8/R9 + fix CSP img-src for S3
rama dev → push refspec dev:dev · dev:staging · dev:main en GitHub + GitLab
ramas locales staging/main actualizadas a 74dbfac
stash descartado tras reconstrucción · suite JSON restaurado (git checkout tests/test_run_results.json)
deploy rsync → u305025526@hostinger · public_html/ · 0 borrados

8 · Bitácora de la sesión

  1. ~19:10 — Resolución del conflicto de stash sobre dev; diagnóstico de mezcla carrito+KF en amrstore.php.
  2. ~19:25 — Reconstrucción por clasificación de 13 hunks; eliminación quirúrgica de 6 bloques del carrito; php -l + greps de verificación.
  3. ~19:35 — Suite 26/26 en host → commit 74dbfac → push refspec a GitHub y GitLab (dev/staging/main).
  4. ~19:45 — Dry-run rsync: hallazgo de database.sqlite de prod más nuevo y archivos legacy; excludes protectores; 0 borrados; transfer real.
  5. ~19:50 — Smoke en vivo: 5/5 HTTP 200, CSP con S3, Playwright (imgs 12/12 S3, buscador, stats, 0 errores consola).
  6. ~19:56 — Revisión visual de 9 capturas desktop/móvil contra producción: sin regresiones.
  7. 20:00 — Publicación de este informe en auditorias/46-informe-aplicacion-replicar-p0-csp-fix.html + fila y contador en auditorias/index.html.