create-velox-app 0.6.64 → 0.6.65
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.
- package/CHANGELOG.md +6 -0
- package/dist/templates/auth.js +0 -8
- package/dist/templates/shared/root.d.ts +7 -0
- package/dist/templates/shared/root.js +32 -0
- package/dist/templates/spa.js +0 -8
- package/dist/templates/trpc.js +0 -8
- package/package.json +1 -1
- package/src/templates/source/root/.claude/skills/veloxts/GENERATORS.md +313 -0
- package/src/templates/source/root/.claude/skills/veloxts/PROCEDURES.md +466 -0
- package/src/templates/source/root/.claude/skills/veloxts/SKILL.md +225 -0
- package/src/templates/source/root/.claude/skills/veloxts/TROUBLESHOOTING.md +416 -0
- package/src/templates/source/root/CLAUDE.auth.md +33 -1
- package/src/templates/source/root/CLAUDE.default.md +33 -1
- package/src/templates/source/root/CLAUDE.trpc.md +20 -0
- package/src/templates/source/rsc/CLAUDE.md +19 -0
- package/src/templates/source/rsc-auth/CLAUDE.md +19 -0
- package/src/templates/source/web/api.ts +4 -5
- package/src/templates/source/web/main.tsx +2 -2
- package/src/templates/source/web/routes/__root.tsx +1 -1
- package/src/templates/source/api/router.types.auth.ts +0 -88
- package/src/templates/source/api/router.types.default.ts +0 -73
- package/src/templates/source/api/router.types.trpc.ts +0 -73
- package/src/templates/source/api/routes.auth.ts +0 -66
- package/src/templates/source/api/routes.default.ts +0 -53
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
# VeloxTS Troubleshooting Guide
|
|
2
|
+
|
|
3
|
+
## MCP Server vs CLI
|
|
4
|
+
|
|
5
|
+
VeloxTS provides two ways to run generators and commands:
|
|
6
|
+
|
|
7
|
+
### CLI (Terminal)
|
|
8
|
+
|
|
9
|
+
Use directly in your terminal:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm velox make resource Post --crud
|
|
13
|
+
pnpm velox migrate status
|
|
14
|
+
pnpm velox db seed
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### MCP Server (AI Assistants)
|
|
18
|
+
|
|
19
|
+
For Claude Desktop or other MCP-compatible assistants, the `@veloxts/mcp` server provides the same functionality through a protocol interface.
|
|
20
|
+
|
|
21
|
+
**Setup** (Claude Desktop config):
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"mcpServers": {
|
|
25
|
+
"veloxts": {
|
|
26
|
+
"command": "npx",
|
|
27
|
+
"args": ["@veloxts/mcp"],
|
|
28
|
+
"cwd": "/path/to/your/project"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Key difference**: MCP needs the `cwd` path to find your project. The CLI auto-detects it.
|
|
35
|
+
|
|
36
|
+
**If MCP says "Not in a VeloxTS project"**:
|
|
37
|
+
1. Check that `cwd` points to your project root (where `package.json` is)
|
|
38
|
+
2. Ensure the project has VeloxTS dependencies installed
|
|
39
|
+
3. Fallback: Use CLI directly via terminal
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Procedure Errors
|
|
44
|
+
|
|
45
|
+
### "useQuery is not a function"
|
|
46
|
+
|
|
47
|
+
**Cause**: Procedure name doesn't follow query naming conventions.
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// BAD - "fetchUsers" is not recognized as a query
|
|
51
|
+
const { data } = api.users.fetchUsers.useQuery({});
|
|
52
|
+
|
|
53
|
+
// GOOD - Use standard prefixes
|
|
54
|
+
const { data } = api.users.listUsers.useQuery({});
|
|
55
|
+
const { data } = api.users.getUser.useQuery({ id });
|
|
56
|
+
const { data } = api.users.findUsers.useQuery({ search });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Query prefixes**: `get*`, `list*`, `find*`
|
|
60
|
+
|
|
61
|
+
**Mutation prefixes**: `create*`, `add*`, `update*`, `edit*`, `patch*`, `delete*`, `remove*`
|
|
62
|
+
|
|
63
|
+
### "procedure.input is not a function"
|
|
64
|
+
|
|
65
|
+
**Cause**: Missing parentheses after `procedure`.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// BAD
|
|
69
|
+
getUser: procedure.input(z.object({ id: z.string() }))
|
|
70
|
+
|
|
71
|
+
// GOOD
|
|
72
|
+
getUser: procedure().input(z.object({ id: z.string() }))
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### "Cannot read property 'query' of undefined"
|
|
76
|
+
|
|
77
|
+
**Cause**: Procedure not registered in router.
|
|
78
|
+
|
|
79
|
+
**Fix**:
|
|
80
|
+
1. Check `src/procedures/index.ts` exports your procedure
|
|
81
|
+
2. Check `src/index.ts` includes it in collections array
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// src/procedures/index.ts
|
|
85
|
+
export * from './users.js';
|
|
86
|
+
export * from './posts.js'; // Add this
|
|
87
|
+
|
|
88
|
+
// src/index.ts
|
|
89
|
+
import { userProcedures, postProcedures } from './procedures/index.js';
|
|
90
|
+
const collections = [userProcedures, postProcedures]; // Add here
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### "Input validation failed"
|
|
94
|
+
|
|
95
|
+
**Cause**: Request data doesn't match Zod schema.
|
|
96
|
+
|
|
97
|
+
**Debug**:
|
|
98
|
+
```typescript
|
|
99
|
+
// Temporarily log input to see what's being sent
|
|
100
|
+
createUser: procedure()
|
|
101
|
+
.input(CreateUserSchema)
|
|
102
|
+
.mutation(async ({ input }) => {
|
|
103
|
+
console.log('Received input:', input);
|
|
104
|
+
// ...
|
|
105
|
+
}),
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Common issues**:
|
|
109
|
+
- Missing required fields
|
|
110
|
+
- Wrong field types (string vs number)
|
|
111
|
+
- Invalid format (email, uuid, date)
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Prisma Errors
|
|
116
|
+
|
|
117
|
+
### "Unknown property datasourceUrl"
|
|
118
|
+
|
|
119
|
+
**Cause**: Using Prisma 7 with deprecated connection syntax.
|
|
120
|
+
|
|
121
|
+
**Fix**: Use driver adapters in `apps/api/src/config/database.ts`:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// BAD - Prisma 7 removed this
|
|
125
|
+
const db = new PrismaClient({
|
|
126
|
+
datasourceUrl: process.env.DATABASE_URL, // Error!
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// GOOD - Use driver adapter
|
|
130
|
+
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
|
|
131
|
+
|
|
132
|
+
const adapter = new PrismaBetterSqlite3({ url: process.env.DATABASE_URL });
|
|
133
|
+
const db = new PrismaClient({ adapter });
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Prisma Decimal validation fails
|
|
137
|
+
|
|
138
|
+
**Cause**: Prisma returns `Decimal` objects, not numbers.
|
|
139
|
+
|
|
140
|
+
**Fix**: Use transforms in Zod schemas:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// Input - coerce string/number to number
|
|
144
|
+
price: z.coerce.number().positive()
|
|
145
|
+
|
|
146
|
+
// Output - transform Decimal to number
|
|
147
|
+
price: z.any().transform((val) => Number(val))
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### "Cannot find module '.prisma/client'"
|
|
151
|
+
|
|
152
|
+
**Cause**: Prisma client not generated.
|
|
153
|
+
|
|
154
|
+
**Fix**:
|
|
155
|
+
```bash
|
|
156
|
+
pnpm db:generate
|
|
157
|
+
# or
|
|
158
|
+
npx prisma generate
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Database URL not found
|
|
162
|
+
|
|
163
|
+
**Cause**: Environment variable not loaded.
|
|
164
|
+
|
|
165
|
+
**Fix**: Check `.env` file exists and has `DATABASE_URL`:
|
|
166
|
+
|
|
167
|
+
```env
|
|
168
|
+
# .env
|
|
169
|
+
DATABASE_URL="file:./dev.db"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
For Prisma 7, database URL goes in `prisma.config.ts`, NOT in `schema.prisma`.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## REST Route Errors
|
|
177
|
+
|
|
178
|
+
### "Route not found" (404)
|
|
179
|
+
|
|
180
|
+
**Check**:
|
|
181
|
+
1. Procedure is registered in collections
|
|
182
|
+
2. Procedure name follows naming conventions
|
|
183
|
+
3. Correct HTTP method is being used
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# Check registered routes
|
|
187
|
+
curl http://localhost:3030/api/health
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Double `/api/api/` in URL
|
|
191
|
+
|
|
192
|
+
**Cause**: Including `/api` prefix in `.rest()` override.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// BAD - Results in /api/api/posts/:id/publish
|
|
196
|
+
.rest({ method: 'POST', path: '/api/posts/:id/publish' })
|
|
197
|
+
|
|
198
|
+
// GOOD - Prefix is auto-added
|
|
199
|
+
.rest({ method: 'POST', path: '/posts/:id/publish' })
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Path parameter not in input
|
|
203
|
+
|
|
204
|
+
**Cause**: REST path params (`:id`) are NOT auto-extracted.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// The :id in the path is informational only
|
|
208
|
+
// You must pass id in the request body
|
|
209
|
+
.rest({ method: 'POST', path: '/posts/:id/publish' })
|
|
210
|
+
.input(z.object({ id: z.string().uuid() })) // Required!
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Authentication Errors
|
|
216
|
+
|
|
217
|
+
### "Unauthorized" (401)
|
|
218
|
+
|
|
219
|
+
**Cause**: Request missing or invalid auth token.
|
|
220
|
+
|
|
221
|
+
**Check**:
|
|
222
|
+
1. Token is being sent in Authorization header
|
|
223
|
+
2. Token format: `Authorization: Bearer <token>`
|
|
224
|
+
3. Token hasn't expired
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// Frontend
|
|
228
|
+
const response = await fetch('/api/users/me', {
|
|
229
|
+
headers: {
|
|
230
|
+
Authorization: `Bearer ${token}`,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### "Forbidden" (403)
|
|
236
|
+
|
|
237
|
+
**Cause**: User authenticated but lacks permission.
|
|
238
|
+
|
|
239
|
+
**Check**:
|
|
240
|
+
1. User has required role/permission
|
|
241
|
+
2. Guard logic is correct
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// Debug: log user info
|
|
245
|
+
.guard(hasRole('admin'))
|
|
246
|
+
.query(({ ctx }) => {
|
|
247
|
+
console.log('User:', ctx.user);
|
|
248
|
+
console.log('Roles:', ctx.user?.roles);
|
|
249
|
+
// ...
|
|
250
|
+
}),
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Session not persisting
|
|
254
|
+
|
|
255
|
+
**Cause**: Cookie not being set or sent.
|
|
256
|
+
|
|
257
|
+
**Check**:
|
|
258
|
+
1. Cookie settings match your domain
|
|
259
|
+
2. `credentials: 'include'` in fetch requests
|
|
260
|
+
3. CORS allows credentials
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// Frontend fetch
|
|
264
|
+
const response = await fetch('/api/auth/login', {
|
|
265
|
+
method: 'POST',
|
|
266
|
+
credentials: 'include', // Required for cookies
|
|
267
|
+
body: JSON.stringify(data),
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Generator Errors
|
|
274
|
+
|
|
275
|
+
### "Not in a VeloxTS project"
|
|
276
|
+
|
|
277
|
+
**Cause**: CLI can't find project root.
|
|
278
|
+
|
|
279
|
+
**Fix**:
|
|
280
|
+
1. Run from project root directory
|
|
281
|
+
2. Ensure `package.json` exists with VeloxTS dependencies
|
|
282
|
+
3. For MCP: set `cwd` in config
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
# Run from correct directory
|
|
286
|
+
cd /path/to/your-velox-project
|
|
287
|
+
pnpm velox make resource Post
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### "File already exists"
|
|
291
|
+
|
|
292
|
+
**Cause**: Generator won't overwrite existing files.
|
|
293
|
+
|
|
294
|
+
**Fix**: Use `--force` flag:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
pnpm velox make resource Post --force
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### "Model already exists in schema"
|
|
301
|
+
|
|
302
|
+
**Cause**: Prisma model with same name already defined.
|
|
303
|
+
|
|
304
|
+
**Options**:
|
|
305
|
+
1. Use a different name
|
|
306
|
+
2. Use `namespace` generator (doesn't inject Prisma)
|
|
307
|
+
3. Manually remove existing model first
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Build Errors
|
|
312
|
+
|
|
313
|
+
### TypeScript errors in generated code
|
|
314
|
+
|
|
315
|
+
**Cause**: Generated code doesn't match your types.
|
|
316
|
+
|
|
317
|
+
**Fix**:
|
|
318
|
+
1. Regenerate Prisma client: `pnpm db:generate`
|
|
319
|
+
2. Check schema matches Prisma model
|
|
320
|
+
3. Ensure imports are correct
|
|
321
|
+
|
|
322
|
+
### "Cannot find module '@veloxts/velox'"
|
|
323
|
+
|
|
324
|
+
**Cause**: Dependencies not installed.
|
|
325
|
+
|
|
326
|
+
**Fix**:
|
|
327
|
+
```bash
|
|
328
|
+
pnpm install
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Module resolution errors
|
|
332
|
+
|
|
333
|
+
**Cause**: Missing `.js` extension in imports.
|
|
334
|
+
|
|
335
|
+
**Fix**: Use `.js` extension for local imports:
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
// BAD
|
|
339
|
+
import { userProcedures } from './procedures/users';
|
|
340
|
+
|
|
341
|
+
// GOOD
|
|
342
|
+
import { userProcedures } from './procedures/users.js';
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Development Server Errors
|
|
348
|
+
|
|
349
|
+
### Port already in use
|
|
350
|
+
|
|
351
|
+
**Cause**: Another process using port 3030.
|
|
352
|
+
|
|
353
|
+
**Fix**:
|
|
354
|
+
```bash
|
|
355
|
+
# Find process
|
|
356
|
+
lsof -i :3030
|
|
357
|
+
|
|
358
|
+
# Kill it
|
|
359
|
+
kill -9 <PID>
|
|
360
|
+
|
|
361
|
+
# Or use different port
|
|
362
|
+
pnpm velox dev --port 4000
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### HMR not working
|
|
366
|
+
|
|
367
|
+
**Check**:
|
|
368
|
+
1. `hot-hook` is installed
|
|
369
|
+
2. `hotHook` config in `package.json`
|
|
370
|
+
3. Try `--no-hmr` to diagnose
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
# Disable HMR to compare
|
|
374
|
+
pnpm velox dev --no-hmr
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Slow startup
|
|
378
|
+
|
|
379
|
+
**Try**:
|
|
380
|
+
```bash
|
|
381
|
+
# Enable verbose timing
|
|
382
|
+
pnpm velox dev --verbose
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Look for which phase is slow (dependency loading, Prisma, etc.)
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## Quick Fixes Checklist
|
|
390
|
+
|
|
391
|
+
When something doesn't work:
|
|
392
|
+
|
|
393
|
+
1. **Regenerate Prisma**: `pnpm db:generate`
|
|
394
|
+
2. **Restart dev server**: `Ctrl+C` then `pnpm dev`
|
|
395
|
+
3. **Clear node_modules**: `rm -rf node_modules && pnpm install`
|
|
396
|
+
4. **Check imports**: Ensure `.js` extensions
|
|
397
|
+
5. **Check registration**: Procedure in `index.ts` exports and collections
|
|
398
|
+
6. **Check naming**: Procedure names follow conventions
|
|
399
|
+
7. **Check env**: `.env` file has required variables
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Getting Help
|
|
404
|
+
|
|
405
|
+
1. **Check this guide** for common issues
|
|
406
|
+
2. **Read error codes**: VeloxTS uses structured error codes (E1xxx, E2xxx, etc.)
|
|
407
|
+
3. **Use `--verbose`**: Most commands support verbose output
|
|
408
|
+
4. **Use `--dry-run`**: Preview changes before applying
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
# Verbose output
|
|
412
|
+
pnpm velox migrate status --verbose
|
|
413
|
+
|
|
414
|
+
# Dry run
|
|
415
|
+
pnpm velox make resource Post --dry-run
|
|
416
|
+
```
|
|
@@ -131,16 +131,48 @@ JWT_SECRET=<64+ chars> # Generate: openssl rand -base64 64
|
|
|
131
131
|
JWT_REFRESH_SECRET=<64+ chars> # Generate: openssl rand -base64 64
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
## Procedure Naming Conventions
|
|
134
|
+
## Procedure Naming Conventions (CRITICAL)
|
|
135
|
+
|
|
136
|
+
VeloxTS uses naming conventions to determine both HTTP methods and React Query hook types.
|
|
137
|
+
|
|
138
|
+
### HTTP Method Mapping
|
|
135
139
|
|
|
136
140
|
| Procedure Name | HTTP Method | Route |
|
|
137
141
|
|----------------|-------------|-------|
|
|
138
142
|
| `getUser` | GET | `/users/:id` |
|
|
139
143
|
| `listUsers` | GET | `/users` |
|
|
144
|
+
| `findUsers` | GET | `/users` (search) |
|
|
140
145
|
| `createUser` | POST | `/users` |
|
|
146
|
+
| `addUser` | POST | `/users` |
|
|
141
147
|
| `updateUser` | PUT | `/users/:id` |
|
|
148
|
+
| `editUser` | PUT | `/users/:id` |
|
|
142
149
|
| `patchUser` | PATCH | `/users/:id` |
|
|
143
150
|
| `deleteUser` | DELETE | `/users/:id` |
|
|
151
|
+
| `removeUser` | DELETE | `/users/:id` |
|
|
152
|
+
|
|
153
|
+
### React Query Hook Mapping
|
|
154
|
+
|
|
155
|
+
**Query procedures** (use `useQuery`, `useSuspenseQuery`):
|
|
156
|
+
- Prefixes: `get*`, `list*`, `find*`
|
|
157
|
+
- Example: `api.users.getUser.useQuery({ id })` ✅
|
|
158
|
+
- Example: `api.users.listUsers.useSuspenseQuery({})` ✅
|
|
159
|
+
|
|
160
|
+
**Mutation procedures** (use `useMutation`):
|
|
161
|
+
- Prefixes: `create*`, `add*`, `update*`, `edit*`, `patch*`, `delete*`, `remove*`
|
|
162
|
+
- Example: `api.users.createUser.useMutation()` ✅
|
|
163
|
+
- Example: `api.posts.updatePost.useMutation()` ✅
|
|
164
|
+
|
|
165
|
+
### Common Mistake
|
|
166
|
+
|
|
167
|
+
If you see "useSuspenseQuery is not a function" or similar errors, your procedure name doesn't follow the convention:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
// ❌ Wrong - "fetchCampaigns" is not a query prefix, treated as mutation
|
|
171
|
+
const { data } = api.campaigns.fetchCampaigns.useQuery({}); // Error!
|
|
172
|
+
|
|
173
|
+
// ✅ Correct - "listCampaigns" is a query prefix
|
|
174
|
+
const { data } = api.campaigns.listCampaigns.useQuery({});
|
|
175
|
+
```
|
|
144
176
|
|
|
145
177
|
## Common Gotchas (IMPORTANT)
|
|
146
178
|
|
|
@@ -111,16 +111,48 @@ VeloxTS provides end-to-end type safety without code generation:
|
|
|
111
111
|
3. **Import in frontend** via `@veloxts/client` hooks
|
|
112
112
|
4. Types flow automatically from backend to frontend
|
|
113
113
|
|
|
114
|
-
## Procedure Naming Conventions
|
|
114
|
+
## Procedure Naming Conventions (CRITICAL)
|
|
115
|
+
|
|
116
|
+
VeloxTS uses naming conventions to determine both HTTP methods and React Query hook types.
|
|
117
|
+
|
|
118
|
+
### HTTP Method Mapping
|
|
115
119
|
|
|
116
120
|
| Procedure Name | HTTP Method | Route |
|
|
117
121
|
|----------------|-------------|-------|
|
|
118
122
|
| `getUser` | GET | `/users/:id` |
|
|
119
123
|
| `listUsers` | GET | `/users` |
|
|
124
|
+
| `findUsers` | GET | `/users` (search) |
|
|
120
125
|
| `createUser` | POST | `/users` |
|
|
126
|
+
| `addUser` | POST | `/users` |
|
|
121
127
|
| `updateUser` | PUT | `/users/:id` |
|
|
128
|
+
| `editUser` | PUT | `/users/:id` |
|
|
122
129
|
| `patchUser` | PATCH | `/users/:id` |
|
|
123
130
|
| `deleteUser` | DELETE | `/users/:id` |
|
|
131
|
+
| `removeUser` | DELETE | `/users/:id` |
|
|
132
|
+
|
|
133
|
+
### React Query Hook Mapping
|
|
134
|
+
|
|
135
|
+
**Query procedures** (use `useQuery`, `useSuspenseQuery`):
|
|
136
|
+
- Prefixes: `get*`, `list*`, `find*`
|
|
137
|
+
- Example: `api.users.getUser.useQuery({ id })` ✅
|
|
138
|
+
- Example: `api.users.listUsers.useSuspenseQuery({})` ✅
|
|
139
|
+
|
|
140
|
+
**Mutation procedures** (use `useMutation`):
|
|
141
|
+
- Prefixes: `create*`, `add*`, `update*`, `edit*`, `patch*`, `delete*`, `remove*`
|
|
142
|
+
- Example: `api.users.createUser.useMutation()` ✅
|
|
143
|
+
- Example: `api.posts.updatePost.useMutation()` ✅
|
|
144
|
+
|
|
145
|
+
### Common Mistake
|
|
146
|
+
|
|
147
|
+
If you see "useSuspenseQuery is not a function" or similar errors, your procedure name doesn't follow the convention:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// ❌ Wrong - "fetchUsers" is not a query prefix, treated as mutation
|
|
151
|
+
const { data } = api.users.fetchUsers.useQuery({}); // Error!
|
|
152
|
+
|
|
153
|
+
// ✅ Correct - "listUsers" is a query prefix
|
|
154
|
+
const { data } = api.users.listUsers.useQuery({});
|
|
155
|
+
```
|
|
124
156
|
|
|
125
157
|
## Common Gotchas (IMPORTANT)
|
|
126
158
|
|
|
@@ -200,6 +200,26 @@ list: procedure
|
|
|
200
200
|
.output(schema)
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
+
### Procedure Naming Conventions
|
|
204
|
+
|
|
205
|
+
VeloxTS uses naming conventions to determine procedure type in REST adapter mode. Even in tRPC-only mode, follow these conventions for consistency and potential future REST migration:
|
|
206
|
+
|
|
207
|
+
**Query procedures** (read operations):
|
|
208
|
+
- Prefixes: `get*`, `list*`, `find*`
|
|
209
|
+
- Use `.query()` builder
|
|
210
|
+
|
|
211
|
+
**Mutation procedures** (write operations):
|
|
212
|
+
- Prefixes: `create*`, `add*`, `update*`, `edit*`, `patch*`, `delete*`, `remove*`
|
|
213
|
+
- Use `.mutation()` builder
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// Good - clear intent from naming
|
|
217
|
+
listPosts: procedure().query(...) // Query
|
|
218
|
+
getPostById: procedure().query(...) // Query
|
|
219
|
+
createPost: procedure().mutation(...) // Mutation
|
|
220
|
+
updatePost: procedure().mutation(...) // Mutation
|
|
221
|
+
```
|
|
222
|
+
|
|
203
223
|
### Handling Prisma Decimals in Zod Schemas
|
|
204
224
|
|
|
205
225
|
Prisma returns `Decimal` objects for decimal fields. Standard Zod validation fails.
|
|
@@ -176,6 +176,25 @@ getPost: procedure
|
|
|
176
176
|
.input(schema)
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
+
### Procedure Naming Conventions
|
|
180
|
+
|
|
181
|
+
VeloxTS uses naming conventions to determine HTTP methods for REST endpoints:
|
|
182
|
+
|
|
183
|
+
| Procedure Name | HTTP Method | Route |
|
|
184
|
+
|----------------|-------------|-------|
|
|
185
|
+
| `getUser` | GET | `/users/:id` |
|
|
186
|
+
| `listUsers` | GET | `/users` |
|
|
187
|
+
| `findUsers` | GET | `/users` (search) |
|
|
188
|
+
| `createUser` | POST | `/users` |
|
|
189
|
+
| `addUser` | POST | `/users` |
|
|
190
|
+
| `updateUser` | PUT | `/users/:id` |
|
|
191
|
+
| `editUser` | PUT | `/users/:id` |
|
|
192
|
+
| `patchUser` | PATCH | `/users/:id` |
|
|
193
|
+
| `deleteUser` | DELETE | `/users/:id` |
|
|
194
|
+
| `removeUser` | DELETE | `/users/:id` |
|
|
195
|
+
|
|
196
|
+
Follow these conventions for consistency across procedures and server actions.
|
|
197
|
+
|
|
179
198
|
### Custom REST Routes
|
|
180
199
|
|
|
181
200
|
When using `.rest()` to override routes, do NOT include the API prefix:
|
|
@@ -249,6 +249,25 @@ getUser: procedure
|
|
|
249
249
|
.guard(authenticated)
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
+
### Procedure Naming Conventions
|
|
253
|
+
|
|
254
|
+
VeloxTS uses naming conventions to determine HTTP methods for REST endpoints:
|
|
255
|
+
|
|
256
|
+
| Procedure Name | HTTP Method | Route |
|
|
257
|
+
|----------------|-------------|-------|
|
|
258
|
+
| `getUser` | GET | `/users/:id` |
|
|
259
|
+
| `listUsers` | GET | `/users` |
|
|
260
|
+
| `findUsers` | GET | `/users` (search) |
|
|
261
|
+
| `createUser` | POST | `/users` |
|
|
262
|
+
| `addUser` | POST | `/users` |
|
|
263
|
+
| `updateUser` | PUT | `/users/:id` |
|
|
264
|
+
| `editUser` | PUT | `/users/:id` |
|
|
265
|
+
| `patchUser` | PATCH | `/users/:id` |
|
|
266
|
+
| `deleteUser` | DELETE | `/users/:id` |
|
|
267
|
+
| `removeUser` | DELETE | `/users/:id` |
|
|
268
|
+
|
|
269
|
+
Follow these conventions for consistency across procedures and server actions.
|
|
270
|
+
|
|
252
271
|
### Custom REST Routes
|
|
253
272
|
|
|
254
273
|
When using `.rest()` to override routes, do NOT include the API prefix:
|
|
@@ -23,13 +23,12 @@
|
|
|
23
23
|
import { createVeloxHooks } from '@veloxts/client/react';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* AppRouter type imported from the
|
|
26
|
+
* AppRouter type imported from the router definition.
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* scans the @veloxts/* packages when building the frontend.
|
|
28
|
+
* Using `import type` ensures this is erased at compile time.
|
|
29
|
+
* Vite never bundles @veloxts/* packages in the frontend build.
|
|
31
30
|
*/
|
|
32
|
-
import type { AppRouter } from '../../api/src/router.
|
|
31
|
+
import type { AppRouter } from '../../api/src/router.js';
|
|
33
32
|
|
|
34
33
|
/**
|
|
35
34
|
* Type-safe API hooks with full autocomplete
|
|
@@ -6,8 +6,8 @@ import { createRoot } from 'react-dom/client';
|
|
|
6
6
|
import { routeTree } from './routeTree.gen';
|
|
7
7
|
import './styles/global.css';
|
|
8
8
|
|
|
9
|
-
// Import router type
|
|
10
|
-
import type { AppRouter } from '../../api/src/router.
|
|
9
|
+
// Import router type (type-only import is erased at compile time)
|
|
10
|
+
import type { AppRouter } from '../../api/src/router.js';
|
|
11
11
|
/* @if auth */
|
|
12
12
|
// Import routes from browser-safe routes file
|
|
13
13
|
import { routes } from '../../api/src/routes.js';
|
|
@@ -2,7 +2,7 @@ import { createRootRoute, Link, Outlet } from '@tanstack/react-router';
|
|
|
2
2
|
/* @if auth */
|
|
3
3
|
import { useQuery } from '@veloxts/client/react';
|
|
4
4
|
|
|
5
|
-
import type { AppRouter } from '../../../api/src/router.
|
|
5
|
+
import type { AppRouter } from '../../../api/src/router.js';
|
|
6
6
|
/* @endif auth */
|
|
7
7
|
import styles from '@/App.module.css';
|
|
8
8
|
|