Files
pitchfast/backlog/tasks/task-28 - Diagnose-dashboard-initial-load-retry-loop.md
2026-06-05 17:04:03 +02:00

6.7 KiB

id, title, status, assignee, created_date, updated_date, labels, dependencies, priority, ordinal
id title status assignee created_date updated_date labels dependencies priority ordinal
TASK-28 Diagnose dashboard initial-load retry loop Done
2026-06-05 13:46 2026-06-05 15:03
high 30000

Description

Find the root cause of the repeated dashboard requests on initial load, especially the repeated GET /dashboard/leads entries, and implement a targeted fix only after reproducing and tracing the loop.

Acceptance Criteria

  • #1 Root cause is identified with evidence from the relevant dashboard/auth/navigation code
  • #2 A minimal fix prevents repeated dashboard/leads requests on initial load
  • #3 Relevant tests or verification commands are run

Implementation Plan

  1. Add a focused regression test proving server auth config enables Convex JWT cookie reuse.
  2. Verify the test fails against the current auth-server configuration.
  3. Enable the documented jwtCache option in convexBetterAuthNextJs with a scoped auth-error predicate.
  4. Run the focused test, full test suite, and lint.
  5. Record verification and leave TASK-28 open for user Firefox/Zen confirmation.

Implementation Notes

Evidence gathered:

  • User-provided log repeatedly shows successful GET /dashboard/leads during dashboard use.
  • Existing Next dev log shows a hydration failure in components/dashboard-theme.tsx:88 inside DashboardThemeToggle during /dashboard rendering: server rendered Moon/aria-pressed=false while client rendered Sun/aria-pressed=true.
  • Next local docs confirm client/server render differences during hydration cause the tree to be regenerated.
  • Separate WIP issue observed: /dashboard/outreach imports a missing component, which can also produce repeated dev overlay errors, but the initial dashboard hydration error is the targeted root cause for this task.

Implemented targeted fix:

  • DashboardThemeProvider now uses useSyncExternalStore with a stable server snapshot of light, preventing the server/client icon and aria-pressed mismatch on initial dashboard hydration.
  • Added tests/dashboard-theme.test.ts to guard against reintroducing localStorage reads in the initial render path. Verification:
  • node --test .test-output/tests/dashboard-theme.test.js passes.
  • pnpm test compiles and includes the new dashboard theme test as passing, but the full run still fails in existing TASK-13 outreach WIP test OutreachReviewWorkspace uses the review workspace API and required controls.
  • pnpm lint no longer reports components/dashboard-theme.tsx; it still fails in existing components/outreach/outreach-review-workspace.tsx WIP.

Additional verification note:

  • pnpm exec tsc --noEmit fails in existing components/outreach/outreach-review-workspace.tsx WIP with type mismatches and missing fields; this is separate from the dashboard theme hydration fix and was already part of unrelated TASK-13 worktree changes.

User retest on 2026-06-05 falsified the first hydration-only fix. New evidence: pnpm dev still logs repeated GET /dashboard/leads every roughly 300-400ms with 200 responses, with proxy.ts taking ~165-522ms each time, followed by one get-session and two convex token requests. Re-entering systematic debugging; no more fixes until request initiator is identified.

Added temporary development-only proxy instrumentation for /dashboard/leads request classification. It logs non-sensitive request headers: accept, rsc, next-router-prefetch, next-router-segment-prefetch, next-hmr-refresh, next-url, sec-fetch-mode, purpose, referer, state-tree presence, and user-agent. Remove after confirming requester.

Corrected root cause after user retest and header instrumentation:

  • First hydration hypothesis was incomplete and did not stop the request fan-out.
  • Development-only proxy header instrumentation showed real browser /dashboard/leads requests were same-origin CORS fetches with next-url set to the current dashboard route, not document reloads, HMR refreshes, or server redirect loops.
  • Code search showed the repeated target originates from visible Next Link surfaces: dashboard sidebar nav plus many LeadFunnelCard action links that can share href /dashboard/leads. Next App Router prefetches visible links, and each protected prefetch crosses proxy.ts and isAuthenticated(), producing many 200 GET /dashboard/leads entries. Implemented fix:
  • Set prefetch={false} on DashboardSidebar nav links and LeadFunnelCard action links to keep click navigation but stop automatic protected-route prefetch fan-out.
  • Removed temporary proxy/fetch diagnostics.
  • Added tests/dashboard-prefetch.test.ts to lock this behavior. Verification:
  • pnpm exec tsc -p tsconfig.test.json passes.
  • node --test .test-output/tests/dashboard-prefetch.test.js .test-output/tests/dashboard-theme.test.js passes.
  • pnpm test passes 260/260.
  • pnpm lint passes with existing generated/unused warnings only, no errors.

2026-06-05 Firefox/Zen HAR follow-up:

  • User confirmed the reload loop reproduces in Firefox/Zen but not Chrome.
  • HAR shows repeated top-level document navigations to /dashboard/audits, not XHR retries or Link prefetch.
  • Requests already include better-auth.convex_jwt, but SSR responses embed fresh initialToken values and /api/auth/convex/token later sets better-auth.convex_jwt again.
  • Local @convex-dev/better-auth source shows getToken() fetches /convex/token unless jwtCache.enabled is configured. Next implementation hypothesis: enable jwtCache so server getToken() reuses a valid Convex JWT cookie instead of minting a new token during each root layout render.

Implemented Firefox/Zen token-churn fix:

  • Added jwtCache.enabled to lib/auth-server.ts for convexBetterAuthNextJs, matching the Convex Better Auth Next.js server utilities docs.
  • Added a scoped isConvexAuthError predicate so recognized application auth failures still surface, while stale cached-token failures can trigger the library refresh path.
  • Added tests/auth-server-jwt-cache.test.ts to guard the server auth cache configuration. Verification after fix:
  • pnpm exec tsc -p tsconfig.test.json passes.
  • node --test .test-output/tests/auth-server-jwt-cache.test.js passes after failing before the implementation.
  • pnpm test passes 265/265.
  • pnpm lint passes with two existing generated-file warnings and no errors. Manual confirmation still needed in Firefox/Zen before closing TASK-28 as Done.

Final Summary

Firefox/Zen reload loop fixed by enabling Convex Better Auth JWT caching in Next.js server auth utilities; regression test added and full tests/lint passed. User confirmed dashboard now loads reliably without loops.