Files
AgendaPro DevandClaude Opus 5 4c19244df9 feat: public landing page with magic login, brand palette and demo build flag
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]>
2026-07-28 14:25:58 -06:00

5.9 KiB

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.