style(13-03): apply Prettier formatting across repo
Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
phase: 06-ux-polish
|
||||
plan: "05"
|
||||
plan: '05'
|
||||
subsystem: pwa/auth
|
||||
tags: [tdd, auth, session-expiry, d-10, d-11]
|
||||
dependency_graph:
|
||||
@@ -40,7 +40,7 @@ decisions:
|
||||
- In-flight write replay deferred (D-11 nice-to-have, RESEARCH Open Question 3)
|
||||
metrics:
|
||||
duration_minutes: 35
|
||||
completed_date: "2026-06-10"
|
||||
completed_date: '2026-06-10'
|
||||
tasks_completed: 4
|
||||
files_changed: 6
|
||||
---
|
||||
@@ -51,15 +51,15 @@ metrics:
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
| Task | Name | Commit | Files |
|
||||
|------|------|--------|-------|
|
||||
| 1 (RED) | Failing SessionExpiredError detection tests | `e5072ff` | client.test.ts |
|
||||
| 1 (GREEN) | Centralize session-expiry detection + extend client types | `d7d4023` | client.ts, client.test.ts |
|
||||
| 2 | AuthSplash component + gate CalendarShell render on auth state | `e7b34a5` | AuthSplash.tsx, CalendarShell.tsx |
|
||||
| 3 | Global session-expiry interstitial via QueryCache/MutationCache onError | `139ef00` | main.tsx, calendarStore.ts, CalendarShell.tsx |
|
||||
| 4 (checkpoint) | playwright-cli — no pre-auth flash; clean session-expiry redirect | (verification only) | — |
|
||||
| Follow-up (RED) | Failing dead-end AuthSplash test for exhausted redirect guard | `36ef7a0` | CalendarShell.test.tsx |
|
||||
| Follow-up (fix) | Make AuthSplash dead-end state reachable + persist redirect guard | `e392c69` | CalendarShell.tsx |
|
||||
| Task | Name | Commit | Files |
|
||||
| --------------- | ----------------------------------------------------------------------- | ------------------- | --------------------------------------------- |
|
||||
| 1 (RED) | Failing SessionExpiredError detection tests | `e5072ff` | client.test.ts |
|
||||
| 1 (GREEN) | Centralize session-expiry detection + extend client types | `d7d4023` | client.ts, client.test.ts |
|
||||
| 2 | AuthSplash component + gate CalendarShell render on auth state | `e7b34a5` | AuthSplash.tsx, CalendarShell.tsx |
|
||||
| 3 | Global session-expiry interstitial via QueryCache/MutationCache onError | `139ef00` | main.tsx, calendarStore.ts, CalendarShell.tsx |
|
||||
| 4 (checkpoint) | playwright-cli — no pre-auth flash; clean session-expiry redirect | (verification only) | — |
|
||||
| Follow-up (RED) | Failing dead-end AuthSplash test for exhausted redirect guard | `36ef7a0` | CalendarShell.test.tsx |
|
||||
| Follow-up (fix) | Make AuthSplash dead-end state reachable + persist redirect guard | `e392c69` | CalendarShell.tsx |
|
||||
|
||||
## What Was Built
|
||||
|
||||
@@ -88,6 +88,7 @@ Created `apps/pwa/src/components/AuthSplash.tsx`:
|
||||
- Logo lockup omitted gracefully (brand asset not present; no block on that).
|
||||
|
||||
`CalendarShell.tsx` updated:
|
||||
|
||||
- `meQuery.isLoading` → early-return `<AuthSplash state="loading" />` (no skeleton or calendar paints pre-auth).
|
||||
- `meQuery.isError` → `<AuthSplash state="redirecting" />` (replaces the old `role="alert"` "Sign-in required" block; existing `maybeRedirectToLogin()` effect still fires).
|
||||
- `CalendarContent`/`SkeletonCalendar` render only on `meQuery.isSuccess`.
|
||||
@@ -97,10 +98,12 @@ Created `apps/pwa/src/components/AuthSplash.tsx`:
|
||||
`calendarStore.ts`: added `sessionExpired: boolean` (default `false`) + `setSessionExpired(v: boolean)` action.
|
||||
|
||||
`main.tsx`: `QueryClient` constructed with:
|
||||
|
||||
```ts
|
||||
queryCache: new QueryCache({ onError(error) { if (error instanceof SessionExpiredError) setSessionExpired(true) } }),
|
||||
mutationCache: new MutationCache({ onError(error) { if (error instanceof SessionExpiredError) setSessionExpired(true) } }),
|
||||
```
|
||||
|
||||
TanStack Query v5 API confirmed via Context7 (`/tanstack/query`): `defaultOptions.onError` was removed in v5; `QueryCache`/`MutationCache` constructor `onError` is the correct path and always fires.
|
||||
|
||||
`CalendarShell.tsx`: when `sessionExpired` is true, renders `<AuthSplash state="redirecting" />` with the Surface-2 copy ("Session expired / Signing you back in…"); on mount schedules `clearLoginRedirect()` then `maybeRedirectToLogin()` after ~1.5s.
|
||||
@@ -120,6 +123,7 @@ The checkpoint surfaced two related issues:
|
||||
2. **One-shot redirect guard persistence:** The guard (`familysync.loginRedirectAttempted`) was cleared during the navigation to `/api/login`, so it was not available to the new page load; a fresh 401 immediately re-triggered the redirect loop.
|
||||
|
||||
Fix (commits `36ef7a0` RED, `e392c69` fix):
|
||||
|
||||
- `CalendarShell` now renders `<AuthSplash state="dead-end" />` once the redirect guard is exhausted after the interstitial fires.
|
||||
- Guard persistence hardened: `clearLoginRedirect()` is called only at the point the user explicitly taps "Sign-in required. Tap here to try again." — not during the automatic redirect path.
|
||||
|
||||
@@ -142,6 +146,7 @@ Re-verified PASS via playwright-cli after fix.
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 1 - Bug] Dead-end AuthSplash state unreachable + redirect guard not persisting**
|
||||
|
||||
- **Found during:** Task 4 (playwright-cli checkpoint)
|
||||
- **Issue:** CalendarShell never rendered `AuthSplash state="dead-end"` (fall-through to empty fragment); the one-shot redirect guard was cleared during navigation, not on user tap, making the guard unavailable to the landing page on a fresh 401.
|
||||
- **Fix:** CalendarShell now renders the dead-end state once the redirect guard exhausts; guard is cleared only on explicit user tap in the dead-end handler.
|
||||
|
||||
Reference in New Issue
Block a user