@smicolon/ai-kit 0.0.1 → 0.1.1

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 (163) hide show
  1. package/.claude-plugin/CLAUDE.md +7 -0
  2. package/.claude-plugin/marketplace.json +373 -0
  3. package/README.md +132 -0
  4. package/package.json +13 -3
  5. package/packs/architect/CHANGELOG.md +17 -0
  6. package/packs/architect/README.md +58 -0
  7. package/packs/architect/agents/system-architect.md +768 -0
  8. package/packs/architect/commands/diagram-create.md +300 -0
  9. package/packs/better-auth/.claude-plugin/plugin.json +14 -0
  10. package/packs/better-auth/.mcp.json +14 -0
  11. package/packs/better-auth/CHANGELOG.md +26 -0
  12. package/packs/better-auth/README.md +125 -0
  13. package/packs/better-auth/agents/auth-architect.md +278 -0
  14. package/packs/better-auth/commands/auth-provider-add.md +265 -0
  15. package/packs/better-auth/commands/auth-setup.md +298 -0
  16. package/packs/better-auth/skills/auth-security/SKILL.md +425 -0
  17. package/packs/better-auth/skills/better-auth-patterns/SKILL.md +455 -0
  18. package/packs/dev-loop/.claude-plugin/plugin.json +10 -0
  19. package/packs/dev-loop/CHANGELOG.md +69 -0
  20. package/packs/dev-loop/README.md +155 -0
  21. package/packs/dev-loop/commands/cancel-dev.md +21 -0
  22. package/packs/dev-loop/commands/dev-loop.md +72 -0
  23. package/packs/dev-loop/commands/dev-plan.md +351 -0
  24. package/packs/dev-loop/hooks/hooks.json +15 -0
  25. package/packs/dev-loop/hooks/stop-hook.sh +178 -0
  26. package/packs/dev-loop/scripts/setup-dev-loop.sh +194 -0
  27. package/packs/dev-loop/skills/tdd-planner/SKILL.md +249 -0
  28. package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +874 -0
  29. package/packs/dev-loop/skills/tdd-planner/references/good-example.md +260 -0
  30. package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +275 -0
  31. package/packs/django/CHANGELOG.md +39 -0
  32. package/packs/django/README.md +92 -0
  33. package/packs/django/agents/django-architect.md +182 -0
  34. package/packs/django/agents/django-builder.md +250 -0
  35. package/packs/django/agents/django-feature-based.md +420 -0
  36. package/packs/django/agents/django-reviewer.md +253 -0
  37. package/packs/django/agents/django-tester.md +230 -0
  38. package/packs/django/commands/api-endpoint.md +285 -0
  39. package/packs/django/commands/model-create.md +178 -0
  40. package/packs/django/commands/test-generate.md +325 -0
  41. package/packs/django/rules/migrations.md +138 -0
  42. package/packs/django/rules/models.md +167 -0
  43. package/packs/django/rules/serializers.md +126 -0
  44. package/packs/django/rules/services.md +131 -0
  45. package/packs/django/rules/tests.md +140 -0
  46. package/packs/django/rules/views.md +102 -0
  47. package/packs/django/skills/import-convention-enforcer/SKILL.md +226 -0
  48. package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +343 -0
  49. package/packs/django/skills/migration-safety-checker/SKILL.md +375 -0
  50. package/packs/django/skills/model-entity-validator/SKILL.md +298 -0
  51. package/packs/django/skills/performance-optimizer/SKILL.md +447 -0
  52. package/packs/django/skills/red-phase-verifier/SKILL.md +180 -0
  53. package/packs/django/skills/security-first-validator/SKILL.md +435 -0
  54. package/packs/django/skills/test-coverage-advisor/SKILL.md +394 -0
  55. package/packs/django/skills/test-validity-checker/SKILL.md +194 -0
  56. package/packs/failure-log/.claude-plugin/plugin.json +14 -0
  57. package/packs/failure-log/CHANGELOG.md +20 -0
  58. package/packs/failure-log/README.md +168 -0
  59. package/packs/failure-log/commands/failure-add.md +106 -0
  60. package/packs/failure-log/commands/failure-list.md +89 -0
  61. package/packs/failure-log/hooks/hooks.json +16 -0
  62. package/packs/failure-log/hooks/scripts/inject-failures.sh +64 -0
  63. package/packs/failure-log/skills/failure-log-manager/SKILL.md +164 -0
  64. package/packs/flutter/.claude-plugin/plugin.json +10 -0
  65. package/packs/flutter/CHANGELOG.md +19 -0
  66. package/packs/flutter/README.md +170 -0
  67. package/packs/flutter/agents/flutter-architect.md +166 -0
  68. package/packs/flutter/agents/flutter-builder.md +303 -0
  69. package/packs/flutter/agents/release-manager.md +355 -0
  70. package/packs/flutter/commands/fastlane-setup.md +188 -0
  71. package/packs/flutter/commands/flutter-build.md +90 -0
  72. package/packs/flutter/commands/flutter-deploy.md +133 -0
  73. package/packs/flutter/commands/flutter-test.md +117 -0
  74. package/packs/flutter/commands/signing-setup.md +209 -0
  75. package/packs/flutter/hooks/hooks.json +17 -0
  76. package/packs/flutter/skills/fastlane-knowledge/SKILL.md +193 -0
  77. package/packs/flutter/skills/flutter-architecture/SKILL.md +127 -0
  78. package/packs/flutter/skills/store-publishing/SKILL.md +163 -0
  79. package/packs/hono/.claude-plugin/plugin.json +19 -0
  80. package/packs/hono/CHANGELOG.md +19 -0
  81. package/packs/hono/README.md +143 -0
  82. package/packs/hono/agents/hono-architect.md +240 -0
  83. package/packs/hono/agents/hono-builder.md +285 -0
  84. package/packs/hono/agents/hono-reviewer.md +279 -0
  85. package/packs/hono/agents/hono-tester.md +346 -0
  86. package/packs/hono/commands/middleware-create.md +223 -0
  87. package/packs/hono/commands/project-init.md +306 -0
  88. package/packs/hono/commands/route-create.md +153 -0
  89. package/packs/hono/commands/rpc-client.md +263 -0
  90. package/packs/hono/hooks/hooks.json +4 -0
  91. package/packs/hono/skills/cloudflare-bindings/SKILL.md +408 -0
  92. package/packs/hono/skills/hono-patterns/SKILL.md +309 -0
  93. package/packs/hono/skills/rpc-typesafe/SKILL.md +388 -0
  94. package/packs/hono/skills/zod-validation/SKILL.md +332 -0
  95. package/packs/nestjs/CHANGELOG.md +29 -0
  96. package/packs/nestjs/README.md +75 -0
  97. package/packs/nestjs/agents/nestjs-architect.md +402 -0
  98. package/packs/nestjs/agents/nestjs-builder.md +301 -0
  99. package/packs/nestjs/agents/nestjs-tester.md +437 -0
  100. package/packs/nestjs/commands/module-create.md +369 -0
  101. package/packs/nestjs/rules/controllers.md +92 -0
  102. package/packs/nestjs/rules/dto.md +124 -0
  103. package/packs/nestjs/rules/entities.md +102 -0
  104. package/packs/nestjs/rules/services.md +106 -0
  105. package/packs/nestjs/skills/barrel-export-manager/SKILL.md +389 -0
  106. package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +365 -0
  107. package/packs/nextjs/CHANGELOG.md +36 -0
  108. package/packs/nextjs/README.md +76 -0
  109. package/packs/nextjs/agents/frontend-tester.md +680 -0
  110. package/packs/nextjs/agents/frontend-visual.md +820 -0
  111. package/packs/nextjs/agents/nextjs-architect.md +331 -0
  112. package/packs/nextjs/agents/nextjs-modular.md +433 -0
  113. package/packs/nextjs/commands/component-create.md +398 -0
  114. package/packs/nextjs/rules/api-routes.md +129 -0
  115. package/packs/nextjs/rules/components.md +106 -0
  116. package/packs/nextjs/rules/hooks.md +132 -0
  117. package/packs/nextjs/skills/accessibility-validator/SKILL.md +445 -0
  118. package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +399 -0
  119. package/packs/nextjs/skills/react-form-validator/SKILL.md +569 -0
  120. package/packs/nuxtjs/CHANGELOG.md +30 -0
  121. package/packs/nuxtjs/README.md +56 -0
  122. package/packs/nuxtjs/agents/frontend-tester.md +680 -0
  123. package/packs/nuxtjs/agents/frontend-visual.md +820 -0
  124. package/packs/nuxtjs/agents/nuxtjs-architect.md +537 -0
  125. package/packs/nuxtjs/commands/component-create.md +223 -0
  126. package/packs/nuxtjs/rules/components.md +101 -0
  127. package/packs/nuxtjs/rules/composables.md +118 -0
  128. package/packs/nuxtjs/rules/server-routes.md +127 -0
  129. package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +183 -0
  130. package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +196 -0
  131. package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +190 -0
  132. package/packs/onboard/CHANGELOG.md +22 -0
  133. package/packs/onboard/README.md +103 -0
  134. package/packs/onboard/agents/onboard-guide.md +118 -0
  135. package/packs/onboard/commands/onboard.md +313 -0
  136. package/packs/onboard/skills/onboard-context-provider/SKILL.md +98 -0
  137. package/packs/tanstack-router/.claude-plugin/plugin.json +14 -0
  138. package/packs/tanstack-router/CHANGELOG.md +30 -0
  139. package/packs/tanstack-router/README.md +113 -0
  140. package/packs/tanstack-router/agents/tanstack-architect.md +173 -0
  141. package/packs/tanstack-router/agents/tanstack-builder.md +360 -0
  142. package/packs/tanstack-router/agents/tanstack-tester.md +454 -0
  143. package/packs/tanstack-router/commands/form-create.md +313 -0
  144. package/packs/tanstack-router/commands/query-create.md +263 -0
  145. package/packs/tanstack-router/commands/route-create.md +190 -0
  146. package/packs/tanstack-router/commands/table-create.md +413 -0
  147. package/packs/tanstack-router/skills/ai-patterns/SKILL.md +370 -0
  148. package/packs/tanstack-router/skills/db-patterns/SKILL.md +346 -0
  149. package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +415 -0
  150. package/packs/tanstack-router/skills/form-patterns/SKILL.md +425 -0
  151. package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +341 -0
  152. package/packs/tanstack-router/skills/query-patterns/SKILL.md +359 -0
  153. package/packs/tanstack-router/skills/router-patterns/SKILL.md +285 -0
  154. package/packs/tanstack-router/skills/store-patterns/SKILL.md +351 -0
  155. package/packs/tanstack-router/skills/table-patterns/SKILL.md +531 -0
  156. package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +428 -0
  157. package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +490 -0
  158. package/packs/worktree/.claude-plugin/plugin.json +19 -0
  159. package/packs/worktree/CHANGELOG.md +24 -0
  160. package/packs/worktree/README.md +110 -0
  161. package/packs/worktree/commands/wt.md +73 -0
  162. package/packs/worktree/scripts/wt.sh +396 -0
  163. package/packs/worktree/skills/worktree-manager/SKILL.md +68 -0
@@ -0,0 +1,313 @@
1
+ ---
2
+ name: form-create
3
+ description: Create TanStack Form components with Zod validation
4
+ args:
5
+ - name: name
6
+ description: Form name (e.g., CreatePost, EditUser, Login)
7
+ required: false
8
+ - name: feature
9
+ description: Feature the form belongs to (e.g., posts, users, auth)
10
+ required: false
11
+ ---
12
+
13
+ # Create TanStack Form
14
+
15
+ Create a form component with TanStack Form and Zod validation.
16
+
17
+ ## Instructions
18
+
19
+ 1. **Gather Information** (if not provided via args):
20
+ - Ask for the form name (e.g., `CreatePostForm`, `EditUserForm`)
21
+ - Ask for the feature it belongs to
22
+ - Ask for the fields the form should have
23
+ - Ask if it should integrate with a mutation hook
24
+
25
+ 2. **Create Zod Schema** in `src/features/{feature}/schemas/{name}Schema.ts`:
26
+ ```typescript
27
+ import { z } from 'zod'
28
+
29
+ export const {name}Schema = z.object({
30
+ title: z.string().min(3, 'Title must be at least 3 characters'),
31
+ content: z.string().min(10, 'Content must be at least 10 characters'),
32
+ email: z.string().email('Invalid email address'),
33
+ // Add more fields as needed
34
+ })
35
+
36
+ export type {Name}FormData = z.infer<typeof {name}Schema>
37
+ ```
38
+
39
+ 3. **Create Form Component** in `src/features/{feature}/components/{Name}Form.tsx`:
40
+
41
+ For a **create form**:
42
+ ```typescript
43
+ import { useForm } from '@tanstack/react-form'
44
+ import { zodValidator } from '@tanstack/zod-form-adapter'
45
+ import { {name}Schema, type {Name}FormData } from '../schemas/{name}Schema'
46
+ import { useCreate{Feature} } from '../hooks'
47
+ import { FormField } from '@/components/ui/FormField'
48
+
49
+ interface {Name}FormProps {
50
+ onSuccess?: () => void
51
+ }
52
+
53
+ export function {Name}Form({ onSuccess }: {Name}FormProps) {
54
+ const create{Feature} = useCreate{Feature}()
55
+
56
+ const form = useForm({
57
+ defaultValues: {
58
+ title: '',
59
+ content: '',
60
+ // ... default values for all fields
61
+ } satisfies {Name}FormData,
62
+ onSubmit: async ({ value }) => {
63
+ await create{Feature}.mutateAsync(value)
64
+ onSuccess?.()
65
+ },
66
+ validatorAdapter: zodValidator(),
67
+ validators: {
68
+ onChange: {name}Schema,
69
+ },
70
+ })
71
+
72
+ return (
73
+ <form
74
+ onSubmit={(e) => {
75
+ e.preventDefault()
76
+ form.handleSubmit()
77
+ }}
78
+ className="space-y-4"
79
+ >
80
+ <form.Field
81
+ name="title"
82
+ children={(field) => (
83
+ <div className="form-field">
84
+ <label htmlFor={field.name}>Title</label>
85
+ <input
86
+ id={field.name}
87
+ value={field.state.value}
88
+ onChange={(e) => field.handleChange(e.target.value)}
89
+ onBlur={field.handleBlur}
90
+ aria-invalid={field.state.meta.errors.length > 0}
91
+ aria-describedby={`${field.name}-error`}
92
+ />
93
+ {field.state.meta.isTouched && field.state.meta.errors.length > 0 && (
94
+ <span id={`${field.name}-error`} className="error" role="alert">
95
+ {field.state.meta.errors[0]}
96
+ </span>
97
+ )}
98
+ </div>
99
+ )}
100
+ />
101
+
102
+ <form.Field
103
+ name="content"
104
+ children={(field) => (
105
+ <div className="form-field">
106
+ <label htmlFor={field.name}>Content</label>
107
+ <textarea
108
+ id={field.name}
109
+ value={field.state.value}
110
+ onChange={(e) => field.handleChange(e.target.value)}
111
+ onBlur={field.handleBlur}
112
+ rows={5}
113
+ aria-invalid={field.state.meta.errors.length > 0}
114
+ />
115
+ {field.state.meta.isTouched && field.state.meta.errors.length > 0 && (
116
+ <span className="error" role="alert">
117
+ {field.state.meta.errors[0]}
118
+ </span>
119
+ )}
120
+ </div>
121
+ )}
122
+ />
123
+
124
+ {/* Add more fields as needed */}
125
+
126
+ <form.Subscribe
127
+ selector={(state) => [state.canSubmit, state.isSubmitting]}
128
+ children={([canSubmit, isSubmitting]) => (
129
+ <button
130
+ type="submit"
131
+ disabled={!canSubmit || isSubmitting}
132
+ className="btn btn-primary"
133
+ >
134
+ {isSubmitting ? 'Saving...' : 'Save'}
135
+ </button>
136
+ )}
137
+ />
138
+
139
+ {create{Feature}.isError && (
140
+ <div className="error" role="alert">
141
+ {create{Feature}.error.message}
142
+ </div>
143
+ )}
144
+ </form>
145
+ )
146
+ }
147
+ ```
148
+
149
+ For an **edit form** with initial data:
150
+ ```typescript
151
+ import { useForm } from '@tanstack/react-form'
152
+ import { zodValidator } from '@tanstack/zod-form-adapter'
153
+ import { {name}Schema, type {Name}FormData } from '../schemas/{name}Schema'
154
+ import { useUpdate{Feature} } from '../hooks'
155
+ import type { {Feature} } from '../types'
156
+
157
+ interface {Name}FormProps {
158
+ {feature}: {Feature}
159
+ onSuccess?: () => void
160
+ }
161
+
162
+ export function {Name}Form({ {feature}, onSuccess }: {Name}FormProps) {
163
+ const update{Feature} = useUpdate{Feature}()
164
+
165
+ const form = useForm({
166
+ defaultValues: {
167
+ title: {feature}.title,
168
+ content: {feature}.content,
169
+ // ... populate from existing data
170
+ } satisfies {Name}FormData,
171
+ onSubmit: async ({ value }) => {
172
+ await update{Feature}.mutateAsync({ id: {feature}.id, ...value })
173
+ onSuccess?.()
174
+ },
175
+ validatorAdapter: zodValidator(),
176
+ validators: {
177
+ onChange: {name}Schema,
178
+ },
179
+ })
180
+
181
+ return (
182
+ <form onSubmit={(e) => { e.preventDefault(); form.handleSubmit() }}>
183
+ {/* Same field structure as create form */}
184
+ </form>
185
+ )
186
+ }
187
+ ```
188
+
189
+ 4. **Create Reusable Form Field Component** (if not exists) in `src/components/ui/FormField.tsx`:
190
+ ```typescript
191
+ import type { FieldApi } from '@tanstack/react-form'
192
+
193
+ interface FormFieldProps<T> {
194
+ field: FieldApi<any, any, any, any, T>
195
+ label: string
196
+ type?: 'text' | 'email' | 'password' | 'textarea' | 'number'
197
+ placeholder?: string
198
+ }
199
+
200
+ export function FormField<T extends string | number>({
201
+ field,
202
+ label,
203
+ type = 'text',
204
+ placeholder,
205
+ }: FormFieldProps<T>) {
206
+ const hasError = field.state.meta.isTouched && field.state.meta.errors.length > 0
207
+
208
+ const inputProps = {
209
+ id: field.name,
210
+ name: field.name,
211
+ value: field.state.value,
212
+ onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
213
+ const value = type === 'number' ? Number(e.target.value) : e.target.value
214
+ field.handleChange(value as T)
215
+ },
216
+ onBlur: field.handleBlur,
217
+ placeholder,
218
+ 'aria-invalid': hasError,
219
+ 'aria-describedby': hasError ? `${field.name}-error` : undefined,
220
+ }
221
+
222
+ return (
223
+ <div className="form-field">
224
+ <label htmlFor={field.name}>{label}</label>
225
+ {type === 'textarea' ? (
226
+ <textarea {...inputProps} rows={5} />
227
+ ) : (
228
+ <input type={type} {...inputProps} />
229
+ )}
230
+ {hasError && (
231
+ <span id={`${field.name}-error`} className="error" role="alert">
232
+ {field.state.meta.errors[0]}
233
+ </span>
234
+ )}
235
+ </div>
236
+ )
237
+ }
238
+ ```
239
+
240
+ 5. **Handle Array Fields** (if needed):
241
+ ```typescript
242
+ <form.Field
243
+ name="tags"
244
+ mode="array"
245
+ children={(field) => (
246
+ <div className="form-field">
247
+ <label>Tags</label>
248
+ {field.state.value.map((_, index) => (
249
+ <div key={index} className="flex gap-2">
250
+ <form.Field
251
+ name={`tags[${index}]`}
252
+ children={(tagField) => (
253
+ <input
254
+ value={tagField.state.value}
255
+ onChange={(e) => tagField.handleChange(e.target.value)}
256
+ />
257
+ )}
258
+ />
259
+ <button type="button" onClick={() => field.removeValue(index)}>
260
+ Remove
261
+ </button>
262
+ </div>
263
+ ))}
264
+ <button type="button" onClick={() => field.pushValue('')}>
265
+ Add Tag
266
+ </button>
267
+ </div>
268
+ )}
269
+ />
270
+ ```
271
+
272
+ 6. **Add Async Validation** (if needed):
273
+ ```typescript
274
+ <form.Field
275
+ name="username"
276
+ validators={{
277
+ onChange: z.string().min(3),
278
+ onChangeAsyncDebounceMs: 500,
279
+ onChangeAsync: async ({ value }) => {
280
+ const exists = await checkUsernameExists(value)
281
+ return exists ? 'Username already taken' : undefined
282
+ },
283
+ }}
284
+ children={(field) => (
285
+ <div>
286
+ <input {...inputProps} />
287
+ {field.state.meta.isValidating && <span>Checking...</span>}
288
+ {/* error display */}
289
+ </div>
290
+ )}
291
+ />
292
+ ```
293
+
294
+ 7. **Update Barrel Exports**:
295
+ ```typescript
296
+ // src/features/{feature}/components/index.ts
297
+ export { {Name}Form } from './{Name}Form'
298
+
299
+ // src/features/{feature}/schemas/index.ts
300
+ export * from './{name}Schema'
301
+ ```
302
+
303
+ ## Quality Checklist
304
+
305
+ - [ ] Zod schema validates all fields
306
+ - [ ] Form uses `zodValidator()` adapter
307
+ - [ ] All fields have proper labels with htmlFor
308
+ - [ ] Error messages use role="alert" for accessibility
309
+ - [ ] aria-invalid and aria-describedby properly set
310
+ - [ ] Submit button disabled during submission
311
+ - [ ] Mutation errors displayed to user
312
+ - [ ] defaultValues use `satisfies` for type checking
313
+ - [ ] Form prevents default submission
@@ -0,0 +1,263 @@
1
+ ---
2
+ name: query-create
3
+ description: Create TanStack Query options, mutations, and hooks with factory pattern
4
+ args:
5
+ - name: feature
6
+ description: Feature name (e.g., posts, users, orders)
7
+ required: false
8
+ - name: type
9
+ description: Query type (query, mutation, infinite)
10
+ required: false
11
+ ---
12
+
13
+ # Create TanStack Query
14
+
15
+ Create query options, mutations, and hooks following the factory pattern.
16
+
17
+ ## Instructions
18
+
19
+ 1. **Gather Information** (if not provided via args):
20
+ - Ask for the feature name (e.g., `posts`, `users`)
21
+ - Ask for the query type: query, mutation, or infinite query
22
+ - Ask for the operation (e.g., list, detail, create, update, delete)
23
+
24
+ 2. **Create Feature Directory Structure** (if new feature):
25
+ ```
26
+ src/features/{feature}/
27
+ ├── api/
28
+ │ └── {feature}Api.ts
29
+ ├── queries/
30
+ │ ├── {feature}Queries.ts
31
+ │ └── index.ts
32
+ ├── hooks/
33
+ │ ├── use{Operation}{Feature}.ts
34
+ │ └── index.ts
35
+ ├── types.ts
36
+ └── index.ts
37
+ ```
38
+
39
+ 3. **Create/Update Query Keys** in `src/lib/query-keys.ts`:
40
+ ```typescript
41
+ export const queryKeys = {
42
+ {feature}: {
43
+ all: () => ['{feature}'] as const,
44
+ lists: () => [...queryKeys.{feature}.all(), 'list'] as const,
45
+ list: (filters: {Feature}Filters) => [...queryKeys.{feature}.lists(), filters] as const,
46
+ details: () => [...queryKeys.{feature}.all(), 'detail'] as const,
47
+ detail: (id: string) => [...queryKeys.{feature}.details(), id] as const,
48
+ },
49
+ } as const
50
+ ```
51
+
52
+ 4. **Create API Functions** in `src/features/{feature}/api/{feature}Api.ts`:
53
+ ```typescript
54
+ import { apiClient } from '@/lib/api-client'
55
+ import type { {Feature}, Create{Feature}Input, Update{Feature}Input, {Feature}Filters } from '../types'
56
+
57
+ export const {feature}Api = {
58
+ get{Feature}s: async (filters?: {Feature}Filters): Promise<{Feature}[]> => {
59
+ const response = await apiClient.get('/{feature}', { params: filters })
60
+ return response.data
61
+ },
62
+
63
+ get{Feature}: async (id: string): Promise<{Feature}> => {
64
+ const response = await apiClient.get(`/{feature}/${id}`)
65
+ return response.data
66
+ },
67
+
68
+ create{Feature}: async (input: Create{Feature}Input): Promise<{Feature}> => {
69
+ const response = await apiClient.post('/{feature}', input)
70
+ return response.data
71
+ },
72
+
73
+ update{Feature}: async ({ id, ...input }: Update{Feature}Input): Promise<{Feature}> => {
74
+ const response = await apiClient.patch(`/{feature}/${id}`, input)
75
+ return response.data
76
+ },
77
+
78
+ delete{Feature}: async (id: string): Promise<void> => {
79
+ await apiClient.delete(`/{feature}/${id}`)
80
+ },
81
+ }
82
+ ```
83
+
84
+ 5. **Create Query Options** in `src/features/{feature}/queries/{feature}Queries.ts`:
85
+
86
+ For **list query**:
87
+ ```typescript
88
+ import { queryOptions } from '@tanstack/react-query'
89
+ import { queryKeys } from '@/lib/query-keys'
90
+ import { {feature}Api } from '../api/{feature}Api'
91
+ import type { {Feature}Filters } from '../types'
92
+
93
+ export const {feature}sQueryOptions = (filters: {Feature}Filters = {}) =>
94
+ queryOptions({
95
+ queryKey: queryKeys.{feature}.list(filters),
96
+ queryFn: () => {feature}Api.get{Feature}s(filters),
97
+ staleTime: 1 * 60 * 1000, // 1 minute
98
+ })
99
+ ```
100
+
101
+ For **detail query**:
102
+ ```typescript
103
+ export const {feature}QueryOptions = (id: string) =>
104
+ queryOptions({
105
+ queryKey: queryKeys.{feature}.detail(id),
106
+ queryFn: () => {feature}Api.get{Feature}(id),
107
+ staleTime: 5 * 60 * 1000, // 5 minutes
108
+ })
109
+ ```
110
+
111
+ For **infinite query**:
112
+ ```typescript
113
+ import { infiniteQueryOptions } from '@tanstack/react-query'
114
+
115
+ export const {feature}sInfiniteQueryOptions = (filters: {Feature}Filters = {}) =>
116
+ infiniteQueryOptions({
117
+ queryKey: queryKeys.{feature}.list({ ...filters, infinite: true }),
118
+ queryFn: ({ pageParam = 1 }) =>
119
+ {feature}Api.get{Feature}s({ ...filters, page: pageParam }),
120
+ getNextPageParam: (lastPage) =>
121
+ lastPage.hasMore ? lastPage.nextPage : undefined,
122
+ initialPageParam: 1,
123
+ })
124
+ ```
125
+
126
+ 6. **Create Mutation Hooks** in `src/features/{feature}/hooks/`:
127
+
128
+ For **create mutation** (`useCreate{Feature}.ts`):
129
+ ```typescript
130
+ import { useMutation, useQueryClient } from '@tanstack/react-query'
131
+ import { queryKeys } from '@/lib/query-keys'
132
+ import { {feature}Api } from '../api/{feature}Api'
133
+
134
+ export function useCreate{Feature}() {
135
+ const queryClient = useQueryClient()
136
+
137
+ return useMutation({
138
+ mutationFn: {feature}Api.create{Feature},
139
+ onSuccess: () => {
140
+ queryClient.invalidateQueries({ queryKey: queryKeys.{feature}.lists() })
141
+ },
142
+ })
143
+ }
144
+ ```
145
+
146
+ For **update mutation** with optimistic update (`useUpdate{Feature}.ts`):
147
+ ```typescript
148
+ import { useMutation, useQueryClient } from '@tanstack/react-query'
149
+ import { queryKeys } from '@/lib/query-keys'
150
+ import { {feature}Api } from '../api/{feature}Api'
151
+ import type { {Feature}, Update{Feature}Input } from '../types'
152
+
153
+ export function useUpdate{Feature}() {
154
+ const queryClient = useQueryClient()
155
+
156
+ return useMutation({
157
+ mutationFn: {feature}Api.update{Feature},
158
+ onMutate: async (newData: Update{Feature}Input) => {
159
+ await queryClient.cancelQueries({
160
+ queryKey: queryKeys.{feature}.detail(newData.id)
161
+ })
162
+
163
+ const previous = queryClient.getQueryData<{Feature}>(
164
+ queryKeys.{feature}.detail(newData.id)
165
+ )
166
+
167
+ queryClient.setQueryData(
168
+ queryKeys.{feature}.detail(newData.id),
169
+ (old: {Feature} | undefined) => old ? { ...old, ...newData } : undefined
170
+ )
171
+
172
+ return { previous }
173
+ },
174
+ onError: (err, newData, context) => {
175
+ if (context?.previous) {
176
+ queryClient.setQueryData(
177
+ queryKeys.{feature}.detail(newData.id),
178
+ context.previous
179
+ )
180
+ }
181
+ },
182
+ onSettled: (data, error, variables) => {
183
+ queryClient.invalidateQueries({
184
+ queryKey: queryKeys.{feature}.detail(variables.id)
185
+ })
186
+ },
187
+ })
188
+ }
189
+ ```
190
+
191
+ For **delete mutation** (`useDelete{Feature}.ts`):
192
+ ```typescript
193
+ import { useMutation, useQueryClient } from '@tanstack/react-query'
194
+ import { queryKeys } from '@/lib/query-keys'
195
+ import { {feature}Api } from '../api/{feature}Api'
196
+
197
+ export function useDelete{Feature}() {
198
+ const queryClient = useQueryClient()
199
+
200
+ return useMutation({
201
+ mutationFn: {feature}Api.delete{Feature},
202
+ onSuccess: () => {
203
+ queryClient.invalidateQueries({ queryKey: queryKeys.{feature}.all() })
204
+ },
205
+ })
206
+ }
207
+ ```
208
+
209
+ 7. **Create Types** in `src/features/{feature}/types.ts`:
210
+ ```typescript
211
+ export interface {Feature} {
212
+ id: string
213
+ // ... feature fields
214
+ createdAt: string
215
+ updatedAt: string
216
+ }
217
+
218
+ export interface Create{Feature}Input {
219
+ // ... creation fields
220
+ }
221
+
222
+ export interface Update{Feature}Input extends Partial<Create{Feature}Input> {
223
+ id: string
224
+ }
225
+
226
+ export interface {Feature}Filters {
227
+ page?: number
228
+ pageSize?: number
229
+ search?: string
230
+ // ... filter fields
231
+ }
232
+ ```
233
+
234
+ 8. **Create Barrel Exports**:
235
+
236
+ `src/features/{feature}/queries/index.ts`:
237
+ ```typescript
238
+ export * from './{feature}Queries'
239
+ ```
240
+
241
+ `src/features/{feature}/hooks/index.ts`:
242
+ ```typescript
243
+ export * from './useCreate{Feature}'
244
+ export * from './useUpdate{Feature}'
245
+ export * from './useDelete{Feature}'
246
+ ```
247
+
248
+ `src/features/{feature}/index.ts`:
249
+ ```typescript
250
+ export * from './queries'
251
+ export * from './hooks'
252
+ export * from './types'
253
+ ```
254
+
255
+ ## Quality Checklist
256
+
257
+ - [ ] Query keys follow factory pattern
258
+ - [ ] Query options use `queryOptions()` helper
259
+ - [ ] Mutations invalidate relevant queries
260
+ - [ ] Optimistic updates include rollback logic
261
+ - [ ] Types are properly defined and exported
262
+ - [ ] Barrel exports are in place
263
+ - [ ] API functions match expected backend endpoints