start-vibing 2.0.8 → 2.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +177 -176
  2. package/dist/cli.js +38 -11
  3. package/package.json +42 -42
  4. package/template/.claude/CLAUDE.md +174 -152
  5. package/template/.claude/agents/01-orchestration/agent-selector.md +130 -123
  6. package/template/.claude/agents/01-orchestration/checkpoint-manager.md +142 -131
  7. package/template/.claude/agents/01-orchestration/context-manager.md +138 -124
  8. package/template/.claude/agents/01-orchestration/error-recovery.md +182 -176
  9. package/template/.claude/agents/01-orchestration/orchestrator.md +114 -107
  10. package/template/.claude/agents/01-orchestration/parallel-coordinator.md +141 -130
  11. package/template/.claude/agents/01-orchestration/task-decomposer.md +121 -118
  12. package/template/.claude/agents/01-orchestration/workflow-router.md +114 -111
  13. package/template/.claude/agents/02-typescript/bun-runtime-expert.md +197 -180
  14. package/template/.claude/agents/02-typescript/esm-resolver.md +193 -187
  15. package/template/.claude/agents/02-typescript/import-alias-enforcer.md +158 -149
  16. package/template/.claude/agents/02-typescript/ts-generics-helper.md +183 -165
  17. package/template/.claude/agents/02-typescript/ts-migration-helper.md +238 -227
  18. package/template/.claude/agents/02-typescript/ts-strict-checker.md +180 -162
  19. package/template/.claude/agents/02-typescript/ts-types-analyzer.md +199 -185
  20. package/template/.claude/agents/02-typescript/type-definition-writer.md +187 -183
  21. package/template/.claude/agents/02-typescript/zod-schema-designer.md +212 -197
  22. package/template/.claude/agents/02-typescript/zod-validator.md +158 -153
  23. package/template/.claude/agents/03-testing/playwright-assertions.md +265 -255
  24. package/template/.claude/agents/03-testing/playwright-e2e.md +247 -245
  25. package/template/.claude/agents/03-testing/playwright-fixtures.md +234 -240
  26. package/template/.claude/agents/03-testing/playwright-multi-viewport.md +256 -261
  27. package/template/.claude/agents/03-testing/playwright-page-objects.md +247 -247
  28. package/template/.claude/agents/03-testing/test-cleanup-manager.md +248 -256
  29. package/template/.claude/agents/03-testing/test-data-generator.md +254 -266
  30. package/template/.claude/agents/03-testing/tester-integration.md +278 -278
  31. package/template/.claude/agents/03-testing/tester-unit.md +207 -204
  32. package/template/.claude/agents/03-testing/vitest-config.md +287 -289
  33. package/template/.claude/agents/04-docker/container-health.md +255 -239
  34. package/template/.claude/agents/04-docker/deployment-validator.md +225 -217
  35. package/template/.claude/agents/04-docker/docker-compose-designer.md +281 -268
  36. package/template/.claude/agents/04-docker/docker-env-manager.md +235 -228
  37. package/template/.claude/agents/04-docker/docker-multi-stage.md +241 -229
  38. package/template/.claude/agents/04-docker/dockerfile-optimizer.md +208 -204
  39. package/template/.claude/agents/05-database/data-migration.md +0 -293
  40. package/template/.claude/agents/05-database/database-seeder.md +273 -270
  41. package/template/.claude/agents/05-database/mongodb-query-optimizer.md +230 -219
  42. package/template/.claude/agents/05-database/mongoose-aggregation.md +306 -280
  43. package/template/.claude/agents/05-database/mongoose-index-optimizer.md +182 -174
  44. package/template/.claude/agents/05-database/mongoose-schema-designer.md +267 -267
  45. package/template/.claude/agents/06-security/auth-session-validator.md +68 -65
  46. package/template/.claude/agents/06-security/input-sanitizer.md +80 -81
  47. package/template/.claude/agents/06-security/owasp-checker.md +97 -87
  48. package/template/.claude/agents/06-security/permission-auditor.md +100 -95
  49. package/template/.claude/agents/06-security/security-auditor.md +84 -82
  50. package/template/.claude/agents/06-security/sensitive-data-scanner.md +83 -85
  51. package/template/.claude/agents/07-documentation/api-documenter.md +136 -131
  52. package/template/.claude/agents/07-documentation/changelog-manager.md +105 -96
  53. package/template/.claude/agents/07-documentation/documenter.md +76 -73
  54. package/template/.claude/agents/07-documentation/domain-updater.md +81 -74
  55. package/template/.claude/agents/07-documentation/jsdoc-generator.md +114 -114
  56. package/template/.claude/agents/07-documentation/readme-generator.md +135 -132
  57. package/template/.claude/agents/08-git/branch-manager.md +58 -58
  58. package/template/.claude/agents/08-git/commit-manager.md +63 -61
  59. package/template/.claude/agents/08-git/pr-creator.md +76 -72
  60. package/template/.claude/agents/09-quality/code-reviewer.md +71 -64
  61. package/template/.claude/agents/09-quality/quality-checker.md +67 -67
  62. package/template/.claude/agents/10-research/best-practices-finder.md +89 -82
  63. package/template/.claude/agents/10-research/competitor-analyzer.md +106 -96
  64. package/template/.claude/agents/10-research/pattern-researcher.md +93 -86
  65. package/template/.claude/agents/10-research/research-cache-manager.md +76 -75
  66. package/template/.claude/agents/10-research/research-web.md +98 -91
  67. package/template/.claude/agents/10-research/tech-evaluator.md +101 -94
  68. package/template/.claude/agents/11-ui-ux/accessibility-auditor.md +136 -128
  69. package/template/.claude/agents/11-ui-ux/design-system-enforcer.md +125 -116
  70. package/template/.claude/agents/11-ui-ux/skeleton-generator.md +118 -120
  71. package/template/.claude/agents/11-ui-ux/ui-desktop.md +132 -126
  72. package/template/.claude/agents/11-ui-ux/ui-mobile.md +98 -94
  73. package/template/.claude/agents/11-ui-ux/ui-tablet.md +110 -111
  74. package/template/.claude/agents/12-performance/api-latency-analyzer.md +156 -149
  75. package/template/.claude/agents/12-performance/bundle-analyzer.md +113 -107
  76. package/template/.claude/agents/12-performance/memory-leak-detector.md +137 -126
  77. package/template/.claude/agents/12-performance/performance-profiler.md +115 -108
  78. package/template/.claude/agents/12-performance/query-optimizer.md +124 -116
  79. package/template/.claude/agents/12-performance/render-optimizer.md +154 -148
  80. package/template/.claude/agents/13-debugging/build-error-fixer.md +207 -188
  81. package/template/.claude/agents/13-debugging/debugger.md +149 -137
  82. package/template/.claude/agents/13-debugging/error-stack-analyzer.md +141 -131
  83. package/template/.claude/agents/13-debugging/network-debugger.md +208 -185
  84. package/template/.claude/agents/13-debugging/runtime-error-fixer.md +181 -173
  85. package/template/.claude/agents/13-debugging/type-error-resolver.md +185 -173
  86. package/template/.claude/agents/14-validation/final-validator.md +93 -83
  87. package/template/.claude/agents/_backup/analyzer.md +134 -125
  88. package/template/.claude/agents/_backup/code-reviewer.md +279 -272
  89. package/template/.claude/agents/_backup/commit-manager.md +219 -212
  90. package/template/.claude/agents/_backup/debugger.md +280 -271
  91. package/template/.claude/agents/_backup/documenter.md +237 -220
  92. package/template/.claude/agents/_backup/domain-updater.md +197 -194
  93. package/template/.claude/agents/_backup/final-validator.md +169 -164
  94. package/template/.claude/agents/_backup/orchestrator.md +149 -138
  95. package/template/.claude/agents/_backup/performance.md +232 -228
  96. package/template/.claude/agents/_backup/quality-checker.md +240 -240
  97. package/template/.claude/agents/_backup/research.md +315 -299
  98. package/template/.claude/agents/_backup/security-auditor.md +192 -186
  99. package/template/.claude/agents/_backup/tester.md +566 -564
  100. package/template/.claude/agents/_backup/ui-ux-reviewer.md +247 -242
  101. package/template/.claude/commands/feature.md +48 -48
  102. package/template/.claude/config/README.md +30 -30
  103. package/template/.claude/config/mcp-config.json +344 -330
  104. package/template/.claude/config/project-config.json +53 -53
  105. package/template/.claude/config/quality-gates.json +46 -46
  106. package/template/.claude/config/security-rules.json +45 -45
  107. package/template/.claude/config/testing-config.json +164 -168
  108. package/template/.claude/hooks/SETUP.md +126 -126
  109. package/template/.claude/hooks/run-hook.ts +176 -172
  110. package/template/.claude/hooks/stop-validator.ts +825 -353
  111. package/template/.claude/hooks/user-prompt-submit.ts +886 -794
  112. package/template/.claude/scripts/mcp-quick-install.ts +151 -151
  113. package/template/.claude/scripts/setup-mcps.ts +651 -628
  114. package/template/.claude/settings.json +275 -276
  115. package/template/.claude/skills/bun-runtime/SKILL.md +430 -430
  116. package/template/.claude/skills/codebase-knowledge/SKILL.md +145 -145
  117. package/template/.claude/skills/codebase-knowledge/domains/claude-system.md +431 -403
  118. package/template/.claude/skills/codebase-knowledge/domains/mcp-integration.md +295 -281
  119. package/template/.claude/skills/debugging-patterns/SKILL.md +485 -484
  120. package/template/.claude/skills/docker-patterns/SKILL.md +555 -547
  121. package/template/.claude/skills/docs-tracker/SKILL.md +239 -239
  122. package/template/.claude/skills/final-check/SKILL.md +284 -284
  123. package/template/.claude/skills/git-workflow/SKILL.md +454 -454
  124. package/template/.claude/skills/mongoose-patterns/SKILL.md +499 -512
  125. package/template/.claude/skills/nextjs-app-router/SKILL.md +327 -337
  126. package/template/.claude/skills/performance-patterns/SKILL.md +547 -549
  127. package/template/.claude/skills/playwright-automation/SKILL.md +438 -438
  128. package/template/.claude/skills/quality-gate/SKILL.md +294 -294
  129. package/template/.claude/skills/react-patterns/SKILL.md +389 -376
  130. package/template/.claude/skills/research-cache/SKILL.md +222 -207
  131. package/template/.claude/skills/security-scan/SKILL.md +222 -222
  132. package/template/.claude/skills/shadcn-ui/SKILL.md +511 -520
  133. package/template/.claude/skills/tailwind-patterns/SKILL.md +465 -467
  134. package/template/.claude/skills/test-coverage/SKILL.md +467 -464
  135. package/template/.claude/skills/trpc-api/SKILL.md +434 -435
  136. package/template/.claude/skills/typescript-strict/SKILL.md +367 -368
  137. package/template/.claude/skills/ui-ux-audit/SKILL.md +254 -254
  138. package/template/.claude/skills/zod-validation/SKILL.md +403 -405
  139. package/template/CLAUDE.md +25 -25
@@ -1,435 +1,434 @@
1
- ---
2
- name: trpc-api
3
- description: tRPC end-to-end type-safe API patterns. Router setup, procedures, middleware, context, client configuration. Use when building type-safe APIs with tRPC.
4
- allowed-tools: Read, Write, Edit, Grep, Glob
5
- ---
6
-
7
- # tRPC API - End-to-End Type Safety
8
-
9
- ## Purpose
10
-
11
- Expert guidance for tRPC v11:
12
-
13
- - **Router Setup** - Modular router architecture
14
- - **Procedures** - Queries, mutations, subscriptions
15
- - **Middleware** - Auth, logging, rate limiting
16
- - **Context** - Session, database, utilities
17
- - **Client** - React Query integration
18
-
19
- ---
20
-
21
- ## Project Structure
22
-
23
- ```
24
- server/
25
- ├── trpc/
26
- │ ├── index.ts # Router exports
27
- │ ├── trpc.ts # tRPC instance
28
- │ ├── context.ts # Context creation
29
- │ └── routers/
30
- │ ├── user.router.ts
31
- │ ├── post.router.ts
32
- │ └── _app.ts # Root router
33
- app/
34
- └── api/trpc/[trpc]/route.ts # Next.js handler
35
- lib/
36
- └── trpc/
37
- ├── client.ts # tRPC client
38
- └── react.tsx # React Query provider
39
- ```
40
-
41
- ---
42
-
43
- ## Server Setup
44
-
45
- ### tRPC Instance
46
-
47
- ```typescript
48
- // server/trpc/trpc.ts
49
- import { initTRPC, TRPCError } from '@trpc/server';
50
- import superjson from 'superjson';
51
- import { type Context } from './context';
52
-
53
- const t = initTRPC.context<Context>().create({
54
- transformer: superjson,
55
- errorFormatter({ shape, error }) {
56
- return {
57
- ...shape,
58
- data: {
59
- ...shape.data,
60
- zodError:
61
- error.cause instanceof ZodError ? error.cause.flatten() : null,
62
- },
63
- };
64
- },
65
- });
66
-
67
- export const router = t.router;
68
- export const publicProcedure = t.procedure;
69
- export const middleware = t.middleware;
70
- ```
71
-
72
- ### Context
73
-
74
- ```typescript
75
- // server/trpc/context.ts
76
- import { type CreateNextContextOptions } from '@trpc/server/adapters/next';
77
- import { getServerSession } from 'next-auth';
78
- import { authOptions } from '@/lib/auth';
79
- import { db } from '@db';
80
-
81
- export async function createContext(opts: CreateNextContextOptions) {
82
- const session = await getServerSession(authOptions);
83
-
84
- return {
85
- session,
86
- user: session?.user ?? null,
87
- db,
88
- req: opts.req,
89
- res: opts.res,
90
- };
91
- }
92
-
93
- export type Context = Awaited<ReturnType<typeof createContext>>;
94
- ```
95
-
96
- ### Auth Middleware
97
-
98
- ```typescript
99
- // server/trpc/trpc.ts
100
- const isAuthed = middleware(({ ctx, next }) => {
101
- if (!ctx.user) {
102
- throw new TRPCError({
103
- code: 'UNAUTHORIZED',
104
- message: 'You must be logged in',
105
- });
106
- }
107
- return next({
108
- ctx: {
109
- ...ctx,
110
- user: ctx.user, // User is now guaranteed
111
- },
112
- });
113
- });
114
-
115
- export const protectedProcedure = t.procedure.use(isAuthed);
116
- ```
117
-
118
- ---
119
-
120
- ## Router Patterns
121
-
122
- ### Basic Router
123
-
124
- ```typescript
125
- // server/trpc/routers/user.router.ts
126
- import { z } from 'zod';
127
- import { router, publicProcedure, protectedProcedure } from '../trpc';
128
-
129
- export const userRouter = router({
130
- // Query - fetch data
131
- getById: publicProcedure
132
- .input(z.object({ id: z.string().uuid() }))
133
- .query(async ({ input, ctx }) => {
134
- const user = await ctx.db.user.findUnique({
135
- where: { id: input.id },
136
- select: { id: true, name: true, email: true },
137
- });
138
-
139
- if (!user) {
140
- throw new TRPCError({
141
- code: 'NOT_FOUND',
142
- message: 'User not found',
143
- });
144
- }
145
-
146
- return user;
147
- }),
148
-
149
- // Mutation - modify data
150
- updateProfile: protectedProcedure
151
- .input(z.object({
152
- name: z.string().min(2).max(100),
153
- bio: z.string().max(500).optional(),
154
- }))
155
- .mutation(async ({ input, ctx }) => {
156
- return ctx.db.user.update({
157
- where: { id: ctx.user.id },
158
- data: input,
159
- });
160
- }),
161
-
162
- // Me - current user
163
- me: protectedProcedure.query(async ({ ctx }) => {
164
- return ctx.db.user.findUnique({
165
- where: { id: ctx.user.id },
166
- });
167
- }),
168
- });
169
- ```
170
-
171
- ### Root Router
172
-
173
- ```typescript
174
- // server/trpc/routers/_app.ts
175
- import { router } from '../trpc';
176
- import { userRouter } from './user.router';
177
- import { postRouter } from './post.router';
178
-
179
- export const appRouter = router({
180
- user: userRouter,
181
- post: postRouter,
182
- });
183
-
184
- export type AppRouter = typeof appRouter;
185
- ```
186
-
187
- ---
188
-
189
- ## Advanced Patterns
190
-
191
- ### Pagination
192
-
193
- ```typescript
194
- const paginationSchema = z.object({
195
- cursor: z.string().optional(),
196
- limit: z.number().min(1).max(100).default(20),
197
- });
198
-
199
- export const postRouter = router({
200
- list: publicProcedure
201
- .input(paginationSchema)
202
- .query(async ({ input, ctx }) => {
203
- const { cursor, limit } = input;
204
-
205
- const posts = await ctx.db.post.findMany({
206
- take: limit + 1,
207
- cursor: cursor ? { id: cursor } : undefined,
208
- orderBy: { createdAt: 'desc' },
209
- });
210
-
211
- let nextCursor: string | undefined;
212
- if (posts.length > limit) {
213
- const nextItem = posts.pop();
214
- nextCursor = nextItem?.id;
215
- }
216
-
217
- return {
218
- items: posts,
219
- nextCursor,
220
- };
221
- }),
222
- });
223
- ```
224
-
225
- ### Optimistic Updates
226
-
227
- ```typescript
228
- // Client-side with React Query
229
- const utils = trpc.useUtils();
230
-
231
- const createPost = trpc.post.create.useMutation({
232
- onMutate: async (newPost) => {
233
- // Cancel outgoing refetches
234
- await utils.post.list.cancel();
235
-
236
- // Snapshot previous value
237
- const previousPosts = utils.post.list.getData();
238
-
239
- // Optimistically update
240
- utils.post.list.setData(undefined, (old) => {
241
- if (!old) return { items: [newPost], nextCursor: undefined };
242
- return { ...old, items: [newPost, ...old.items] };
243
- });
244
-
245
- return { previousPosts };
246
- },
247
-
248
- onError: (err, newPost, context) => {
249
- // Rollback on error
250
- utils.post.list.setData(undefined, context?.previousPosts);
251
- },
252
-
253
- onSettled: () => {
254
- // Always refetch after error or success
255
- utils.post.list.invalidate();
256
- },
257
- });
258
- ```
259
-
260
- ### Batch Requests
261
-
262
- ```typescript
263
- // tRPC automatically batches by default
264
- // Multiple calls in same tick are batched
265
-
266
- const user = trpc.user.me.useQuery();
267
- const posts = trpc.post.list.useQuery();
268
- const notifications = trpc.notification.unread.useQuery();
269
- // These are batched into a single HTTP request
270
- ```
271
-
272
- ---
273
-
274
- ## Error Handling
275
-
276
- ### Error Codes
277
-
278
- ```typescript
279
- throw new TRPCError({
280
- code: 'NOT_FOUND', // 404
281
- code: 'BAD_REQUEST', // 400
282
- code: 'UNAUTHORIZED', // 401
283
- code: 'FORBIDDEN', // 403
284
- code: 'CONFLICT', // 409
285
- code: 'INTERNAL_SERVER_ERROR', // 500
286
- message: 'Descriptive message',
287
- cause: originalError,
288
- });
289
- ```
290
-
291
- ### Client Error Handling
292
-
293
- ```typescript
294
- const mutation = trpc.post.create.useMutation({
295
- onError: (error) => {
296
- if (error.data?.code === 'CONFLICT') {
297
- toast.error('Post with this title already exists');
298
- } else if (error.data?.zodError) {
299
- // Validation errors
300
- const fieldErrors = error.data.zodError.fieldErrors;
301
- Object.entries(fieldErrors).forEach(([field, errors]) => {
302
- toast.error(`${field}: ${errors?.join(', ')}`);
303
- });
304
- } else {
305
- toast.error(error.message);
306
- }
307
- },
308
- });
309
- ```
310
-
311
- ---
312
-
313
- ## Client Setup
314
-
315
- ### React Provider
316
-
317
- ```typescript
318
- // lib/trpc/react.tsx
319
- 'use client';
320
-
321
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
322
- import { httpBatchLink } from '@trpc/client';
323
- import { createTRPCReact } from '@trpc/react-query';
324
- import { useState } from 'react';
325
- import superjson from 'superjson';
326
- import { type AppRouter } from '@/server/trpc/routers/_app';
327
-
328
- export const trpc = createTRPCReact<AppRouter>();
329
-
330
- export function TRPCProvider({ children }: { children: React.ReactNode }) {
331
- const [queryClient] = useState(() => new QueryClient({
332
- defaultOptions: {
333
- queries: {
334
- staleTime: 5 * 1000,
335
- refetchOnWindowFocus: false,
336
- },
337
- },
338
- }));
339
-
340
- const [trpcClient] = useState(() =>
341
- trpc.createClient({
342
- links: [
343
- httpBatchLink({
344
- url: '/api/trpc',
345
- transformer: superjson,
346
- }),
347
- ],
348
- })
349
- );
350
-
351
- return (
352
- <trpc.Provider client={trpcClient} queryClient={queryClient}>
353
- <QueryClientProvider client={queryClient}>
354
- {children}
355
- </QueryClientProvider>
356
- </trpc.Provider>
357
- );
358
- }
359
- ```
360
-
361
- ### Usage in Components
362
-
363
- ```typescript
364
- 'use client';
365
-
366
- import { trpc } from '@/lib/trpc/react';
367
-
368
- export function UserProfile() {
369
- const { data: user, isLoading } = trpc.user.me.useQuery();
370
- const updateProfile = trpc.user.updateProfile.useMutation();
371
-
372
- if (isLoading) return <Skeleton />;
373
- if (!user) return null;
374
-
375
- return (
376
- <form onSubmit={(e) => {
377
- e.preventDefault();
378
- updateProfile.mutate({ name: 'New Name' });
379
- }}>
380
- <input defaultValue={user.name} />
381
- <button type="submit" disabled={updateProfile.isPending}>
382
- Save
383
- </button>
384
- </form>
385
- );
386
- }
387
- ```
388
-
389
- ---
390
-
391
- ## Next.js Handler
392
-
393
- ```typescript
394
- // app/api/trpc/[trpc]/route.ts
395
- import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
396
- import { appRouter } from '@/server/trpc/routers/_app';
397
- import { createContext } from '@/server/trpc/context';
398
-
399
- const handler = (req: Request) =>
400
- fetchRequestHandler({
401
- endpoint: '/api/trpc',
402
- req,
403
- router: appRouter,
404
- createContext: () => createContext({ req }),
405
- });
406
-
407
- export { handler as GET, handler as POST };
408
- ```
409
-
410
- ---
411
-
412
- ## Agent Integration
413
-
414
- This skill is used by:
415
-
416
- - **trpc-expert** subagent
417
- - **api-documenter** for API documentation
418
- - **security-auditor** for route validation
419
- - **test-coverage** for API tests
420
-
421
- ---
422
-
423
- ## FORBIDDEN
424
-
425
- 1. **User ID from input** - ALWAYS use `ctx.user.id`
426
- 2. **Procedures without `.input()`** - Validate all inputs
427
- 3. **`any` in input schemas** - Use proper Zod types
428
- 4. **Sensitive data in responses** - Filter with `.select()`
429
- 5. **Public procedures for mutations** - Use `protectedProcedure`
430
-
431
- ---
432
-
433
- ## Version
434
-
435
- - **v1.0.0** - Initial implementation based on tRPC v11 patterns
1
+ ---
2
+ name: trpc-api
3
+ description: tRPC end-to-end type-safe API patterns. Router setup, procedures, middleware, context, client configuration. Use when building type-safe APIs with tRPC.
4
+ allowed-tools: Read, Write, Edit, Grep, Glob
5
+ ---
6
+
7
+ # tRPC API - End-to-End Type Safety
8
+
9
+ ## Purpose
10
+
11
+ Expert guidance for tRPC v11:
12
+
13
+ - **Router Setup** - Modular router architecture
14
+ - **Procedures** - Queries, mutations, subscriptions
15
+ - **Middleware** - Auth, logging, rate limiting
16
+ - **Context** - Session, database, utilities
17
+ - **Client** - React Query integration
18
+
19
+ ---
20
+
21
+ ## Project Structure
22
+
23
+ ```
24
+ server/
25
+ ├── trpc/
26
+ │ ├── index.ts # Router exports
27
+ │ ├── trpc.ts # tRPC instance
28
+ │ ├── context.ts # Context creation
29
+ │ └── routers/
30
+ │ ├── user.router.ts
31
+ │ ├── post.router.ts
32
+ │ └── _app.ts # Root router
33
+ app/
34
+ └── api/trpc/[trpc]/route.ts # Next.js handler
35
+ lib/
36
+ └── trpc/
37
+ ├── client.ts # tRPC client
38
+ └── react.tsx # React Query provider
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Server Setup
44
+
45
+ ### tRPC Instance
46
+
47
+ ```typescript
48
+ // server/trpc/trpc.ts
49
+ import { initTRPC, TRPCError } from '@trpc/server';
50
+ import superjson from 'superjson';
51
+ import { type Context } from './context';
52
+
53
+ const t = initTRPC.context<Context>().create({
54
+ transformer: superjson,
55
+ errorFormatter({ shape, error }) {
56
+ return {
57
+ ...shape,
58
+ data: {
59
+ ...shape.data,
60
+ zodError: error.cause instanceof ZodError ? error.cause.flatten() : null,
61
+ },
62
+ };
63
+ },
64
+ });
65
+
66
+ export const router = t.router;
67
+ export const publicProcedure = t.procedure;
68
+ export const middleware = t.middleware;
69
+ ```
70
+
71
+ ### Context
72
+
73
+ ```typescript
74
+ // server/trpc/context.ts
75
+ import { type CreateNextContextOptions } from '@trpc/server/adapters/next';
76
+ import { getServerSession } from 'next-auth';
77
+ import { authOptions } from '@/lib/auth';
78
+ import { db } from '@db';
79
+
80
+ export async function createContext(opts: CreateNextContextOptions) {
81
+ const session = await getServerSession(authOptions);
82
+
83
+ return {
84
+ session,
85
+ user: session?.user ?? null,
86
+ db,
87
+ req: opts.req,
88
+ res: opts.res,
89
+ };
90
+ }
91
+
92
+ export type Context = Awaited<ReturnType<typeof createContext>>;
93
+ ```
94
+
95
+ ### Auth Middleware
96
+
97
+ ```typescript
98
+ // server/trpc/trpc.ts
99
+ const isAuthed = middleware(({ ctx, next }) => {
100
+ if (!ctx.user) {
101
+ throw new TRPCError({
102
+ code: 'UNAUTHORIZED',
103
+ message: 'You must be logged in',
104
+ });
105
+ }
106
+ return next({
107
+ ctx: {
108
+ ...ctx,
109
+ user: ctx.user, // User is now guaranteed
110
+ },
111
+ });
112
+ });
113
+
114
+ export const protectedProcedure = t.procedure.use(isAuthed);
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Router Patterns
120
+
121
+ ### Basic Router
122
+
123
+ ```typescript
124
+ // server/trpc/routers/user.router.ts
125
+ import { z } from 'zod';
126
+ import { router, publicProcedure, protectedProcedure } from '../trpc';
127
+
128
+ export const userRouter = router({
129
+ // Query - fetch data
130
+ getById: publicProcedure
131
+ .input(z.object({ id: z.string().uuid() }))
132
+ .query(async ({ input, ctx }) => {
133
+ const user = await ctx.db.user.findUnique({
134
+ where: { id: input.id },
135
+ select: { id: true, name: true, email: true },
136
+ });
137
+
138
+ if (!user) {
139
+ throw new TRPCError({
140
+ code: 'NOT_FOUND',
141
+ message: 'User not found',
142
+ });
143
+ }
144
+
145
+ return user;
146
+ }),
147
+
148
+ // Mutation - modify data
149
+ updateProfile: protectedProcedure
150
+ .input(
151
+ z.object({
152
+ name: z.string().min(2).max(100),
153
+ bio: z.string().max(500).optional(),
154
+ })
155
+ )
156
+ .mutation(async ({ input, ctx }) => {
157
+ return ctx.db.user.update({
158
+ where: { id: ctx.user.id },
159
+ data: input,
160
+ });
161
+ }),
162
+
163
+ // Me - current user
164
+ me: protectedProcedure.query(async ({ ctx }) => {
165
+ return ctx.db.user.findUnique({
166
+ where: { id: ctx.user.id },
167
+ });
168
+ }),
169
+ });
170
+ ```
171
+
172
+ ### Root Router
173
+
174
+ ```typescript
175
+ // server/trpc/routers/_app.ts
176
+ import { router } from '../trpc';
177
+ import { userRouter } from './user.router';
178
+ import { postRouter } from './post.router';
179
+
180
+ export const appRouter = router({
181
+ user: userRouter,
182
+ post: postRouter,
183
+ });
184
+
185
+ export type AppRouter = typeof appRouter;
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Advanced Patterns
191
+
192
+ ### Pagination
193
+
194
+ ```typescript
195
+ const paginationSchema = z.object({
196
+ cursor: z.string().optional(),
197
+ limit: z.number().min(1).max(100).default(20),
198
+ });
199
+
200
+ export const postRouter = router({
201
+ list: publicProcedure.input(paginationSchema).query(async ({ input, ctx }) => {
202
+ const { cursor, limit } = input;
203
+
204
+ const posts = await ctx.db.post.findMany({
205
+ take: limit + 1,
206
+ cursor: cursor ? { id: cursor } : undefined,
207
+ orderBy: { createdAt: 'desc' },
208
+ });
209
+
210
+ let nextCursor: string | undefined;
211
+ if (posts.length > limit) {
212
+ const nextItem = posts.pop();
213
+ nextCursor = nextItem?.id;
214
+ }
215
+
216
+ return {
217
+ items: posts,
218
+ nextCursor,
219
+ };
220
+ }),
221
+ });
222
+ ```
223
+
224
+ ### Optimistic Updates
225
+
226
+ ```typescript
227
+ // Client-side with React Query
228
+ const utils = trpc.useUtils();
229
+
230
+ const createPost = trpc.post.create.useMutation({
231
+ onMutate: async (newPost) => {
232
+ // Cancel outgoing refetches
233
+ await utils.post.list.cancel();
234
+
235
+ // Snapshot previous value
236
+ const previousPosts = utils.post.list.getData();
237
+
238
+ // Optimistically update
239
+ utils.post.list.setData(undefined, (old) => {
240
+ if (!old) return { items: [newPost], nextCursor: undefined };
241
+ return { ...old, items: [newPost, ...old.items] };
242
+ });
243
+
244
+ return { previousPosts };
245
+ },
246
+
247
+ onError: (err, newPost, context) => {
248
+ // Rollback on error
249
+ utils.post.list.setData(undefined, context?.previousPosts);
250
+ },
251
+
252
+ onSettled: () => {
253
+ // Always refetch after error or success
254
+ utils.post.list.invalidate();
255
+ },
256
+ });
257
+ ```
258
+
259
+ ### Batch Requests
260
+
261
+ ```typescript
262
+ // tRPC automatically batches by default
263
+ // Multiple calls in same tick are batched
264
+
265
+ const user = trpc.user.me.useQuery();
266
+ const posts = trpc.post.list.useQuery();
267
+ const notifications = trpc.notification.unread.useQuery();
268
+ // These are batched into a single HTTP request
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Error Handling
274
+
275
+ ### Error Codes
276
+
277
+ ```typescript
278
+ throw new TRPCError({
279
+ code: 'NOT_FOUND', // 404
280
+ code: 'BAD_REQUEST', // 400
281
+ code: 'UNAUTHORIZED', // 401
282
+ code: 'FORBIDDEN', // 403
283
+ code: 'CONFLICT', // 409
284
+ code: 'INTERNAL_SERVER_ERROR', // 500
285
+ message: 'Descriptive message',
286
+ cause: originalError,
287
+ });
288
+ ```
289
+
290
+ ### Client Error Handling
291
+
292
+ ```typescript
293
+ const mutation = trpc.post.create.useMutation({
294
+ onError: (error) => {
295
+ if (error.data?.code === 'CONFLICT') {
296
+ toast.error('Post with this title already exists');
297
+ } else if (error.data?.zodError) {
298
+ // Validation errors
299
+ const fieldErrors = error.data.zodError.fieldErrors;
300
+ Object.entries(fieldErrors).forEach(([field, errors]) => {
301
+ toast.error(`${field}: ${errors?.join(', ')}`);
302
+ });
303
+ } else {
304
+ toast.error(error.message);
305
+ }
306
+ },
307
+ });
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Client Setup
313
+
314
+ ### React Provider
315
+
316
+ ```typescript
317
+ // lib/trpc/react.tsx
318
+ 'use client';
319
+
320
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
321
+ import { httpBatchLink } from '@trpc/client';
322
+ import { createTRPCReact } from '@trpc/react-query';
323
+ import { useState } from 'react';
324
+ import superjson from 'superjson';
325
+ import { type AppRouter } from '@/server/trpc/routers/_app';
326
+
327
+ export const trpc = createTRPCReact<AppRouter>();
328
+
329
+ export function TRPCProvider({ children }: { children: React.ReactNode }) {
330
+ const [queryClient] = useState(() => new QueryClient({
331
+ defaultOptions: {
332
+ queries: {
333
+ staleTime: 5 * 1000,
334
+ refetchOnWindowFocus: false,
335
+ },
336
+ },
337
+ }));
338
+
339
+ const [trpcClient] = useState(() =>
340
+ trpc.createClient({
341
+ links: [
342
+ httpBatchLink({
343
+ url: '/api/trpc',
344
+ transformer: superjson,
345
+ }),
346
+ ],
347
+ })
348
+ );
349
+
350
+ return (
351
+ <trpc.Provider client={trpcClient} queryClient={queryClient}>
352
+ <QueryClientProvider client={queryClient}>
353
+ {children}
354
+ </QueryClientProvider>
355
+ </trpc.Provider>
356
+ );
357
+ }
358
+ ```
359
+
360
+ ### Usage in Components
361
+
362
+ ```typescript
363
+ 'use client';
364
+
365
+ import { trpc } from '@/lib/trpc/react';
366
+
367
+ export function UserProfile() {
368
+ const { data: user, isLoading } = trpc.user.me.useQuery();
369
+ const updateProfile = trpc.user.updateProfile.useMutation();
370
+
371
+ if (isLoading) return <Skeleton />;
372
+ if (!user) return null;
373
+
374
+ return (
375
+ <form onSubmit={(e) => {
376
+ e.preventDefault();
377
+ updateProfile.mutate({ name: 'New Name' });
378
+ }}>
379
+ <input defaultValue={user.name} />
380
+ <button type="submit" disabled={updateProfile.isPending}>
381
+ Save
382
+ </button>
383
+ </form>
384
+ );
385
+ }
386
+ ```
387
+
388
+ ---
389
+
390
+ ## Next.js Handler
391
+
392
+ ```typescript
393
+ // app/api/trpc/[trpc]/route.ts
394
+ import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
395
+ import { appRouter } from '@/server/trpc/routers/_app';
396
+ import { createContext } from '@/server/trpc/context';
397
+
398
+ const handler = (req: Request) =>
399
+ fetchRequestHandler({
400
+ endpoint: '/api/trpc',
401
+ req,
402
+ router: appRouter,
403
+ createContext: () => createContext({ req }),
404
+ });
405
+
406
+ export { handler as GET, handler as POST };
407
+ ```
408
+
409
+ ---
410
+
411
+ ## Agent Integration
412
+
413
+ This skill is used by:
414
+
415
+ - **trpc-expert** subagent
416
+ - **api-documenter** for API documentation
417
+ - **security-auditor** for route validation
418
+ - **test-coverage** for API tests
419
+
420
+ ---
421
+
422
+ ## FORBIDDEN
423
+
424
+ 1. **User ID from input** - ALWAYS use `ctx.user.id`
425
+ 2. **Procedures without `.input()`** - Validate all inputs
426
+ 3. **`any` in input schemas** - Use proper Zod types
427
+ 4. **Sensitive data in responses** - Filter with `.select()`
428
+ 5. **Public procedures for mutations** - Use `protectedProcedure`
429
+
430
+ ---
431
+
432
+ ## Version
433
+
434
+ - **v1.0.0** - Initial implementation based on tRPC v11 patterns