fix: defectos encontrados por la suite de extremo a extremo
La primera corrida completa dio 57 fallas. Solo una parte eran del producto; el resto era instrumentación mal escrita. Queda en 261 en verde. Defectos del producto: - La atribución de campaña se perdía. La captura vivía en un efecto de React, así que si la persona llegaba con parámetros de campaña y navegaba antes de hidratar, el primer toque nunca se guardaba y utmCampaign llegaba vacío al CRM. Ahora se captura en un script en línea que corre al analizar el documento. - Siete páginas sin og:image: una página que declara su propio openGraph no hereda las imágenes del layout, las sobreescribe. Solo se nota al compartir el enlace. Se resuelve con una función compartida en seo.ts. - El panel no se podía usar desde Safari por HTTP: la cookie Secure no se guarda y el acceso falla en silencio. Queda explícito y documentado. - El panel se corría de lado en móvil: la cabecera no cabía a 375px. - Las tarjetas de perfil del acceso se cortaban en móvil. Un elemento de rejilla nace con min-width auto y no puede encogerse bajo su contenido. Era además el origen de un desplazamiento que se arrastraba al tablero. - Las tablas accesibles de las gráficas volvían desplazable la página: sr-only fija width 1px y el algoritmo de tablas lo ignora. - El campo de búsqueda del catálogo no tenía nombre accesible. - Límite de tasa de 5 envíos por IP: bloqueaba una demostración en vivo con varias personas en la misma red. Configurable, ahora 20. - El salto de contenido pasa de left:-9999px a recorte de 1px. Instrumentación corregida, con la razón escrita en cada caso: - El desborde horizontal se mide intentando desplazar la página, no con documentElement.scrollWidth, que sobreinforma con contenedores propios. - La comprobación de accesibilidad respeta el árbol de accesibilidad. - El aislamiento entre roles se prueba pidiendo por URL una oportunidad ajena, no comparando folios entre listados paginados. - Fuera las esperas por networkidle, que agotaban el tiempo sin fallar. - Que el panel no esté enlazado se comprueba leyendo el HTML servido. - Safari no enfoca enlaces con Tab: declarado como del navegador. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0e0331c1fc
commit
31ee899987
@@ -12,6 +12,7 @@ SQLite en un volumen. No hay base de datos externa.
|
||||
| `NEXT_PUBLIC_SITE_URL` | Sí, **en construcción** | Las URL canónicas, el sitemap y Open Graph apuntan al dominio equivocado. Ver la advertencia de abajo. |
|
||||
| `NEXT_PUBLIC_WHATSAPP` | Sí, **en construcción** | El widget de WhatsApp abre una conversación con un número vacío. |
|
||||
| `DEMO_ACCESO_RAPIDO` | No | Con cualquier valor distinto de `false`, el acceso de un clic por perfil está activo en `/admin/login`. |
|
||||
| `AUTH_COOKIE_INSECURE` | No | Solo para pruebas locales sin TLS. Ver la advertencia de HTTPS abajo. **Nunca en producción.** |
|
||||
| `NODE_ENV` | No | Ya viene en `production` dentro de la imagen. |
|
||||
|
||||
### Advertencia sobre las variables `NEXT_PUBLIC_*`
|
||||
@@ -38,6 +39,20 @@ node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"
|
||||
Uno por entorno. No reutilices el de desarrollo: cualquiera que lo tenga puede
|
||||
firmar una cookie de sesión válida y entrar al panel como administrador.
|
||||
|
||||
### El panel exige HTTPS
|
||||
|
||||
La cookie de sesión va marcada como `Secure`, que es lo correcto. La
|
||||
consecuencia es que **si el panel se sirve por HTTP plano, en Safari y en iOS
|
||||
nadie puede entrar**: el navegador se niega a guardar la cookie, el acceso
|
||||
devuelve a la pantalla de inicio de sesión y no dice por qué. Chromium hace una
|
||||
excepción con `localhost`, así que el problema se ve solo en WebKit y es fácil
|
||||
de atribuir a otra cosa.
|
||||
|
||||
Detrás de Coolify con Cloudflare esto no ocurre, porque el tráfico llega por
|
||||
HTTPS. Importa en dos casos: si alguien expone el contenedor por IP y puerto sin
|
||||
TLS, y al probar en local. Para lo segundo existe `AUTH_COOKIE_INSECURE=true`,
|
||||
que **no debe usarse en un entorno accesible desde internet**.
|
||||
|
||||
## El volumen — la parte frágil
|
||||
|
||||
**Si no montas `/app/data`, cada redespliegue borra los leads capturados.**
|
||||
|
||||
Reference in New Issue
Block a user