--- name: trpc-patterns description: TRPC with Tanstack Query patterns Applies to files matching: *.tsx. --- # TRPC with Tanstack Query Integration ## Backend Structure - **Main router**: [trpc/routers/_app.ts](mdc:trpc/routers/_app.ts) - All routers must be registered here - **Individual routers**: `trpc/routers/*.router.ts` - Create feature-specific routers (e.g., `chat.router.ts`, `vote.router.ts`) - **Database queries**: [lib/db/queries.ts](mdc:lib/db/queries.ts) - All database operations should be defined here - **Database schema**: [lib/db/schema.ts](mdc:lib/db/schema.ts) - Drizzle ORM schema definitions ## Frontend Integration ### Setup - Use `useTRPC()` hook from `@/trpc/react` - Import `useMutation`, `useQuery`, `useQueryClient` from `@tanstack/react-query` ### Query Pattern ```typescript const trpc = useTRPC(); const { data, isLoading, refetch } = useQuery({ ...trpc.router.procedure.queryOptions(), enabled: !!condition, }); ``` ### Mutation Pattern ```typescript const trpc = useTRPC(); const queryClient = useQueryClient(); const mutation = useMutation( trpc.router.procedure.mutationOptions({ onSuccess: () => { // Invalidate related queries queryClient.invalidateQueries({ queryKey: trpc.router.relatedQuery.queryKey(), }); }, }) ); // Usage await mutation.mutateAsync({ input: data }); ``` ## Backend Router Pattern ```typescript import { createTRPCRouter, protectedProcedure } from '@/trpc/init'; import { z } from 'zod'; export const featureRouter = createTRPCRouter({ queryName: protectedProcedure.query(async ({ ctx }) => { return await dbFunction({ userId: ctx.user.id }); }), mutationName: protectedProcedure .input(z.object({ /* validation schema */ })) .mutation(async ({ ctx, input }) => { // Verify permissions/ownership // Call database function return await dbFunction(input); }), }); ``` ## Key Principles 1. Always use `protectedProcedure` for authenticated routes 2. Validate inputs with Zod schemas 3. Verify user ownership/permissions in mutations 4. Use database functions from [lib/db/queries.ts](mdc:lib/db/queries.ts) 5. Invalidate related queries after mutations 6. Handle loading and error states in the UI