Unnamed Skill

TRPC with Tanstack Query patterns Applies to files matching: *.tsx.

$ Instalar

git clone https://github.com/FranciscoMoretti/sparka /tmp/sparka && cp -r /tmp/sparka/.skillz/trpc-patterns ~/.claude/skills/sparka

// tip: Run this command in your terminal to install the skill


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 - 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 - All database operations should be defined here
  • Database schema: 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

const trpc = useTRPC();
const { data, isLoading, refetch } = useQuery({
  ...trpc.router.procedure.queryOptions(),
  enabled: !!condition,
});

Mutation Pattern

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

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
  5. Invalidate related queries after mutations
  6. Handle loading and error states in the UI