feat(web): preload user identity query at root route

Quentin Gliech and Claude Opus 4.6 (1M context) created

Fire the UserIdentity query in the root route's beforeLoad so it's
already in the Apollo cache before any component calling useAuth()
renders.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Change summary

webui2/src/lib/auth.tsx      | 14 +++++++-------
webui2/src/routes/__root.tsx |  5 +++++
2 files changed, 12 insertions(+), 7 deletions(-)

Detailed changes

webui2/src/lib/auth.tsx 🔗

@@ -1,12 +1,12 @@
 // auth.tsx — current user hook for the webui.
 //
-// Fetches the user identity from git config via GraphQL. Apollo handles
-// deduplication and caching, so no Provider/Context is needed.
+// The UserIdentity query is preloaded in the root route loader and consumed
+// via useSuspenseQuery, so useAuth() always returns a resolved user.
 
 import { gql } from "@apollo/client";
-import { useQuery } from "@apollo/client/react";
+import { useSuspenseQuery } from "@apollo/client/react";
 
-const USER_IDENTITY_QUERY = gql`
+export const USER_IDENTITY_QUERY = gql`
   query UserIdentity {
     repository {
       userIdentity {
@@ -32,9 +32,9 @@ export interface AuthUser {
   login: string | null;
 }
 
-export function useAuth(): { user: AuthUser | null; loading: boolean } {
-  const { data, loading } = useQuery<{ repository: { userIdentity: AuthUser | null } }>(
+export function useAuth(): { user: AuthUser } {
+  const { data } = useSuspenseQuery<{ repository: { userIdentity: AuthUser } }>(
     USER_IDENTITY_QUERY,
   );
-  return { user: data?.repository?.userIdentity ?? null, loading };
+  return { user: data.repository.userIdentity };
 }

webui2/src/routes/__root.tsx 🔗

@@ -5,12 +5,17 @@ import { Shell } from "@/components/layout/shell";
 import { Button } from "@/components/ui/button";
 import { ButtonLink } from "@/components/ui/button-link";
 import type { preloadQuery } from "@/lib/apollo";
+import { USER_IDENTITY_QUERY } from "@/lib/auth";
 
 export interface RouterContext {
   preloadQuery: typeof preloadQuery;
 }
 
 export const Route = createRootRouteWithContext<RouterContext>()({
+  async loader({ context }) {
+    const ref = context.preloadQuery(USER_IDENTITY_QUERY);
+    await context.preloadQuery.toPromise(ref);
+  },
   component: Shell,
   errorComponent: ErrorPage,
 });