From 505f64ed93503ab2a10e5ac39fd67b15882be2d2 Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Sat, 6 Jun 2026 22:11:33 -0400 Subject: [PATCH] =?UTF-8?q?docs:=20add=20backlog=20item=20999.2=20?= =?UTF-8?q?=E2=80=94=20slick=20unauthenticated-entry=20(no=20login=20flash?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .planning/ROADMAP.md | 16 ++++++++++++++++ .../.gitkeep | 0 2 files changed, 16 insertions(+) create mode 100644 .planning/phases/999.2-auth-entry-login-flash-splash-gate/.gitkeep diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index d0de6c9..7964dcf 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -183,3 +183,19 @@ Note: Phase 4 depends only on Phase 1 and can begin as soon as Phase 1 is comple Plans: - [ ] TBD (promote with /gsd-review-backlog when ready) + +### Phase 999.2: Slick unauthenticated-entry — no calendar/"Sign-in required" flash before Authelia redirect (BACKLOG) + +**Goal:** [Captured for future planning] On a cold unauthenticated load the PWA briefly paints the calendar shell + skeleton, then flashes a "Sign-in required" error, then redirects to Authelia — not slick (violates the "low-friction for the non-technical Apple member" hard constraint). Make unauthenticated entry render a single neutral "Signing you in…" splash and go straight to Authelia, with no app content or error text painted first. + +**Root cause** (diagnosed during Phase 03 Gate 2 live verification, 2026-06-07) — `apps/pwa/src/components/CalendarShell.tsx`: the component renders optimistically before auth is known. While `meQuery` (GET `/api/me`) is pending, `isInitialLoading` renders the calendar shell + `SkeletonCalendar`. When `meQuery` resolves as an `opaqueredirect` (unauthenticated — `fetchMe` uses `redirect:'manual'` in `apps/pwa/src/api/client.ts`), it errors and in the same tick (1) the early return `if (meQuery.isError) return
Sign-in required
` (~line 187) paints, and (2) a `useEffect` calls `window.location.href='/api/login'`. Because the navigation is async, React paints "Sign-in required" for ~one frame before leaving for Authelia. Net: calendar flash → "Sign-in required" flash → Authelia. + +**Proposed fix:** Gate the app render on auth state — (a) don't render CalendarContent/skeleton until `meQuery.isSuccess`; (b) while unauthenticated and redirecting, render a neutral full-screen "Signing you in…" splash instead of the "Sign-in required" alert; (c) reserve the "Sign-in required" dead-end only for the one-shot-guard fall-through (already bounced through `/api/login` and still failing). Optionally hoist the auth check above the heavy calendar mount. + +**Severity:** low / cosmetic, but hits every unauthenticated cold load and the wife's first impression. Tags: phase-03, ux-polish, auth. +**Requirements:** TBD +**Plans:** 0 plans + +Plans: + +- [ ] TBD (promote with /gsd-review-backlog when ready) diff --git a/.planning/phases/999.2-auth-entry-login-flash-splash-gate/.gitkeep b/.planning/phases/999.2-auth-entry-login-flash-splash-gate/.gitkeep new file mode 100644 index 0000000..e69de29