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:
Lucas Berger
2026-06-11 20:35:18 -04:00
parent 4bc0445173
commit 982438dc10
398 changed files with 19050 additions and 16382 deletions
@@ -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.