Adds a public funnel landing at `/` and moves the login to `/login`, rebuilt around the panel's own colors instead of an invented palette. Landing (`src/components/landing/`, one section per file, no props): - Seven funnel sections composed by `LandingPage`. The hero's eight swatches are literally `PIE_COLORS` from `DashboardPage`, the same hex values the seed hands to avatars and services, so "your colors become your numbers" is literal. - `BrandMark` becomes the single source for the logo, replicating `public/favicon.svg`. Blue is the action surface, orange only ever marks. - `NotebookVisual` is the one deliberate exception to the palette: it is what the product replaces. - Copy drops all system vocabulary; motion comes from `src/lib/motion.ts` with a single easing, and reduced-motion resolves `initial` to the final state so a never-firing `whileInView` cannot leave a section invisible forever. Routing and bundle: - `homePathFor` is the single definition of each role's destination. - Landing, login, dashboard and calendar load lazily. Eager, the login dragged framer-motion (~40 KB gz) into every panel load and the landing downloaded recharts + FullCalendar (~187 KB gz) without charting anything. `clsx` is pinned to the `react` chunk because Rollup otherwise assigns it to `charts`, making the entry import 111 KB gz for a 200-byte utility. Responsiveness (iPhone/iPad), verified with `npm run audit:responsive`: - No touch form field below 16px, `dvh` height utilities, safe-area insets, and 40px touch targets keyed off `pointer: coarse` rather than `sm:`. - New `.ld-gutter`: `.safe-x` lives outside `@layer` and beats Tailwind's `px-*`, so it left the login's side padding at 0 on anything but an iPhone in landscape. No overflow check could see it — there was no overflow, just zero margin. The audit now guards it with a `gutter` check. - `shell-height` no longer fires on pages that legitimately scroll; the static `raw-viewport-unit` scan covers those instead. Production build: - The Dockerfile now sets `VITE_DEMO_UI=1` as a build arg. `DEMO` is a build-time constant, so without it Vite eliminated the magic login and the "Ver como…" switcher: the deployed landing promised "no registration" and led to an empty form. Verified by building both ways and diffing the bundle. - Service worker cache bumped to v2 so the orphaned pre-landing chunks get purged from returning visitors' caches. Verified: typecheck clean; unit 39/39, e2e 33/33, admin 17/17, booking 12/12, landing 13/13 (WebKit), PWA passed against the real production build. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
80 lines
5.9 KiB
Markdown
80 lines
5.9 KiB
Markdown
# Task 4 Report
|
|
|
|
## Files
|
|
|
|
- Added `pwa-e2e.mjs` with production endpoint, manifest, SPA fallback, Chromium install prompt, iOS instructions, standalone/unsupported states, service-worker readiness/source checks, and real browser `/api/health` request verification.
|
|
- Updated `README.md` with local production validation, Android/Chrome installation, iOS Safari instructions, standalone behavior, connectivity expectations, and Coolify HTTPS validation guidance.
|
|
|
|
## Verification
|
|
|
|
- `node --check pwa-e2e.mjs`: passed.
|
|
- `npm.cmd run typecheck`: passed.
|
|
- `npm.cmd run build`: passed; Vite produced the production bundle in `dist/`.
|
|
- `npm.cmd run test:pwa`: passed; output `PWA checks passed` against the built production server on port 3000.
|
|
- `npm.cmd run audit:visual`: passed; 58 screens/visits, 0 failed loads, 0 horizontal overflow issues. The audit reported 8 console 404 messages while still exiting 0.
|
|
- `git diff --check`: passed with no whitespace errors. Git emitted existing LF-to-CRLF working-copy warnings for tracked files.
|
|
|
|
The first PWA run exposed a test-harness race where the synthetic event could fire before React registered its listener. The harness was corrected to dispatch 100 ms after `load`; the subsequent production run passed.
|
|
|
|
## Self-review
|
|
|
|
- Endpoint checks use the configured `PWA_BASE_URL`, defaulting to `http://localhost:3000`.
|
|
- Manifest assertions cover standalone display, root start URL/scope, and both required icon sizes.
|
|
- Browser contexts are isolated for Chromium prompt, iOS Safari instructions, standalone mode, and unsupported/no-event mode.
|
|
- Service-worker readiness has a five-second bound, and the source guard checks cover `/api/` and non-GET requests.
|
|
- The browser API check observes a real request and validates its JSON response rather than using a fixture.
|
|
- No app authentication, tenant data, API route, database schema, or runtime behavior was changed.
|
|
|
|
## Concerns
|
|
|
|
- The visual audit continues to record eight pre-existing 404 console messages on some authenticated/admin visits. They were not introduced by Task 4 and were not changed because the task explicitly limits scope to PWA verification and production documentation.
|
|
- The report itself and pre-existing `.superpowers/sdd/*` and `graphify-out/*` changes remain outside the Task 4 commit staging set.
|
|
|
|
## Review Fixes
|
|
|
|
- Added `fetchWithTimeout()` using `AbortController` for every direct endpoint/source fetch. The in-page `/api/health` request now uses its own bounded `AbortController` as well.
|
|
- Added exact-one accessible-action coverage for the login page, authenticated business shell, and authenticated admin shell. Business/admin flows use the existing demo credentials and a mobile viewport so their compact install controls are visible and accessible.
|
|
- Replaced fixed sleeps in standalone/unsupported checks with bounded DOM-state polling for zero matching install actions.
|
|
- Replaced iOS body-text checks with visible exact-text locators for `Compartir` and `Añadir a pantalla de inicio`.
|
|
- Relaxed service-worker source checks to tolerate whitespace and quote style while still requiring the pathname `/api/` bypass and non-GET guard.
|
|
- Tracked all browser contexts and closes them explicitly before closing the browser in `finally`; default UI/navigation timeouts are bounded.
|
|
|
|
## Review-Fix Verification
|
|
|
|
- `node --check pwa-e2e.mjs`: passed.
|
|
- `npm.cmd run typecheck`: passed.
|
|
- `npm.cmd run build`: passed; Vite produced the production bundle in `dist/`.
|
|
- `npm.cmd run test:pwa`: passed; output `PWA checks passed` against the built production server on port 3000.
|
|
- `npm.cmd run audit:visual`: passed; 58 screens/visits, 0 failed loads, 0 horizontal overflow issues. The audit still reports 8 pre-existing console 404 messages.
|
|
- `git diff --check`: passed with no whitespace errors; Git only emitted existing LF-to-CRLF working-copy warnings.
|
|
|
|
## Review-Fix Self-review
|
|
|
|
- Direct network operations now have bounded completion, including response-body reads for endpoint/source assertions and the browser-side API response.
|
|
- Login, business, and admin each assert one and only one accessible `Instalar AgendaMax` action; the two shell checks exercise the authenticated UI path rather than assuming route markup.
|
|
- Negative install-state checks wait on the DOM condition with a timeout and fail non-zero if the condition never becomes true.
|
|
- All changes remain in the PWA test harness and this report; application behavior and unrelated tests are unchanged.
|
|
|
|
## Remaining Concerns
|
|
|
|
- The visual audit's 8 pre-existing 404 console messages remain outside Task 4 scope. They do not cause failed loads, overflow failures, or a non-zero audit exit.
|
|
|
|
## Service-worker Behavioral Fix
|
|
|
|
- Added a reload and `navigator.serviceWorker.controller` gate before behavioral API checks, ensuring requests run through an active, controlling worker.
|
|
- While online, the browser now verifies `GET /api/health` returns `200` and a safe invalid `POST /api/auth/login` returns `401`.
|
|
- With the Playwright context offline, both API requests must produce bounded network errors rather than cached responses. Connectivity is restored in a `finally` block.
|
|
|
|
## Service-worker Behavioral Verification
|
|
|
|
- `npm.cmd run typecheck`: passed.
|
|
- `npm.cmd run build`: passed; Vite produced the production bundle in `dist/`.
|
|
- `npm.cmd run test:pwa`: passed; output `PWA checks passed` against the built production server on port 3000.
|
|
- `git diff --check`: passed with no whitespace errors; Git only emitted existing LF-to-CRLF working-copy warnings.
|
|
|
|
## Service-worker Behavioral Self-review
|
|
|
|
- The online assertions validate real statuses (`200` and `401`) before offline mode is enabled, so a cached fixture cannot satisfy the positive path.
|
|
- Offline assertions require both requests to reject with a network-error result and do not accept a response status or body.
|
|
- The offline state is always reverted in `finally`, and the existing bounded request, navigation, worker-readiness, UI, install-surface, and cleanup checks remain intact.
|