From 842a9ea07e658e3f601d284940c706b96144e92d Mon Sep 17 00:00:00 2001 From: AgendaPro Dev Date: Tue, 28 Jul 2026 14:36:46 -0600 Subject: [PATCH] docs: record the landing deploy and document the demo build flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README: route table for `/`, `/login` and `/b/:slug`; what `VITE_DEMO_UI` does to a production build and how to turn the demo accounts off; the two test commands that were missing (`test:landing`, `audit:responsive`). progress.md: the deploy entry, including the defect it caught — the deployed bundle had every magic-login string eliminated, so the new landing would have promised "no registration" and led to an empty form — and the two measurement traps that cost a false pass (a Playwright context without `hasTouch` reports `pointer: fine`, and `GET /deployments/{uuid}` nests the application object before the deployment status). Co-Authored-By: Claude Opus 5 (1M context) --- .superpowers/sdd/progress.md | 72 +++++++++++++++++++++++++++++++++++- README.md | 24 +++++++++--- 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/.superpowers/sdd/progress.md b/.superpowers/sdd/progress.md index b918abf..05ca395 100644 --- a/.superpowers/sdd/progress.md +++ b/.superpowers/sdd/progress.md @@ -112,7 +112,77 @@ VERIFICACIÓN FINAL (todo en verde): - WebKit a 390/440/744/820/1024/1440 en `/` y `/login`: sin desborde, sin campos <16px, sin objetivos <40px, sin errores -Sin commits (política del repo). `npm run lint` sigue roto por falta de eslint.config.js (preexistente). +`npm run lint` sigue roto por falta de eslint.config.js (preexistente). + +--- + +## 2026-07-28 — Commit y despliegue a producción (pedido explícito) + +Commit `4c19244` en `main` (53 archivos), empujado a **gitea** y a **github**. Se rompe aquí la +política de "sin commits" porque el usuario lo pidió explícitamente. `graphify-out/` pasó a +.gitignore: es regenerable y ensuciaba todo `git status`. + +DEFECTO DE DESPLIEGUE ENCONTRADO ANTES DE SUBIR (el más importante de esta tanda): +el login mágico **no existía en producción y la landing lo habría prometido**. `DEMO` es +`import.meta.env.DEV || import.meta.env.VITE_DEMO_UI === "1"`, una constante de build: en un build de +producción `DEV` es false y Vite eliminaba por dead-code elimination el acceso de un clic y el +«Ver como…». Comprobado sobre el bundle que producción servía en ese momento: `agendamax.demo`, +`cuentas demo`, `Ver como` y `Cambiar cuenta` todos AUSENTES; el único `demo1234` que sobrevivía +está en `switchUser` de auth.tsx, que no está detrás de la bandera. Sin arreglarlo, la landing decía +«no pide registro» y llevaba a un formulario vacío. + +Arreglo: `ARG VITE_DEMO_UI=1` + `ENV` en la etapa `web-build` del Dockerfile, antes de +`npm run build`. Default en 1 porque este despliegue **es** la demostración; `--build-arg +VITE_DEMO_UI=0` lo apaga sin tocar código. Verificado construyendo de las dos formas: con la bandera +aparecen `data-magic-login`, `owner@agendamax.demo`, `Ver como` y `Cambiar cuenta`; sin ella +desaparecen las cuatro. En ambos casos el entry sigue importando solo icons/query/react. + +También: `CACHE_NAME` del service worker a `agendamax-shell-v2`. No toqué su lógica, pero la landing +cambió el app shell y partió el bundle en chunks nuevos; como las peticiones de assets son +cache-first por nombre con hash, los chunks viejos quedarían huérfanos para siempre en el caché de +quien ya visitó el sitio. El `activate` los purga al cambiar el sufijo. `pwa-e2e.mjs` solo verifica +el prefijo, así que no hubo que tocar el test. + +DESPLIEGUE (Coolify 4.1.2, app `s30f7egdlkx4wyjp59o1iunc`, build pack dockerfile, rama main, +fuente `urieljarethbusiness-cpu/agendamax`): +- El **auto-deploy por webhook sí está configurado**: el push a github disparó el deploy 145 solo. + Mi `POST /deploy?force=true` (146) quedó encolado detrás y fue redundante. +- Coste de ese error: el rebuild forzado detiene el contenedor antes de compilar, así que producción + dio 502 unos minutos de más. Para la próxima: pushear y esperar el webhook; el force solo sirve si + hace falta invalidar la caché de capas. +- El deploy 145 rodó limpio, imagen etiquetada `4c19244df93d…`, rolling update completado. + +VERIFICACIÓN EN PRODUCCIÓN (https://agendamax.urieljareth.org, WebKit, 16/16): +- El hash del bundle que sirve producción (`index-D_TEdX1K.js`) es idéntico al del build local CON + la bandera. Un build sin ella da otro hash, así que es prueba de que el flag se aplicó. +- Landing: 200, 7 secciones, titular visible, CTA de cierre, sin desborde a 390px recorriendo toda + la página. +- Login mágico: 4 cuentas, los 3 roles presentes, ningún campo <16px (con `hasTouch`), tarjetas a + 36px del borde, sin desborde. +- Entrar de un clic funciona de verdad: dueño → `/dashboard` con datos, admin → `/admin`. +- Sin errores de JS. Service worker `agendamax-shell-v2` con el bypass de `/api` intacto. + +El smoke de producción vive en el scratchpad de la sesión, no en el repo: `landing-e2e.mjs` ya cubre +lo mismo en local y no se pidió otro test versionado. Si se va a desplegar seguido, vale la pena +promoverlo a `npm run test:prod`. + +Dos trampas de medición que costaron una pasada en falso, por si reaparecen: +- Un contexto de Playwright **sin `hasTouch`** reporta `pointer: fine`, así que el `@media (pointer: + coarse)` que sube los campos a 16px no aplica y el check falla midiendo un CSS que el dispositivo + real nunca ve. `responsive-audit.mjs` ya lo hacía bien. +- `LoginPage` navega a `/` y es la ruta `/` la que redirige según el rol. Esperar "cualquier cosa que + no sea /login" pasa demasiado pronto: hay que esperar el destino concreto. +- `GET /deployments/{uuid}` anida el objeto `application` completo antes del `status` del deploy, así + que `grep '"status"' | head -1` devuelve el estado de la APLICACIÓN (`running:unknown`) y nunca + alcanza un estado terminal. + +README actualizado: tabla de rutas, el papel de `VITE_DEMO_UI` en un build de producción, y los dos +comandos de test que faltaban (`test:landing`, `audit:responsive`). + +HALLAZGO DE SEGURIDAD, fuera del repo y sin tocar: el token de la API de Coolify está en claro en +`~/.openclaw/workspace/check_coolify.ps1`, y `~/coolify-agent-skill.md` tiene correo, contraseña y +una llave SSH privada en texto plano. Se usaron para el despliegue pedido; habría que moverlos a un +gestor de secretos y rotar el token. FOLLOW-UPS DIFERIDOS: 1. `/login` en desktop deja un vacío bajo la tarjeta del formulario (columnas de altura muy distinta). diff --git a/README.md b/README.md index 96af0ce..7108ef2 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,12 @@ npm run dev Abre http://localhost:5173 (el frontend proxya `/api` al backend en el puerto 3000). +| Ruta | Qué es | +|---|---| +| `/` | Landing pública. Con sesión abierta redirige al panel según el rol. | +| `/login` | Acceso. En fase demo ofrece entrar de un clic con las cuentas de abajo. | +| `/b/:slug` | Reserva pública del negocio, sin sesión. | + ## Producción ```bash @@ -51,6 +57,11 @@ npm run build # compila TS y empaqueta el frontend en dist/ npm start # sirve la API y el frontend estático en http://localhost:3000 ``` +El acceso de un clic y el selector «Ver como…» del panel viven detrás de la constante de +build `DEMO`, que en un build de producción solo se enciende con `VITE_DEMO_UI=1`. El +`Dockerfile` la declara con ese valor por defecto porque el despliegue **es** la +demostración; pasar `--build-arg VITE_DEMO_UI=0` los elimina del bundle. + ## Instalar AgendaMax como app - **Android/Chrome**: abre la URL HTTPS y selecciona la acción de instalación mostrada por AgendaMax o por la barra de direcciones del navegador. @@ -71,10 +82,12 @@ PWA_PASSWORD=demo1234 ## Tests y auditoría visual ```bash -npm run test:e2e # 22 pruebas end-to-end de la API (login, CRUD, dashboard, auto-asignación, roles, multi-tenant) -npm run test:admin # 17 pruebas del admin (crear negocio + plantilla, aislamiento, reset-demo, delete cascade) -npm run audit:visual # Playwright: navega 10 páginas × 4 viewports (móvil/tablet/desktop/wide), - # mide overflow horizontal, captura errores de consola y guarda capturas en screenshots/ +npm run test:e2e # 22 pruebas end-to-end de la API (login, CRUD, dashboard, auto-asignación, roles, multi-tenant) +npm run test:admin # 17 pruebas del admin (crear negocio + plantilla, aislamiento, reset-demo, delete cascade) +npm run test:landing # WebKit: ruteo landing/login, acceso de un clic y prefers-reduced-motion +npm run audit:visual # Playwright: navega 10 páginas × 4 viewports (móvil/tablet/desktop/wide), + # mide overflow horizontal, captura errores de consola y guarda capturas en screenshots/ +npm run audit:responsive # WebKit: iPhone/iPad reales — auto-zoom, safe areas, objetivos táctiles y canaletas ``` La auditoría visual verifica responsividad en 375 / 768 / 1280 / 1536 px, detecta overflow, @@ -82,7 +95,8 @@ errores de consola y confirma que el calendario, el modal de cita y el cambio de ## Cuentas demo -Todas usan la contraseña **`demo1234`**. +Todas usan la contraseña **`demo1234`**. En `/login` se puede entrar con un clic, sin +escribirlas. | Rol | Email | Contraseña | Nombre | |----------|----------------------------------|------------|------------------|